| 1 |
/** |
|---|
| 2 |
* Copyright: Copyright © 2007-2008 Diggory Hardy. |
|---|
| 3 |
* Authors: Diggory Hardy, diggory.hardy@gmail.com |
|---|
| 4 |
* License: as for tango (BSD) |
|---|
| 5 |
* |
|---|
| 6 |
* Merge this into whatever module it fits best in. |
|---|
| 7 |
*/ |
|---|
| 8 |
module escSeqs; |
|---|
| 9 |
|
|---|
| 10 |
/****************************************************************************** |
|---|
| 11 |
* Given a character from an escape sequence returns the |
|---|
| 12 |
* character the escape sequence represents. |
|---|
| 13 |
* |
|---|
| 14 |
* Supported escape sequences are the following subset of those supported by D: |
|---|
| 15 |
* \" \' \\ \a \b \f \n \r \t \v |
|---|
| 16 |
* |
|---|
| 17 |
* Param: |
|---|
| 18 |
* c The second character of a two-letter escape sequence (e.g. 't' from \t). |
|---|
| 19 |
* |
|---|
| 20 |
* Returns: |
|---|
| 21 |
* The character represented by the escape sequence (e.g. tab). |
|---|
| 22 |
* |
|---|
| 23 |
* Throws: |
|---|
| 24 |
* Throws a <typeofexception> exception when c is not a character from a |
|---|
| 25 |
* recognised escape sequence. |
|---|
| 26 |
* |
|---|
| 27 |
* Example usage: |
|---|
| 28 |
* ----------------------------------------------------------------------------- |
|---|
| 29 |
* char[] str; |
|---|
| 30 |
* for (uint i = 0; i < str.length; ++i) { |
|---|
| 31 |
* if (str[i] == '\\') { |
|---|
| 32 |
* if (i + 1 >= str.length) throw new Exception ("Invalid escape sequence"); |
|---|
| 33 |
* str = str[0..i] ~ replaceEscapedChar (str[i+1]) ~ str[i+2..$]; |
|---|
| 34 |
* } |
|---|
| 35 |
* } |
|---|
| 36 |
* ----------------------------------------------------------------------------- |
|---|
| 37 |
******************************************************************************/ |
|---|
| 38 |
char replaceEscapedChar (char c) |
|---|
| 39 |
{ |
|---|
| 40 |
static char[char] escChars; |
|---|
| 41 |
static bool escCharsFilled; // will be initialised false |
|---|
| 42 |
|
|---|
| 43 |
if (!escCharsFilled) { |
|---|
| 44 |
// map of all supported escape sequences (cannot be static?) |
|---|
| 45 |
escChars = ['"' : '"', '\'' : '\'', |
|---|
| 46 |
'\\' : '\\', 'a' : '\a', |
|---|
| 47 |
'b' : '\b', 'f' : '\f', |
|---|
| 48 |
'n' : '\n', 'r' : '\r', |
|---|
| 49 |
't' : '\t', 'v' : '\v']; |
|---|
| 50 |
escCharsFilled = true; |
|---|
| 51 |
} |
|---|
| 52 |
|
|---|
| 53 |
char* r = c in escChars; |
|---|
| 54 |
if (r != null) return *r; |
|---|
| 55 |
else throw new Exception ("Invalid escape sequence: \\"~c); // FIXME: make an appropriate escape sequence type |
|---|
| 56 |
} |
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
/****************************************************************************** |
|---|
| 60 |
* Given an escapable character returns the second character of its escape |
|---|
| 61 |
* sequence. |
|---|
| 62 |
* |
|---|
| 63 |
* Supported escape sequences are the following subset of those supported by D: |
|---|
| 64 |
* \" \' \\ \a \b \f \n \r \t \v |
|---|
| 65 |
* |
|---|
| 66 |
* Param: |
|---|
| 67 |
* c A character representable by an escape sequence (e.g. tab). |
|---|
| 68 |
* |
|---|
| 69 |
* Returns: |
|---|
| 70 |
* The second character of the corresponding two-letter escape sequence |
|---|
| 71 |
* (e.g. 't' from \t). |
|---|
| 72 |
* |
|---|
| 73 |
* Remarks: |
|---|
| 74 |
* ASSUMES the character has an escape sequence â no built-in check. |
|---|
| 75 |
* |
|---|
| 76 |
* Example usage: |
|---|
| 77 |
* ----------------------------------------------------------------------------- |
|---|
| 78 |
* char[] str; |
|---|
| 79 |
* for (uint i = 0; i < str.length; ++i) { |
|---|
| 80 |
* if (isEscapableChar(str[i])) { |
|---|
| 81 |
* str = str[0..i] ~ '\\' ~ replaceEscapableChar (str[i]) ~ str[i+1..$]; |
|---|
| 82 |
* ++i; |
|---|
| 83 |
* } |
|---|
| 84 |
* } |
|---|
| 85 |
* ----------------------------------------------------------------------------- |
|---|
| 86 |
******************************************************************************/ |
|---|
| 87 |
// Warning: this DOES NOT check c is escapable |
|---|
| 88 |
char replaceEscapableChar (char c) { |
|---|
| 89 |
static char[char] escCharsRev; // reversed escChars |
|---|
| 90 |
static bool escCharsRevFilled; // will be initialised false |
|---|
| 91 |
|
|---|
| 92 |
if (!escCharsRevFilled) { // only do this once |
|---|
| 93 |
// map of all supported escape sequences |
|---|
| 94 |
escCharsRev = ['"' : '"', '\'' : '\'', |
|---|
| 95 |
'\\' : '\\', '\a' : 'a', |
|---|
| 96 |
'\b' : 'b', '\f' : 'f', |
|---|
| 97 |
'\n' : 'n', '\r' : 'r', |
|---|
| 98 |
'\t' : 't', '\v' : 'v']; |
|---|
| 99 |
escCharsRevFilled = true; |
|---|
| 100 |
} |
|---|
| 101 |
|
|---|
| 102 |
return escCharsRev[c]; |
|---|
| 103 |
} |
|---|
| 104 |
/** Companion function to replaceEscapableChar to check whether the character is escapable. |
|---|
| 105 |
* |
|---|
| 106 |
* Param: |
|---|
| 107 |
* c As for replaceEscapableChar(). |
|---|
| 108 |
* |
|---|
| 109 |
* Returns: |
|---|
| 110 |
* true if character is escapable. |
|---|
| 111 |
*/ |
|---|
| 112 |
bool isEscapableChar (char c) { |
|---|
| 113 |
return ((c <= '\r' && c >= '\a') || c == '\"' || c == '\'' || c == '\\'); |
|---|
| 114 |
} |
|---|