1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2008 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 /* 24 * Glenn Fowler 25 * AT&T Research 26 * 27 * return the next character in the string s 28 * \ character constants are converted 29 * p is updated to point to the next character in s 30 */ 31 32 #include <ast.h> 33 #include <ctype.h> 34 35 #include <ccode.h> 36 #if !_PACKAGE_astsa 37 #include <regex.h> 38 #endif 39 40 int 41 chresc(register const char* s, char** p) 42 { 43 register const char* q; 44 register int c; 45 const char* e; 46 #if !_PACKAGE_astsa 47 int n; 48 char buf[64]; 49 #endif 50 51 switch (c = mbchar(s)) 52 { 53 case 0: 54 s--; 55 break; 56 case '\\': 57 switch (c = *s++) 58 { 59 case '0': case '1': case '2': case '3': 60 case '4': case '5': case '6': case '7': 61 c -= '0'; 62 q = s + 2; 63 while (s < q) 64 switch (*s) 65 { 66 case '0': case '1': case '2': case '3': 67 case '4': case '5': case '6': case '7': 68 c = (c << 3) + *s++ - '0'; 69 break; 70 default: 71 q = s; 72 break; 73 } 74 break; 75 case 'a': 76 c = CC_bel; 77 break; 78 case 'b': 79 c = '\b'; 80 break; 81 case 'c': 82 control: 83 if (c = *s) 84 { 85 s++; 86 if (islower(c)) 87 c = toupper(c); 88 } 89 c = ccmapc(c, CC_NATIVE, CC_ASCII); 90 c ^= 0x40; 91 c = ccmapc(c, CC_ASCII, CC_NATIVE); 92 break; 93 case 'C': 94 if (*s == '-' && *(s + 1)) 95 { 96 s++; 97 goto control; 98 } 99 #if !_PACKAGE_astsa 100 if (*s == '[' && (n = regcollate(s + 1, (char**)&e, buf, sizeof(buf))) >= 0) 101 { 102 if (n == 1) 103 c = buf[0]; 104 s = e; 105 } 106 #endif 107 break; 108 case 'e': 109 case 'E': 110 c = CC_esc; 111 break; 112 case 'f': 113 c = '\f'; 114 break; 115 case 'M': 116 if (*s == '-') 117 { 118 s++; 119 c = CC_esc; 120 } 121 break; 122 case 'n': 123 c = '\n'; 124 break; 125 case 'r': 126 c = '\r'; 127 break; 128 case 't': 129 c = '\t'; 130 break; 131 case 'v': 132 c = CC_vt; 133 break; 134 case 'u': 135 case 'U': 136 case 'x': 137 c = 0; 138 q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0; 139 e = s; 140 while (!e || !q || s < q) 141 { 142 switch (*s) 143 { 144 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 145 c = (c << 4) + *s++ - 'a' + 10; 146 continue; 147 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 148 c = (c << 4) + *s++ - 'A' + 10; 149 continue; 150 case '0': case '1': case '2': case '3': case '4': 151 case '5': case '6': case '7': case '8': case '9': 152 c = (c << 4) + *s++ - '0'; 153 continue; 154 case '{': 155 case '[': 156 if (s != e) 157 break; 158 e = 0; 159 s++; 160 continue; 161 case '}': 162 case ']': 163 if (!e) 164 s++; 165 break; 166 default: 167 break; 168 } 169 break; 170 } 171 break; 172 case 0: 173 s--; 174 break; 175 } 176 break; 177 } 178 if (p) 179 *p = (char*)s; 180 return c; 181 } 182