source: trunk/dll/literal.c@ 117

Last change on this file since 117 was 117, checked in by root, 21 years ago

Rework fixup to avoid overflows

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