~ubuntu-branches/ubuntu/quantal/enigmail/quantal-security

« back to all changes in this revision

Viewing changes to config/mkdepend/ifparser.c

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2013-09-13 16:02:15 UTC
  • mfrom: (0.12.16)
  • Revision ID: package-import@ubuntu.com-20130913160215-u3g8nmwa0pdwagwc
Tags: 2:1.5.2-0ubuntu0.12.10.1
* New upstream release v1.5.2 for Thunderbird 24

* Build enigmail using a stripped down Thunderbird 17 build system, as it's
  now quite difficult to build the way we were doing previously, with the
  latest Firefox build system
* Add debian/patches/no_libxpcom.patch - Don't link against libxpcom, as it
  doesn't exist anymore (but exists in the build system)
* Add debian/patches/use_sdk.patch - Use the SDK version of xpt.py and
  friends
* Drop debian/patches/ipc-pipe_rename.diff (not needed anymore)
* Drop debian/patches/makefile_depth.diff (not needed anymore)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * $Xorg: ifparser.c,v 1.3 2000/08/17 19:41:50 cpqbld Exp $
3
 
 *
4
 
 * Copyright 1992 Network Computing Devices, Inc.
5
 
 * 
6
 
 * Permission to use, copy, modify, and distribute this software and its
7
 
 * documentation for any purpose and without fee is hereby granted, provided
8
 
 * that the above copyright notice appear in all copies and that both that
9
 
 * copyright notice and this permission notice appear in supporting
10
 
 * documentation, and that the name of Network Computing Devices may not be
11
 
 * used in advertising or publicity pertaining to distribution of the software
12
 
 * without specific, written prior permission.  Network Computing Devices makes
13
 
 * no representations about the suitability of this software for any purpose.
14
 
 * It is provided ``as is'' without express or implied warranty.
15
 
 * 
16
 
 * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17
 
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
18
 
 * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
19
 
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20
 
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
21
 
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
 
 * PERFORMANCE OF THIS SOFTWARE.
23
 
 * 
24
 
 * Author:  Jim Fulton
25
 
 *          Network Computing Devices, Inc.
26
 
 * 
27
 
 * Simple if statement processor
28
 
 *
29
 
 * This module can be used to evaluate string representations of C language
30
 
 * if constructs.  It accepts the following grammar:
31
 
 * 
32
 
 *     EXPRESSION       :=      VALUE
33
 
 *                       |      VALUE  BINOP    EXPRESSION
34
 
 *                       |      VALUE   '?'     EXPRESSION ':'  EXPRESSION
35
 
 * 
36
 
 *     VALUE            :=      '('  EXPRESSION  ')'
37
 
 *                       |      '!'  VALUE
38
 
 *                       |      '-'  VALUE
39
 
 *                       |      '+'  VALUE
40
 
 *                       |      '~'  VALUE
41
 
 *                       |      'defined'  '('  variable  ')'
42
 
 *                       |      'defined'  variable
43
 
 *                       |      # variable '(' variable-list ')'
44
 
 *                       |      variable
45
 
 *                       |      number
46
 
 * 
47
 
 *     BINOP            :=      '*'     |  '/'  |  '%'
48
 
 *                       |      '+'     |  '-'
49
 
 *                       |      '<<'    |  '>>'
50
 
 *                       |      '<'     |  '>'  |  '<='  |  '>='
51
 
 *                       |      '=='    |  '!='
52
 
 *                       |      '&'     |  '^'  |  '|'
53
 
 *                       |      '&&'    |  '||'
54
 
 * 
55
 
 * The normal C order of precedence is supported.
56
 
 * 
57
 
 * 
58
 
 * External Entry Points:
59
 
 * 
60
 
 *     ParseIfExpression                parse a string for #if
61
 
 */
62
 
/* $XFree86: xc/config/makedepend/ifparser.c,v 3.11 2002/09/23 01:48:08 tsi Exp $ */
63
 
 
64
 
#include "ifparser.h"
65
 
#include <ctype.h>
66
 
#include <stdlib.h>
67
 
#include <string.h>
68
 
 
69
 
/****************************************************************************
70
 
                   Internal Macros and Utilities for Parser
71
 
 ****************************************************************************/
72
 
 
73
 
#define DO(val) if (!(val)) return NULL
74
 
#define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff))
75
 
#define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++
76
 
#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_')
77
 
 
78
 
 
79
 
static const char *
80
 
parse_variable (IfParser *g, const char *cp, const char **varp)
81
 
{
82
 
    SKIPSPACE (cp);
83
 
 
84
 
    if (!isvarfirstletter (*cp))
85
 
        return CALLFUNC(g, handle_error) (g, cp, "variable name");
86
 
 
87
 
    *varp = cp;
88
 
    /* EMPTY */
89
 
    for (cp++; isalnum(*cp) || *cp == '_'; cp++) ;
90
 
    return cp;
91
 
}
92
 
 
93
 
 
94
 
static const char *
95
 
parse_number (IfParser *g, const char *cp, long *valp)
96
 
{
97
 
    long base = 10;
98
 
    SKIPSPACE (cp);
99
 
 
100
 
    if (!isdigit(*cp))
101
 
        return CALLFUNC(g, handle_error) (g, cp, "number");
102
 
 
103
 
    *valp = 0;
104
 
 
105
 
    if (*cp == '0') {
106
 
        cp++;
107
 
        if ((*cp == 'x') || (*cp == 'X')) {
108
 
            base = 16;
109
 
            cp++;
110
 
        } else {
111
 
            base = 8;
112
 
        }
113
 
    }
114
 
 
115
 
    /* Ignore overflows and assume ASCII, what source is usually written in */
116
 
    while (1) {
117
 
        int increment = -1;
118
 
        if (base == 8) {
119
 
            if ((*cp >= '0') && (*cp <= '7'))
120
 
                increment = *cp++ - '0';
121
 
        } else if (base == 16) {
122
 
            if ((*cp >= '0') && (*cp <= '9'))
123
 
                increment = *cp++ - '0';
124
 
            else if ((*cp >= 'A') &&  (*cp <= 'F'))
125
 
                increment = *cp++ - ('A' - 10);
126
 
            else if ((*cp >= 'a') && (*cp <= 'f'))
127
 
                increment = *cp++ - ('a' - 10);
128
 
        } else {        /* Decimal */
129
 
            if ((*cp >= '0') && (*cp <= '9'))
130
 
                increment = *cp++ - '0';
131
 
        }
132
 
        if (increment < 0)
133
 
            break;
134
 
        *valp = (*valp * base) + increment;
135
 
    }
136
 
 
137
 
    /* Skip trailing qualifiers */
138
 
    while (*cp == 'U' || *cp == 'u' || *cp == 'L' || *cp == 'l') cp++;
139
 
    return cp;
140
 
}
141
 
 
142
 
static const char *
143
 
parse_character (IfParser *g, const char *cp, long *valp)
144
 
{
145
 
    char val;
146
 
 
147
 
    SKIPSPACE (cp);
148
 
    if (*cp == '\\')
149
 
        switch (cp[1]) {
150
 
        case 'n': val = '\n'; break;
151
 
        case 't': val = '\t'; break;
152
 
        case 'v': val = '\v'; break;
153
 
        case 'b': val = '\b'; break;
154
 
        case 'r': val = '\r'; break;
155
 
        case 'f': val = '\f'; break;
156
 
        case 'a': val = '\a'; break;
157
 
        case '\\': val = '\\'; break;
158
 
        case '?': val = '\?'; break;
159
 
        case '\'': val = '\''; break;
160
 
        case '\"': val = '\"'; break;
161
 
        case 'x': val = (char) strtol (cp + 2, NULL, 16); break;
162
 
        default: val = (char) strtol (cp + 1, NULL, 8); break;
163
 
        }
164
 
    else
165
 
        val = *cp;
166
 
    while (*cp != '\'') cp++;
167
 
    *valp = (long) val;
168
 
    return cp;
169
 
}
170
 
 
171
 
static const char *
172
 
parse_value (IfParser *g, const char *cp, long *valp)
173
 
{
174
 
    const char *var, *varend;
175
 
 
176
 
    *valp = 0;
177
 
 
178
 
    SKIPSPACE (cp);
179
 
    if (!*cp)
180
 
        return cp;
181
 
 
182
 
    switch (*cp) {
183
 
      case '(':
184
 
        DO (cp = ParseIfExpression (g, cp + 1, valp));
185
 
        SKIPSPACE (cp);
186
 
        if (*cp != ')') 
187
 
            return CALLFUNC(g, handle_error) (g, cp, ")");
188
 
 
189
 
        return cp + 1;                  /* skip the right paren */
190
 
 
191
 
      case '!':
192
 
        DO (cp = parse_value (g, cp + 1, valp));
193
 
        *valp = !(*valp);
194
 
        return cp;
195
 
 
196
 
      case '-':
197
 
        DO (cp = parse_value (g, cp + 1, valp));
198
 
        *valp = -(*valp);
199
 
        return cp;
200
 
 
201
 
      case '+':
202
 
        DO (cp = parse_value (g, cp + 1, valp));
203
 
        return cp;
204
 
 
205
 
      case '~':
206
 
        DO (cp = parse_value (g, cp + 1, valp));
207
 
        *valp = ~(*valp);
208
 
        return cp;
209
 
 
210
 
      case '#':
211
 
        DO (cp = parse_variable (g, cp + 1, &var));
212
 
        SKIPSPACE (cp);
213
 
        if (*cp != '(')
214
 
            return CALLFUNC(g, handle_error) (g, cp, "(");
215
 
        do {
216
 
            DO (cp = parse_variable (g, cp + 1, &var));
217
 
            SKIPSPACE (cp);
218
 
        } while (*cp && *cp != ')');
219
 
        if (*cp != ')')
220
 
            return CALLFUNC(g, handle_error) (g, cp, ")");
221
 
        *valp = 1; /* XXX */
222
 
        return cp + 1;
223
 
 
224
 
      case '\'':
225
 
        DO (cp = parse_character (g, cp + 1, valp));
226
 
        if (*cp != '\'')
227
 
            return CALLFUNC(g, handle_error) (g, cp, "'");
228
 
        return cp + 1;
229
 
 
230
 
      case 'd':
231
 
        if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) {
232
 
            int paren = 0;
233
 
            int len;
234
 
 
235
 
            cp += 7;
236
 
            SKIPSPACE (cp);
237
 
            if (*cp == '(') {
238
 
                paren = 1;
239
 
                cp++;
240
 
            }
241
 
            DO (cp = parse_variable (g, cp, &var));
242
 
            len = cp - var;
243
 
            SKIPSPACE (cp);
244
 
            if (paren && *cp != ')')
245
 
                return CALLFUNC(g, handle_error) (g, cp, ")");
246
 
            *valp = (*(g->funcs.eval_defined)) (g, var, len);
247
 
            return cp + paren;          /* skip the right paren */
248
 
        }
249
 
        /* fall out */
250
 
    }
251
 
 
252
 
    if (isdigit(*cp)) {
253
 
        DO (cp = parse_number (g, cp, valp));
254
 
    } else if (!isvarfirstletter(*cp))
255
 
        return CALLFUNC(g, handle_error) (g, cp, "variable or number");
256
 
    else {
257
 
        DO (cp = parse_variable (g, cp, &var));
258
 
        varend = cp;
259
 
        SKIPSPACE(cp);
260
 
        if (*cp != '(') {
261
 
            *valp = (*(g->funcs.eval_variable)) (g, var, varend - var);
262
 
        } else {
263
 
            do {
264
 
                long dummy;
265
 
                DO (cp = ParseIfExpression (g, cp + 1, &dummy));
266
 
                SKIPSPACE(cp);
267
 
                if (*cp == ')')
268
 
                    break;
269
 
                if (*cp != ',')
270
 
                    return CALLFUNC(g, handle_error) (g, cp, ",");
271
 
            } while (1);
272
 
 
273
 
            *valp = 1;  /* XXX */
274
 
            cp++;
275
 
        }
276
 
    }
277
 
    
278
 
    return cp;
279
 
}
280
 
 
281
 
 
282
 
 
283
 
static const char *
284
 
parse_product (IfParser *g, const char *cp, long *valp)
285
 
{
286
 
    long rightval;
287
 
 
288
 
    DO (cp = parse_value (g, cp, valp));
289
 
    SKIPSPACE (cp);
290
 
 
291
 
    switch (*cp) {
292
 
      case '*':
293
 
        DO (cp = parse_product (g, cp + 1, &rightval));
294
 
        *valp = (*valp * rightval);
295
 
        break;
296
 
 
297
 
      case '/':
298
 
        DO (cp = parse_product (g, cp + 1, &rightval));
299
 
        if (rightval == 0)
300
 
          return CALLFUNC(g, handle_error) (g, cp, "0");
301
 
        *valp = (*valp / rightval);
302
 
        break;
303
 
 
304
 
      case '%':
305
 
        DO (cp = parse_product (g, cp + 1, &rightval));
306
 
        *valp = (*valp % rightval);
307
 
        break;
308
 
    }
309
 
    return cp;
310
 
}
311
 
 
312
 
 
313
 
static const char *
314
 
parse_sum (IfParser *g, const char *cp, long *valp)
315
 
{
316
 
    long rightval;
317
 
 
318
 
    DO (cp = parse_product (g, cp, valp));
319
 
    SKIPSPACE (cp);
320
 
 
321
 
    switch (*cp) {
322
 
      case '+':
323
 
        DO (cp = parse_sum (g, cp + 1, &rightval));
324
 
        *valp = (*valp + rightval);
325
 
        break;
326
 
 
327
 
      case '-':
328
 
        DO (cp = parse_sum (g, cp + 1, &rightval));
329
 
        *valp = (*valp - rightval);
330
 
        break;
331
 
    }
332
 
    return cp;
333
 
}
334
 
 
335
 
 
336
 
static const char *
337
 
parse_shift (IfParser *g, const char *cp, long *valp)
338
 
{
339
 
    long rightval;
340
 
 
341
 
    DO (cp = parse_sum (g, cp, valp));
342
 
    SKIPSPACE (cp);
343
 
 
344
 
    switch (*cp) {
345
 
      case '<':
346
 
        if (cp[1] == '<') {
347
 
            DO (cp = parse_shift (g, cp + 2, &rightval));
348
 
            *valp = (*valp << rightval);
349
 
        }
350
 
        break;
351
 
 
352
 
      case '>':
353
 
        if (cp[1] == '>') {
354
 
            DO (cp = parse_shift (g, cp + 2, &rightval));
355
 
            *valp = (*valp >> rightval);
356
 
        }
357
 
        break;
358
 
    }
359
 
    return cp;
360
 
}
361
 
 
362
 
 
363
 
static const char *
364
 
parse_inequality (IfParser *g, const char *cp, long *valp)
365
 
{
366
 
    long rightval;
367
 
 
368
 
    DO (cp = parse_shift (g, cp, valp));
369
 
    SKIPSPACE (cp);
370
 
 
371
 
    switch (*cp) {
372
 
      case '<':
373
 
        if (cp[1] == '=') {
374
 
            DO (cp = parse_inequality (g, cp + 2, &rightval));
375
 
            *valp = (*valp <= rightval);
376
 
        } else {
377
 
            DO (cp = parse_inequality (g, cp + 1, &rightval));
378
 
            *valp = (*valp < rightval);
379
 
        }
380
 
        break;
381
 
 
382
 
      case '>':
383
 
        if (cp[1] == '=') {
384
 
            DO (cp = parse_inequality (g, cp + 2, &rightval));
385
 
            *valp = (*valp >= rightval);
386
 
        } else {
387
 
            DO (cp = parse_inequality (g, cp + 1, &rightval));
388
 
            *valp = (*valp > rightval);
389
 
        }
390
 
        break;
391
 
    }
392
 
    return cp;
393
 
}
394
 
 
395
 
 
396
 
static const char *
397
 
parse_equality (IfParser *g, const char *cp, long *valp)
398
 
{
399
 
    long rightval;
400
 
 
401
 
    DO (cp = parse_inequality (g, cp, valp));
402
 
    SKIPSPACE (cp);
403
 
 
404
 
    switch (*cp) {
405
 
      case '=':
406
 
        if (cp[1] == '=')
407
 
            cp++;
408
 
        DO (cp = parse_equality (g, cp + 1, &rightval));
409
 
        *valp = (*valp == rightval);
410
 
        break;
411
 
 
412
 
      case '!':
413
 
        if (cp[1] != '=')
414
 
            break;
415
 
        DO (cp = parse_equality (g, cp + 2, &rightval));
416
 
        *valp = (*valp != rightval);
417
 
        break;
418
 
    }
419
 
    return cp;
420
 
}
421
 
 
422
 
 
423
 
static const char *
424
 
parse_band (IfParser *g, const char *cp, long *valp)
425
 
{
426
 
    long rightval;
427
 
 
428
 
    DO (cp = parse_equality (g, cp, valp));
429
 
    SKIPSPACE (cp);
430
 
 
431
 
    switch (*cp) {
432
 
      case '&':
433
 
        if (cp[1] != '&') {
434
 
            DO (cp = parse_band (g, cp + 1, &rightval));
435
 
            *valp = (*valp & rightval);
436
 
        }
437
 
        break;
438
 
    }
439
 
    return cp;
440
 
}
441
 
 
442
 
 
443
 
static const char *
444
 
parse_bxor (IfParser *g, const char *cp, long *valp)
445
 
{
446
 
    long rightval;
447
 
 
448
 
    DO (cp = parse_band (g, cp, valp));
449
 
    SKIPSPACE (cp);
450
 
 
451
 
    switch (*cp) {
452
 
      case '^':
453
 
        DO (cp = parse_bxor (g, cp + 1, &rightval));
454
 
        *valp = (*valp ^ rightval);
455
 
        break;
456
 
    }
457
 
    return cp;
458
 
}
459
 
 
460
 
 
461
 
static const char *
462
 
parse_bor (IfParser *g, const char *cp, long *valp)
463
 
{
464
 
    long rightval;
465
 
 
466
 
    DO (cp = parse_bxor (g, cp, valp));
467
 
    SKIPSPACE (cp);
468
 
 
469
 
    switch (*cp) {
470
 
      case '|':
471
 
        if (cp[1] != '|') {
472
 
            DO (cp = parse_bor (g, cp + 1, &rightval));
473
 
            *valp = (*valp | rightval);
474
 
        }
475
 
        break;
476
 
    }
477
 
    return cp;
478
 
}
479
 
 
480
 
 
481
 
static const char *
482
 
parse_land (IfParser *g, const char *cp, long *valp)
483
 
{
484
 
    long rightval;
485
 
 
486
 
    DO (cp = parse_bor (g, cp, valp));
487
 
    SKIPSPACE (cp);
488
 
 
489
 
    switch (*cp) {
490
 
      case '&':
491
 
        if (cp[1] != '&')
492
 
            return CALLFUNC(g, handle_error) (g, cp, "&&");
493
 
        DO (cp = parse_land (g, cp + 2, &rightval));
494
 
        *valp = (*valp && rightval);
495
 
        break;
496
 
    }
497
 
    return cp;
498
 
}
499
 
 
500
 
 
501
 
static const char *
502
 
parse_lor (IfParser *g, const char *cp, long *valp)
503
 
{
504
 
    long rightval;
505
 
 
506
 
    DO (cp = parse_land (g, cp, valp));
507
 
    SKIPSPACE (cp);
508
 
 
509
 
    switch (*cp) {
510
 
      case '|':
511
 
        if (cp[1] != '|')
512
 
            return CALLFUNC(g, handle_error) (g, cp, "||");
513
 
        DO (cp = parse_lor (g, cp + 2, &rightval));
514
 
        *valp = (*valp || rightval);
515
 
        break;
516
 
    }
517
 
    return cp;
518
 
}
519
 
 
520
 
 
521
 
static const char *
522
 
parse_cond(IfParser *g, const char *cp, long *valp)
523
 
{
524
 
    long trueval, falseval;
525
 
 
526
 
    DO (cp = parse_lor (g, cp, valp));
527
 
    SKIPSPACE (cp);
528
 
 
529
 
    switch (*cp) {
530
 
      case '?':
531
 
        DO (cp = parse_cond (g, cp + 1, &trueval));
532
 
        SKIPSPACE (cp);
533
 
        if (*cp != ':')
534
 
            return CALLFUNC(g, handle_error) (g, cp, ":");
535
 
        DO (cp = parse_cond (g, cp + 1, &falseval));
536
 
        *valp = (*valp ? trueval : falseval);
537
 
        break;
538
 
    }
539
 
    return cp;
540
 
}
541
 
 
542
 
 
543
 
/****************************************************************************
544
 
                             External Entry Points
545
 
 ****************************************************************************/
546
 
 
547
 
const char *
548
 
ParseIfExpression (IfParser *g, const char *cp, long *valp)
549
 
{
550
 
    return parse_cond (g, cp, valp);
551
 
}