source: trunk/dll/literal.c@ 298

Last change on this file since 298 was 298, checked in by root, 19 years ago

liternal: comments

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: literal.c 298 2006-06-27 00:17:58Z root $
5
6 string quoting utilities
7 wildcarding utilities
8
9 Copyright (c) 1993-98 M. Kimes
10 Copyright (c) 2004, 2006 Steven H.Levine
11
12 Archive containers
13
14 01 Aug 04 SHL Rework fixup to avoid overflows
15 16 Jun 06 SHL liternal: comments
16
17***********************************************************************/
18
19#define INCL_OS2
20#define INCL_WIN
21
22#include <os2.h>
23#include <ctype.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include "fm3dll.h"
28
29static INT index(const CHAR *s,const CHAR c);
30
31#pragma alloc_text(LITERAL,literal,index,fixup,wildcard)
32
33/* Get index of char in string
34 * @parm s string to search
35 * @parm c char to search for
36 * @return 0 relative index of c in s or -1
37 */
38
39static INT index(const CHAR *s,const CHAR c)
40{
41 CHAR *p;
42
43 p = strchr(s,c);
44 if(p == NULL || !*p)
45 return -1;
46 return (INT)(p - s);
47}
48
49/* Translate a string with \ escape tokens to binary equivalent
50 * Translates in place
51 *
52 * 1. \x1b translates to CHAR(0x1b)
53 * 2. \27 translates to CHAR(27)
54 * 3. \" translates to "
55 * 4. \' translates to '
56 * 5. \\ translates to \
57 * 6. \r translates to carriage return
58 * 7. \n translates to linefeed
59 * 8. \b translates to backspace
60 * 9. \t translates to tab
61 * 10. \a translates to bell
62 * 11. \f translates to formfeed
63 *
64 * Synopsis
65 * *s = "this\x20is\32a test of \\MSC\\CSM\7"
66 * literal(s);
67 *
68 * ( s now equals "this is a test of \MSC\CSM")
69 *
70 * Return converted character count
71 * Does not include terminating nul
72 */
73
74#define HEX "0123456789ABCDEF"
75#define DEC "0123456789"
76
77UINT literal(PSZ pszBuf)
78{
79 INT wpos;
80 INT iBuf;
81 UINT cBufBytes;
82 INT iBufSave;
83 PSZ pszOut;
84 PSZ pszWork;
85 CHAR wchar;
86
87 if(!pszBuf || !*pszBuf)
88 return 0;
89 cBufBytes = strlen(pszBuf) + 1;
90 pszWork = pszOut = malloc(cBufBytes + 1);
91
92 iBuf = 0; /* set index to first character */
93 while(pszBuf[iBuf]) {
94 switch(pszBuf[iBuf]) {
95 case '\\':
96 switch(pszBuf[iBuf + 1]) {
97 case 'x' : /* hexadecimal */
98 wchar = 0;
99 iBuf += 2; /* get past "\x" */
100 if(index(HEX,(CHAR)toupper(pszBuf[iBuf])) != -1) {
101 iBufSave = iBuf;
102 while(((wpos = index(HEX,(CHAR)toupper(pszBuf[iBuf]))) != -1) &&
103 iBuf < iBufSave + 2) {
104 wchar = (CHAR)(wchar << 4) + (CHAR)wpos;
105 iBuf++;
106 }
107 }
108 else
109 wchar = 'x'; /* just an x */
110 iBuf--;
111 *pszOut++ = wchar;
112 break;
113
114 case '\\' : /* we want a "\" */
115 iBuf++;
116 *pszOut++ = '\\';
117 break;
118
119 case 't' : /* tab CHAR */
120 iBuf++;
121 *pszOut++ = '\t';
122 break;
123
124 case 'n' : /* new line */
125 iBuf++;
126 *pszOut++ = '\n';
127 break;
128
129 case 'r' : /* carr return */
130 iBuf++;
131 *pszOut++ = '\r';
132 break;
133
134 case 'b' : /* back space */
135 iBuf++;
136 *pszOut++ = '\b';
137 break;
138
139 case 'f': /* formfeed */
140 iBuf++;
141 *pszOut++ = '\x0c';
142 break;
143
144 case 'a': /* bell */
145 iBuf++;
146 *pszOut++ = '\07';
147 break;
148
149 case '\'' : /* single quote */
150 iBuf++;
151 *pszOut++ = '\'';
152 break;
153
154 case '\"' : /* double quote */
155 iBuf++;
156 *pszOut++ = '\"';
157 break;
158
159 default : /* decimal */
160 iBuf++; /* get past "\" */
161 wchar = 0;
162 if(index(DEC,pszBuf[iBuf]) != -1) {
163 iBufSave = iBuf;
164 do { /* cvt to binary */
165 wchar = (CHAR)(wchar * 10 + (pszBuf[iBuf++] - 48));
166 } while (index(DEC,pszBuf[iBuf]) != -1 && iBuf < iBufSave + 3);
167 iBuf--;
168 }
169 else
170 wchar = pszBuf[iBuf];
171 *pszOut ++ = wchar;
172 break;
173 } // switch
174 break;
175
176 default :
177 *pszOut++ = pszBuf[iBuf];
178 break;
179 } // switch
180 iBuf++;
181 } // while
182 *pszOut = 0; /* Always terminate, even if not string */
183
184 cBufBytes = pszOut - pszWork; /* Calc string length excluding terminator */
185 memcpy(pszBuf,pszWork,cBufBytes + 1); /* Overwrite including terminator */
186 free(pszWork);
187
188 return cBufBytes; /* Return string length */
189}
190
191/* Check wildcard match
192 * @parm pszBuf Buffer to check
193 * @parm pszWildCard wildcard to match
194 * @parm fNotFileSpec TRUE if generic match else filespec match
195 * @return TRUE if matched else FALSE
196 */
197
198
199BOOL wildcard(const PSZ pszBuf,const PSZ pszWildCard,const BOOL fNotFileSpec)
200{
201 const CHAR *fstr = pszBuf;
202 PSZ fcard = pszWildCard;
203 INT wmatch = TRUE;
204
205 while(wmatch && *fcard && *fstr) {
206 switch(*fcard) {
207 case '?' : /* character substitution */
208 fcard++;
209 if(fNotFileSpec || (*fstr != '.' && *fstr != '/' && *fstr != '\\'))
210 fstr++; /* skip (match) next character */
211 break;
212
213 case '*' :
214 /* find next non-wild character in wildcard */
215 while(*fcard && (*fcard == '?' || *fcard == '*'))
216 fcard++;
217 if(!*fcard) /* if last char of wildcard is *, it matches */
218 return TRUE;
219 /* skip until partition, match, or eos */
220 while(*fstr && toupper(*fstr) != toupper(*fcard) &&
221 (fNotFileSpec || (*fstr != '\\' &&
222 *fstr != '/' && *fstr != '.')))
223 fstr++;
224 if(!fNotFileSpec && !*fstr) /* implicit '.' */
225 if(*fcard == '.')
226 fcard++;
227 break;
228
229 default :
230 if(!fNotFileSpec && ((*fstr == '/' || *fstr == '\\') &&
231 (*fcard == '/' || *fcard == '\\')))
232 wmatch = TRUE;
233 else
234 wmatch = (toupper(*fstr) == toupper(*fcard));
235 fstr++;
236 fcard++;
237 break;
238 }
239 }
240
241 if ((*fcard && *fcard != '*') || *fstr)
242 return 0;
243 else
244 return wmatch;
245}
246
247
248// fixup - quote literal character array
249
250PSZ fixup(const PCH pachIn, PSZ pszOutBuf, const UINT cBufBytes, const UINT cInBytes)
251{
252 PCH pchIn = pachIn;
253 PCH pchOut = pszOutBuf;
254 PSZ pszTemp;
255 static CHAR szTemp[5] = "\\x"; // Constant prefix
256
257 // input is a character array, not a string - may not be null terminated
258 // cBufBytes is buffer size
259 if (pachIn) {
260 // Ensure room for null and possible \ escape
261 while (pchIn - pachIn < cInBytes &&
262 pchOut - pszOutBuf + 2 < cBufBytes) {
263 if(!isprint(*pchIn)) {
264 if(*pchIn == '\r') {
265 *pchOut++ = '\\';
266 *pchOut++ = 'r';
267 }
268 else if(*pchIn == '\n') {
269 *pchOut++ = '\\';
270 *pchOut++ = 'n';
271 }
272 else if(*pchIn == '\b') {
273 *pchOut++ = '\\';
274 *pchOut++ = 'b';
275 }
276 else {
277 sprintf(szTemp + 2,"%02hx",*pchIn);
278 for (pszTemp = szTemp; *pszTemp;)
279 *pchOut++ = *pszTemp++;
280 }
281 pchIn++;
282 }
283 else if(*pchIn == '\\') {
284 *pchOut++ = '\\';
285 *pchOut++ = '\\';
286 pchIn++;
287 }
288 else
289 *pchOut++ = *pchIn++;
290 } // while
291 } // if pachIn
292 *pchOut = 0;
293 return pszOutBuf;
294}
295
Note: See TracBrowser for help on using the repository browser.