xref: /onnv-gate/usr/src/lib/libast/common/string/chresc.c (revision 12068:08a39a083754)
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