~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/sfio/sftable.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "sfhdr.h"
 
2
 
 
3
/*      Dealing with $ argument addressing stuffs.
 
4
**
 
5
**      Written by Kiem-Phong Vo.
 
6
*/
 
7
 
 
8
#if __STD_C
 
9
static char* sffmtint(const char* str, int* v)
 
10
#else
 
11
static char* sffmtint(str, v)
 
12
char*   str;
 
13
int*    v;
 
14
#endif
 
15
{       
 
16
        for(*v = 0; isdigit(*str); ++str)
 
17
                *v = *v * 10 + (*str - '0');
 
18
        *v -= 1;
 
19
        return (char*)str;
 
20
}
 
21
 
 
22
#if __STD_C
 
23
static Fmtpos_t* sffmtpos(Sfio_t* f, const char* form, va_list args, int type)
 
24
#else
 
25
static Fmtpos_t* sffmtpos(f,form,args,type)
 
26
Sfio_t*         f;
 
27
char*           form;
 
28
va_list         args;
 
29
int             type;
 
30
#endif
 
31
{
 
32
        int             base, fmt, flags, dot, width, precis;
 
33
        ssize_t         n_str, size;
 
34
        char            *t_str, *sp;
 
35
        int             v, n, skip, dollar, decimal, thousand;
 
36
        Sffmt_t         *ft, savft;
 
37
        Fmtpos_t*       fp;     /* position array of arguments  */
 
38
        int             argp, argn, maxp, need[FP_INDEX];
 
39
 
 
40
        if(type < 0)
 
41
                fp = NIL(Fmtpos_t*);
 
42
        else if(!(fp = sffmtpos(f,form,args,-1)) )
 
43
                return NIL(Fmtpos_t*);
 
44
 
 
45
        dollar = decimal = thousand = 0; argn = maxp = -1;
 
46
        while((n = *form) )
 
47
        {       if(n != '%') /* collect the non-pattern chars */
 
48
                {       sp = (char*)form++;
 
49
                        while(*form && *form != '%')
 
50
                                form += 1;
 
51
                        continue;
 
52
                }
 
53
                else    form += 1;
 
54
                if(*form == 0)
 
55
                        break;
 
56
                else if(*form == '%')
 
57
                {       form += 1;
 
58
                        continue;
 
59
                }
 
60
 
 
61
                if(*form == '*' && type > 0) /* skip in scanning */
 
62
                {       skip = 1;
 
63
                        form += 1;
 
64
                        argp = -1;
 
65
                }
 
66
                else /* get the position of this argument */
 
67
                {       skip = 0;
 
68
                        sp = sffmtint(form,&argp);
 
69
                        if(*sp == '$')
 
70
                        {       dollar = 1;
 
71
                                form = sp+1;
 
72
                        }
 
73
                        else    argp = -1;
 
74
                }
 
75
 
 
76
                flags = dot = 0;
 
77
                t_str = NIL(char*); n_str = 0;
 
78
                size = width = precis = base = -1;
 
79
                for(n = 0; n < FP_INDEX; ++n)
 
80
                        need[n] = -1;
 
81
 
 
82
        loop_flags:     /* LOOP FOR \0, %, FLAGS, WIDTH, PRECISION, BASE, TYPE */
 
83
                switch((fmt = *form++) )
 
84
                {
 
85
                case LEFTP : /* get the type enclosed in balanced parens */
 
86
                        t_str = (char*)form;
 
87
                        for(v = 1;;)
 
88
                        {       switch(*form++)
 
89
                                {
 
90
                                case 0 :        /* not balancable, retract */
 
91
                                        form = t_str;
 
92
                                        t_str = NIL(char*);
 
93
                                        n_str = 0;
 
94
                                        goto loop_flags;
 
95
                                case LEFTP :    /* increasing nested level */
 
96
                                        v += 1;
 
97
                                        continue;
 
98
                                case RIGHTP :   /* decreasing nested level */
 
99
                                        if((v -= 1) != 0)
 
100
                                                continue;
 
101
                                        n_str = form-t_str;
 
102
                                        if(*t_str == '*')
 
103
                                        {       t_str = sffmtint(t_str+1,&n);
 
104
                                                if(*t_str == '$')
 
105
                                                        dollar = 1;
 
106
                                                else    n = -1;
 
107
                                                if((n = FP_SET(n,argn)) > maxp)
 
108
                                                        maxp = n;
 
109
                                                if(fp && fp[n].ft.fmt == 0)
 
110
                                                {       fp[n].ft.fmt = LEFTP;
 
111
                                                        fp[n].ft.form = (char*)form;
 
112
                                                }
 
113
                                                need[FP_STR] = n;
 
114
                                        }
 
115
                                        goto loop_flags;
 
116
                                }
 
117
                        }
 
118
 
 
119
                case '-' :
 
120
                        flags |= SFFMT_LEFT;
 
121
                        flags &= ~SFFMT_ZERO;
 
122
                        goto loop_flags;
 
123
                case '0' :
 
124
                        if(!(flags&SFFMT_LEFT) )
 
125
                                flags |= SFFMT_ZERO;
 
126
                        goto loop_flags;
 
127
                case ' ' :
 
128
                        if(!(flags&SFFMT_SIGN) )
 
129
                                flags |= SFFMT_BLANK;
 
130
                        goto loop_flags;
 
131
                case '+' :
 
132
                        flags |= SFFMT_SIGN;
 
133
                        flags &= ~SFFMT_BLANK;
 
134
                        goto loop_flags;
 
135
                case '#' :
 
136
                        flags |= SFFMT_ALTER;
 
137
                        goto loop_flags;
 
138
                case QUOTE:
 
139
                        SFSETLOCALE(&decimal,&thousand);
 
140
                        if(thousand)
 
141
                                flags |= SFFMT_THOUSAND;
 
142
                        goto loop_flags;
 
143
 
 
144
                case '.' :
 
145
                        if((dot += 1) == 2)
 
146
                                base = 0; /* for %s,%c */
 
147
                        if(isdigit(*form))
 
148
                        {       fmt = *form++;
 
149
                                goto dot_size;
 
150
                        }
 
151
                        else if(*form != '*')
 
152
                                goto loop_flags;
 
153
                        else    form += 1; /* drop thru below */
 
154
 
 
155
                case '*' :
 
156
                        form = sffmtint(form,&n);
 
157
                        if(*form == '$' )
 
158
                        {       dollar = 1;
 
159
                                form += 1;
 
160
                        }
 
161
                        else    n = -1;
 
162
                        if((n = FP_SET(n,argn)) > maxp)
 
163
                                maxp = n;
 
164
                        if(fp && fp[n].ft.fmt == 0)
 
165
                        {       fp[n].ft.fmt = '.';
 
166
                                fp[n].ft.size = dot;
 
167
                                fp[n].ft.form = (char*)form;
 
168
                        }
 
169
                        if(dot <= 2)
 
170
                                need[dot] = n;
 
171
                        goto loop_flags;
 
172
 
 
173
                case '1' : case '2' : case '3' :
 
174
                case '4' : case '5' : case '6' :
 
175
                case '7' : case '8' : case '9' :
 
176
                dot_size :
 
177
                        for(v = fmt - '0', fmt = *form; isdigit(fmt); fmt = *++form)
 
178
                                v = v*10 + (fmt - '0');
 
179
                        if(dot == 0)
 
180
                                width = v;
 
181
                        else if(dot == 1)
 
182
                                precis = v;
 
183
                        else if(dot == 2)
 
184
                                base = v;
 
185
                        goto loop_flags;
 
186
 
 
187
                case 'I' : /* object length */
 
188
                        size = 0;
 
189
                        flags = (flags & ~SFFMT_TYPES) | SFFMT_IFLAG;
 
190
                        if(isdigit(*form) )
 
191
                        {       for(n = *form; isdigit(n); n = *++form)
 
192
                                        size = size*10 + (n - '0');
 
193
                        }
 
194
                        else if(*form == '*')
 
195
                        {       form = sffmtint(form+1,&n);
 
196
                                if(*form == '$' )
 
197
                                {       dollar = 1;
 
198
                                        form += 1;
 
199
                                }
 
200
                                else    n = -1;
 
201
                                if((n = FP_SET(n,argn)) > maxp)
 
202
                                        maxp = n;
 
203
                                if(fp && fp[n].ft.fmt == 0)
 
204
                                {       fp[n].ft.fmt = 'I';
 
205
                                        fp[n].ft.size = sizeof(int);
 
206
                                        fp[n].ft.form = (char*)form;
 
207
                                }
 
208
                                need[FP_SIZE] = n;
 
209
                        }
 
210
                        goto loop_flags;
 
211
 
 
212
                case 'l' :
 
213
                        size = -1;
 
214
                        flags &= ~SFFMT_TYPES;
 
215
                        if(*form == 'l')
 
216
                        {       form += 1;
 
217
                                flags |= SFFMT_LLONG;
 
218
                        }
 
219
                        else    flags |= SFFMT_LONG;
 
220
                        goto loop_flags;
 
221
                case 'h' :
 
222
                        size = -1;
 
223
                        flags &= ~SFFMT_TYPES;
 
224
                        if(*form == 'h')
 
225
                        {       form += 1;
 
226
                                flags |= SFFMT_SSHORT;
 
227
                        }
 
228
                        else    flags |= SFFMT_SHORT;
 
229
                        goto loop_flags;
 
230
                case 'L' :
 
231
                        size = -1;
 
232
                        flags = (flags & ~SFFMT_TYPES) | SFFMT_LDOUBLE;
 
233
                        goto loop_flags;
 
234
                }
 
235
 
 
236
                if(flags & (SFFMT_TYPES & ~SFFMT_IFLAG) )
 
237
                {       if((_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT)) || fmt == 'n')
 
238
                        {       size =  (flags&SFFMT_LLONG) ? sizeof(Sflong_t) :
 
239
                                        (flags&SFFMT_LONG) ? sizeof(long) :
 
240
                                        (flags&SFFMT_SHORT) ? sizeof(short) :
 
241
                                        (flags&SFFMT_SSHORT) ? sizeof(char) :
 
242
                                        (flags&SFFMT_JFLAG) ? sizeof(Sflong_t) :
 
243
                                        (flags&SFFMT_TFLAG) ? sizeof(ptrdiff_t) :
 
244
                                        (flags&SFFMT_ZFLAG) ? sizeof(size_t) :
 
245
                                        -1;
 
246
                        }
 
247
                        else if(_Sftype[fmt]&SFFMT_FLOAT)
 
248
                        {       size = (flags&SFFMT_LDOUBLE) ? sizeof(Sfdouble_t) :
 
249
                                       (flags&(SFFMT_LONG|SFFMT_LLONG)) ?
 
250
                                                sizeof(double) : -1;
 
251
                        }
 
252
                }
 
253
 
 
254
                if(skip)
 
255
                        continue;
 
256
 
 
257
                if((argp = FP_SET(argp,argn)) > maxp)
 
258
                        maxp = argp;
 
259
 
 
260
                if(dollar && fmt == '!')
 
261
                        return NIL(Fmtpos_t*);
 
262
 
 
263
                if(fp && fp[argp].ft.fmt == 0)
 
264
                {       fp[argp].ft.form = (char*)form;
 
265
                        fp[argp].ft.fmt = fp[argp].fmt = fmt;
 
266
                        fp[argp].ft.size = size;
 
267
                        fp[argp].ft.flags = flags;
 
268
                        fp[argp].ft.width = width;
 
269
                        fp[argp].ft.precis = precis;
 
270
                        fp[argp].ft.base = base;
 
271
                        fp[argp].ft.t_str = t_str;
 
272
                        fp[argp].ft.n_str = n_str;
 
273
                        for(n = 0; n < FP_INDEX; ++n)
 
274
                                fp[argp].need[n] = need[n];
 
275
                }
 
276
        }
 
277
 
 
278
        if(!fp) /* constructing position array only */
 
279
        {       if(!dollar || !(fp = (Fmtpos_t*)malloc((maxp+1)*sizeof(Fmtpos_t))) )
 
280
                        return NIL(Fmtpos_t*);
 
281
                for(n = 0; n <= maxp; ++n)
 
282
                        fp[n].ft.fmt = 0;
 
283
                return fp;
 
284
        }
 
285
 
 
286
        /* get value for positions */
 
287
        for(n = 0, ft = NIL(Sffmt_t*); n <= maxp; ++n)
 
288
        {       if(fp[n].ft.fmt == 0) /* gap: pretend it's a 'd' pattern */
 
289
                {       fp[n].ft.fmt = 'd';
 
290
                        fp[n].ft.width = 0;
 
291
                        fp[n].ft.precis = 0;
 
292
                        fp[n].ft.base = 0;
 
293
                        fp[n].ft.size = 0;
 
294
                        fp[n].ft.t_str = 0;
 
295
                        fp[n].ft.n_str = 0;
 
296
                        fp[n].ft.flags = 0;
 
297
                        for(v = 0; v < FP_INDEX; ++v)
 
298
                                fp[n].need[v] = -1;
 
299
                }
 
300
 
 
301
                if(ft && ft->extf)
 
302
                {       fp[n].ft.version = ft->version;
 
303
                        fp[n].ft.extf = ft->extf;
 
304
                        fp[n].ft.eventf = ft->eventf;
 
305
                        if((v = fp[n].need[FP_WIDTH]) >= 0 && v < n)
 
306
                                fp[n].ft.width = fp[v].argv.i;
 
307
                        if((v = fp[n].need[FP_PRECIS]) >= 0 && v < n)
 
308
                                fp[n].ft.precis = fp[v].argv.i;
 
309
                        if((v = fp[n].need[FP_BASE]) >= 0 && v < n)
 
310
                                fp[n].ft.base = fp[v].argv.i;
 
311
                        if((v = fp[n].need[FP_STR]) >= 0 && v < n)
 
312
                                fp[n].ft.t_str = fp[v].argv.s;
 
313
                        if((v = fp[n].need[FP_SIZE]) >= 0 && v < n)
 
314
                                fp[n].ft.size = fp[v].argv.i;
 
315
 
 
316
                        memcpy(ft,&fp[n].ft,sizeof(Sffmt_t));
 
317
                        va_copy(ft->args,args);
 
318
                        ft->flags |= SFFMT_ARGPOS;
 
319
                        v = (*ft->extf)(f, (Void_t*)(&fp[n].argv), ft);
 
320
                        va_copy(args,ft->args);
 
321
                        memcpy(&fp[n].ft,ft,sizeof(Sffmt_t));
 
322
                        if(v < 0)
 
323
                        {       memcpy(ft,&savft,sizeof(Sffmt_t));
 
324
                                ft = NIL(Sffmt_t*);
 
325
                        }
 
326
 
 
327
                        if(!(fp[n].ft.flags&SFFMT_VALUE) )
 
328
                                goto arg_list;
 
329
                }
 
330
                else
 
331
                { arg_list:
 
332
                        if(fp[n].ft.fmt == LEFTP)
 
333
                        {       fp[n].argv.s = va_arg(args, char*);
 
334
                                fp[n].ft.size = strlen(fp[n].argv.s);
 
335
                        }
 
336
                        else if(fp[n].ft.fmt == '.' || fp[n].ft.fmt == 'I')
 
337
                                fp[n].argv.i = va_arg(args, int);
 
338
                        else if(fp[n].ft.fmt == '!')
 
339
                        {       if(ft)
 
340
                                        memcpy(ft,&savft,sizeof(Sffmt_t));
 
341
                                fp[n].argv.ft = ft = va_arg(args, Sffmt_t*);
 
342
                                if(ft->form)
 
343
                                        ft = NIL(Sffmt_t*);
 
344
                                if(ft)
 
345
                                        memcpy(&savft,ft,sizeof(Sffmt_t));
 
346
                        }
 
347
                        else if(type > 0) /* from sfvscanf */
 
348
                                fp[n].argv.vp = va_arg(args, Void_t*);
 
349
                        else switch(_Sftype[fp[n].ft.fmt])
 
350
                        { case SFFMT_INT:
 
351
                          case SFFMT_UINT:
 
352
#if !_ast_intmax_long
 
353
                                if(FMTCMP(size, Sflong_t, Sflong_t))
 
354
                                        fp[n].argv.ll = va_arg(args, Sflong_t);
 
355
                                else
 
356
#endif
 
357
                                if(FMTCMP(size, long, Sflong_t) )
 
358
                                        fp[n].argv.l = va_arg(args, long);
 
359
                                else    fp[n].argv.i = va_arg(args, int);
 
360
                                break;
 
361
                          case SFFMT_FLOAT:
 
362
#if !_ast_fltmax_double
 
363
                                if(FMTCMP(size, Sfdouble_t, Sfdouble_t))
 
364
                                        fp[n].argv.ld = va_arg(args,Sfdouble_t);
 
365
                                else
 
366
#endif
 
367
                                        fp[n].argv.d  = va_arg(args,double);
 
368
                                break;
 
369
                          case SFFMT_POINTER:
 
370
                                        fp[n].argv.vp = va_arg(args,Void_t*);
 
371
                                break;
 
372
                          case SFFMT_BYTE:
 
373
                                if(fp[n].ft.base >= 0)
 
374
                                        fp[n].argv.s = va_arg(args,char*);
 
375
                                else    fp[n].argv.c = (char)va_arg(args,int);
 
376
                                break;
 
377
                          default: /* unknown pattern */
 
378
                                break;
 
379
                        }
 
380
                }
 
381
        }
 
382
 
 
383
        if(ft)
 
384
                memcpy(ft,&savft,sizeof(Sffmt_t));
 
385
        return fp;
 
386
}
 
387
 
 
388
 
 
389
/* function to initialize conversion tables */
 
390
static int sfcvinit()
 
391
{       reg int d, l;
 
392
 
 
393
        for(d = 0; d <= SF_MAXCHAR; ++d)
 
394
        {       _Sfcv36[d] = SF_RADIX;
 
395
                _Sfcv64[d] = SF_RADIX;
 
396
        }
 
397
 
 
398
        /* [0-9] */
 
399
        for(d = 0; d < 10; ++d)
 
400
        {       _Sfcv36[(uchar)_Sfdigits[d]] = d;
 
401
                _Sfcv64[(uchar)_Sfdigits[d]] = d;
 
402
        }
 
403
 
 
404
        /* [a-z] */
 
405
        for(; d < 36; ++d)
 
406
        {       _Sfcv36[(uchar)_Sfdigits[d]] = d;
 
407
                _Sfcv64[(uchar)_Sfdigits[d]] = d;
 
408
        }
 
409
 
 
410
        /* [A-Z] */
 
411
        for(l = 10; d < 62; ++l, ++d)
 
412
        {       _Sfcv36[(uchar)_Sfdigits[d]] = l;
 
413
                _Sfcv64[(uchar)_Sfdigits[d]] = d;
 
414
        }
 
415
 
 
416
        /* remaining digits */
 
417
        for(; d < SF_RADIX; ++d)
 
418
        {       _Sfcv36[(uchar)_Sfdigits[d]] = d;
 
419
                _Sfcv64[(uchar)_Sfdigits[d]] = d;
 
420
        }
 
421
 
 
422
        _Sftype['d'] = _Sftype['i'] = SFFMT_INT;
 
423
        _Sftype['u'] = _Sftype['o'] = _Sftype['x'] = _Sftype['X'] = SFFMT_UINT;
 
424
        _Sftype['e'] = _Sftype['E'] =
 
425
        _Sftype['g'] = _Sftype['G'] = _Sftype['f'] = SFFMT_FLOAT;
 
426
        _Sftype['s'] = _Sftype['n'] = _Sftype['p'] = _Sftype['!'] = SFFMT_POINTER;
 
427
        _Sftype['c'] = SFFMT_BYTE;
 
428
        _Sftype['['] = SFFMT_CLASS;
 
429
 
 
430
        return 1;
 
431
}
 
432
 
 
433
/* table for floating point and integer conversions */
 
434
Sftab_t _Sftable =
 
435
{
 
436
        { 1e1, 1e2, 1e4, 1e8, 1e16, 1e32 },             /* _Sfpos10     */
 
437
 
 
438
        { 1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32 },       /* _Sfneg10     */
 
439
 
 
440
        { '0','0', '0','1', '0','2', '0','3', '0','4',  /* _Sfdec       */
 
441
          '0','5', '0','6', '0','7', '0','8', '0','9',
 
442
          '1','0', '1','1', '1','2', '1','3', '1','4',
 
443
          '1','5', '1','6', '1','7', '1','8', '1','9',
 
444
          '2','0', '2','1', '2','2', '2','3', '2','4',
 
445
          '2','5', '2','6', '2','7', '2','8', '2','9',
 
446
          '3','0', '3','1', '3','2', '3','3', '3','4',
 
447
          '3','5', '3','6', '3','7', '3','8', '3','9',
 
448
          '4','0', '4','1', '4','2', '4','3', '4','4',
 
449
          '4','5', '4','6', '4','7', '4','8', '4','9',
 
450
          '5','0', '5','1', '5','2', '5','3', '5','4',
 
451
          '5','5', '5','6', '5','7', '5','8', '5','9',
 
452
          '6','0', '6','1', '6','2', '6','3', '6','4',
 
453
          '6','5', '6','6', '6','7', '6','8', '6','9',
 
454
          '7','0', '7','1', '7','2', '7','3', '7','4',
 
455
          '7','5', '7','6', '7','7', '7','8', '7','9',
 
456
          '8','0', '8','1', '8','2', '8','3', '8','4',
 
457
          '8','5', '8','6', '8','7', '8','8', '8','9',
 
458
          '9','0', '9','1', '9','2', '9','3', '9','4',
 
459
          '9','5', '9','6', '9','7', '9','8', '9','9',
 
460
        },
 
461
 
 
462
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_",
 
463
 
 
464
        sfcvinit, 0,
 
465
        sffmtpos,
 
466
        sffmtint
 
467
};