source: trunk/dll/literal.c@ 351

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

Check more run time errors

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