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 string with expanded escape chars 284887Schin */ 294887Schin 304887Schin #include <ast.h> 314887Schin #include <ccode.h> 324887Schin #include <ctype.h> 334887Schin 344887Schin /* 354887Schin * quote string as of length n with qb...qe 364887Schin * (flags&FMT_ALWAYS) always quotes, otherwise quote output only if necessary 374887Schin * qe and the usual suspects are \... escaped 384887Schin * (flags&FMT_WIDE) doesn't escape 8 bit chars 394887Schin * (flags&FMT_ESCAPED) doesn't \... escape the usual suspects 404887Schin * (flags&FMT_SHELL) escape $`"#;~&|()<>[]*? 414887Schin */ 424887Schin 434887Schin char* 444887Schin fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags) 454887Schin { 464887Schin register unsigned char* s = (unsigned char*)as; 474887Schin register unsigned char* e = s + n; 484887Schin register char* b; 494887Schin register int c; 504887Schin register int escaped; 514887Schin register int spaced; 524887Schin register int doublequote; 534887Schin register int singlequote; 544887Schin int shell; 554887Schin char* f; 564887Schin char* buf; 574887Schin 584887Schin c = 4 * (n + 1); 594887Schin if (qb) 604887Schin c += strlen((char*)qb); 614887Schin if (qe) 624887Schin c += strlen((char*)qe); 634887Schin b = buf = fmtbuf(c); 644887Schin shell = 0; 654887Schin doublequote = 0; 664887Schin singlequote = 0; 674887Schin if (qb) 684887Schin { 694887Schin if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0) 704887Schin shell = 1; 714887Schin else if ((flags & FMT_SHELL) && qb[1] == 0) 724887Schin { 734887Schin if (qb[0] == '"') 744887Schin doublequote = 1; 754887Schin else if (qb[0] == '\'') 764887Schin singlequote = 1; 774887Schin } 784887Schin while (*b = *qb++) 794887Schin b++; 804887Schin } 814887Schin else if (flags & FMT_SHELL) 824887Schin doublequote = 1; 834887Schin f = b; 844887Schin escaped = spaced = !!(flags & FMT_ALWAYS); 854887Schin while (s < e) 864887Schin { 874887Schin if ((c = mbsize(s)) > 1) 884887Schin { 894887Schin while (c-- && s < e) 904887Schin *b++ = *s++; 914887Schin } 924887Schin else 934887Schin { 944887Schin c = *s++; 954887Schin if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\')) 964887Schin { 974887Schin escaped = 1; 984887Schin *b++ = '\\'; 994887Schin switch (c) 1004887Schin { 1014887Schin case CC_bel: 1024887Schin c = 'a'; 1034887Schin break; 1044887Schin case '\b': 1054887Schin c = 'b'; 1064887Schin break; 1074887Schin case '\f': 1084887Schin c = 'f'; 1094887Schin break; 1104887Schin case '\n': 1114887Schin c = 'n'; 1124887Schin break; 1134887Schin case '\r': 1144887Schin c = 'r'; 1154887Schin break; 1164887Schin case '\t': 1174887Schin c = 't'; 1184887Schin break; 1194887Schin case CC_vt: 1204887Schin c = 'v'; 1214887Schin break; 1224887Schin case CC_esc: 1234887Schin c = 'E'; 1244887Schin break; 1254887Schin case '\\': 1264887Schin break; 1274887Schin default: 1284887Schin if (!(flags & FMT_WIDE) || !(c & 0200)) 1294887Schin { 1304887Schin *b++ = '0' + ((c >> 6) & 07); 1314887Schin *b++ = '0' + ((c >> 3) & 07); 1324887Schin c = '0' + (c & 07); 1334887Schin } 1344887Schin else 1354887Schin b--; 1364887Schin break; 1374887Schin } 1384887Schin } 1394887Schin else if (c == '\\') 1404887Schin { 1414887Schin escaped = 1; 1424887Schin *b++ = c; 1434887Schin if (*s) 1444887Schin c = *s++; 1454887Schin } 1464887Schin else if (qe && strchr(qe, c)) 1474887Schin { 1484887Schin if (singlequote && c == '\'') 1494887Schin { 1504887Schin spaced = 1; 1514887Schin *b++ = '\''; 1524887Schin *b++ = '\\'; 1534887Schin *b++ = '\''; 1544887Schin c = '\''; 1554887Schin } 1564887Schin else 1574887Schin { 1584887Schin escaped = 1; 1594887Schin *b++ = '\\'; 1604887Schin } 1614887Schin } 1624887Schin else if (c == '$' || c == '`') 1634887Schin { 1644887Schin if (c == '$' && (flags & FMT_PARAM) && (*s == '{' || *s == '(')) 1654887Schin { 1664887Schin if (singlequote || shell) 1674887Schin { 1684887Schin escaped = 1; 1694887Schin *b++ = '\''; 1704887Schin *b++ = c; 1714887Schin *b++ = *s++; 1724887Schin if (shell) 1734887Schin { 1744887Schin spaced = 1; 1754887Schin *b++ = '$'; 1764887Schin } 1774887Schin c = '\''; 1784887Schin } 1794887Schin else 1804887Schin { 1814887Schin escaped = 1; 1824887Schin *b++ = c; 1834887Schin c = *s++; 1844887Schin } 1854887Schin } 1864887Schin else if (doublequote) 1874887Schin *b++ = '\\'; 1884887Schin else if (singlequote || (flags & FMT_SHELL)) 1894887Schin spaced = 1; 1904887Schin } 1914887Schin else if (!spaced && !escaped && (isspace(c) || ((flags & FMT_SHELL) || shell) && (strchr("\";~&|()<>[]*?", c) || c == '#' && (b == f || isspace(*(b - 1)))))) 1924887Schin spaced = 1; 1934887Schin *b++ = c; 1944887Schin } 1954887Schin } 1964887Schin if (qb) 1974887Schin { 1984887Schin if (!escaped) 1994887Schin buf += shell + !spaced; 2004887Schin if (qe && (escaped || spaced)) 2014887Schin while (*b = *qe++) 2024887Schin b++; 2034887Schin } 2044887Schin *b = 0; 2054887Schin return buf; 2064887Schin } 2074887Schin 2084887Schin /* 2094887Schin * escape the usual suspects and quote chars in qs 2104887Schin * in length n string as 2114887Schin */ 2124887Schin 2134887Schin char* 2144887Schin fmtnesq(const char* as, const char* qs, size_t n) 2154887Schin { 2164887Schin return fmtquote(as, NiL, qs, n, 0); 2174887Schin } 2184887Schin 2194887Schin /* 2204887Schin * escape the usual suspects and quote chars in qs 2214887Schin */ 2224887Schin 2234887Schin char* 2244887Schin fmtesq(const char* as, const char* qs) 2254887Schin { 2264887Schin return fmtquote(as, NiL, qs, strlen((char*)as), 0); 2274887Schin } 2284887Schin 2294887Schin /* 2304887Schin * escape the usual suspects 2314887Schin */ 2324887Schin 2334887Schin char* 2344887Schin fmtesc(const char* as) 2354887Schin { 2364887Schin return fmtquote(as, NiL, NiL, strlen((char*)as), 0); 2374887Schin } 238