14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin * Glenn Fowler
254887Schin * AT&T Research
264887Schin *
274887Schin * return the next character in the string s
284887Schin * \ character constants are converted
294887Schin * p is updated to point to the next character in s
304887Schin */
314887Schin
324887Schin #include <ast.h>
334887Schin #include <ctype.h>
344887Schin
354887Schin #include <ccode.h>
364887Schin #if !_PACKAGE_astsa
374887Schin #include <regex.h>
384887Schin #endif
394887Schin
404887Schin int
chresc(register const char * s,char ** p)414887Schin chresc(register const char* s, char** p)
424887Schin {
434887Schin register const char* q;
444887Schin register int c;
454887Schin const char* e;
464887Schin #if !_PACKAGE_astsa
474887Schin int n;
484887Schin char buf[64];
494887Schin #endif
504887Schin
514887Schin switch (c = mbchar(s))
524887Schin {
534887Schin case 0:
544887Schin s--;
554887Schin break;
564887Schin case '\\':
574887Schin switch (c = *s++)
584887Schin {
594887Schin case '0': case '1': case '2': case '3':
604887Schin case '4': case '5': case '6': case '7':
614887Schin c -= '0';
624887Schin q = s + 2;
634887Schin while (s < q)
644887Schin switch (*s)
654887Schin {
664887Schin case '0': case '1': case '2': case '3':
674887Schin case '4': case '5': case '6': case '7':
684887Schin c = (c << 3) + *s++ - '0';
694887Schin break;
704887Schin default:
714887Schin q = s;
724887Schin break;
734887Schin }
744887Schin break;
754887Schin case 'a':
764887Schin c = CC_bel;
774887Schin break;
784887Schin case 'b':
794887Schin c = '\b';
804887Schin break;
814887Schin case 'c':
824887Schin control:
834887Schin if (c = *s)
844887Schin {
854887Schin s++;
864887Schin if (islower(c))
874887Schin c = toupper(c);
884887Schin }
894887Schin c = ccmapc(c, CC_NATIVE, CC_ASCII);
904887Schin c ^= 0x40;
914887Schin c = ccmapc(c, CC_ASCII, CC_NATIVE);
924887Schin break;
934887Schin case 'C':
944887Schin if (*s == '-' && *(s + 1))
954887Schin {
964887Schin s++;
974887Schin goto control;
984887Schin }
994887Schin #if !_PACKAGE_astsa
1004887Schin if (*s == '[' && (n = regcollate(s + 1, (char**)&e, buf, sizeof(buf))) >= 0)
1014887Schin {
1024887Schin if (n == 1)
1034887Schin c = buf[0];
1044887Schin s = e;
1054887Schin }
1064887Schin #endif
1074887Schin break;
1084887Schin case 'e':
1094887Schin case 'E':
1104887Schin c = CC_esc;
1114887Schin break;
1124887Schin case 'f':
1134887Schin c = '\f';
1144887Schin break;
1154887Schin case 'M':
1164887Schin if (*s == '-')
1174887Schin {
1184887Schin s++;
1194887Schin c = CC_esc;
1204887Schin }
1214887Schin break;
1224887Schin case 'n':
1234887Schin c = '\n';
1244887Schin break;
1254887Schin case 'r':
1264887Schin c = '\r';
1274887Schin break;
1284887Schin case 't':
1294887Schin c = '\t';
1304887Schin break;
1314887Schin case 'v':
1324887Schin c = CC_vt;
1334887Schin break;
1344887Schin case 'u':
1354887Schin case 'U':
1364887Schin case 'x':
1374887Schin c = 0;
1384887Schin q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0;
1394887Schin e = s;
1404887Schin while (!e || !q || s < q)
1414887Schin {
1424887Schin switch (*s)
1434887Schin {
1444887Schin case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1454887Schin c = (c << 4) + *s++ - 'a' + 10;
1464887Schin continue;
1474887Schin case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1484887Schin c = (c << 4) + *s++ - 'A' + 10;
1494887Schin continue;
1504887Schin case '0': case '1': case '2': case '3': case '4':
1514887Schin case '5': case '6': case '7': case '8': case '9':
1524887Schin c = (c << 4) + *s++ - '0';
1534887Schin continue;
1544887Schin case '{':
1554887Schin case '[':
1564887Schin if (s != e)
1574887Schin break;
1584887Schin e = 0;
1594887Schin s++;
1604887Schin continue;
1614887Schin case '}':
1624887Schin case ']':
1634887Schin if (!e)
1644887Schin s++;
1654887Schin break;
1664887Schin default:
1674887Schin break;
1684887Schin }
1694887Schin break;
1704887Schin }
1714887Schin break;
1724887Schin case 0:
1734887Schin s--;
1744887Schin break;
1754887Schin }
1764887Schin break;
1774887Schin }
1784887Schin if (p)
1794887Schin *p = (char*)s;
1804887Schin return c;
1814887Schin }
182