00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <lestes/common.hh>
00035 #include <lestes/std/source_location.hh>
00036 #include <lestes/std/ucn_string.hh>
00037 #include <lestes/lang/cplus/lex/stringifier.hh>
00038 #include <lestes/lang/cplus/lex/pp_token.hh>
00039 #include <lestes/lang/cplus/lex/token_input.hh>
00040 #include <lestes/lang/cplus/lex/token_value.hh>
00041
00042 package(lestes);
00043 package(lang);
00044 package(cplus);
00045 package(lex);
00046
00047
00048
00049
00050 stringifier::stringifier(void)
00051 {
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 ptr<pp_token> stringifier::process(const ptr<token_input> &input)
00066 {
00067 ucn_string str;
00068 ptr<pp_token> tok = input->read_front();
00069
00070 if (tok->type_get() == pp_token::TOK_BLANK) tok = input->read_front();
00071 ptr<source_location> loc = tok->location_get();
00072
00073 if (tok->type_get() != pp_token::TOK_TERMINATOR) {
00074 ptr<pp_token> last = tok;
00075 tok = input->read_front();
00076
00077 while (tok->type_get() != pp_token::TOK_TERMINATOR) {
00078 str += escape_spelling(last);
00079 last = tok;
00080 tok = input->read_front();
00081 }
00082
00083
00084 if (last->type_get() != pp_token::TOK_BLANK) str += escape_spelling(last);
00085 }
00086
00087
00088 return pp_token::create(loc,pp_token::TOK_STRING_LIT,token_value::create(str));
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 ucn_string stringifier::escape_spelling(const ptr<pp_token> &tok)
00100 {
00101 lassert(tok);
00102
00103 switch (tok->type_get()) {
00104 case pp_token::TOK_STRING_LIT:
00105 case pp_token::TOK_WSTRING_LIT:
00106 case pp_token::TOK_CHAR_LIT:
00107 case pp_token::TOK_WCHAR_LIT:
00108 case pp_token::TOK_OTHER:
00109 case pp_token::TOK_IDENT:
00110 break;
00111 default:
00112 return tok->spelling_get();
00113 }
00114
00115 ucn_string str(tok->spelling_get());
00116 ucn_string::size_type len = str.length();
00117 ucn u;
00118 ucn_string work;
00119
00120 for (ucn_string::size_type i = 0; i < len; i++) {
00121 u = str[i];
00122
00123 if (character::is_translated(u)) {
00124 ulint x = character::extract_value(u);
00125 work += character::ascii_backslash;
00126 work += character::ascii_backslash;
00127 if (x <= 0xffff) {
00128 work += character::ascii_lower_u;
00129 work += character::create_xdigit((x >> 12) & 0xf);
00130 work += character::create_xdigit((x >> 4) & 0xf);
00131 work += character::create_xdigit((x >> 8) & 0xf);
00132 work += character::create_xdigit(x & 0xf);
00133 } else {
00134 work += character::ascii_upper_u;
00135 work += character::create_xdigit((x >> 28) & 0xf);
00136 work += character::create_xdigit((x >> 24) & 0xf);
00137 work += character::create_xdigit((x >> 20) & 0xf);
00138 work += character::create_xdigit((x >> 16) & 0xf);
00139 work += character::create_xdigit((x >> 12) & 0xf);
00140 work += character::create_xdigit((x >> 8) & 0xf);
00141 work += character::create_xdigit((x >> 4) & 0xf);
00142 work += character::create_xdigit(x & 0xf);
00143 }
00144 } else {
00145 if (u == character::ascii_dquote || u == character::ascii_backslash)
00146 work += character::ascii_backslash;
00147 work += u;
00148 }
00149
00150 }
00151 return work;
00152 }
00153
00154
00155
00156
00157
00158 ptr<stringifier> stringifier::instance(void)
00159 {
00160 if (!singleton) {
00161 singleton = new stringifier();
00162 }
00163 return singleton;
00164 }
00165
00166
00167
00168
00169 ptr<stringifier> stringifier::singleton;
00170
00171 end_package(lex);
00172 end_package(cplus);
00173 end_package(lang);
00174 end_package(lestes);
00175
00176