File indexing completed on 2018-03-02 18:44:42 UTC
view on githubraw file Latest commit bf5846c3 on 2004-02-25 18:19:54 UTC
bf5846c3a1 Ed H*0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 #include "ifparser.h"
0099 #include <ctype.h>
0100
0101
0102
0103
0104
0105 #define DO(val) if (!(val)) return NULL
0106 #define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff))
0107 #define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++
0108 #define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_')
0109
0110
0111 static const char *
0112 parse_variable (g, cp, varp)
0113 IfParser *g;
0114 const char *cp;
0115 const char **varp;
0116 {
0117 SKIPSPACE (cp);
0118
0119 if (!isvarfirstletter (*cp))
0120 return CALLFUNC(g, handle_error) (g, cp, "variable name");
0121
0122 *varp = cp;
0123
0124 for (cp++; isalnum(*cp) || *cp == '_'; cp++) ;
0125 return cp;
0126 }
0127
0128
0129 static const char *
0130 parse_number (g, cp, valp)
0131 IfParser *g;
0132 const char *cp;
0133 int *valp;
0134 {
0135 SKIPSPACE (cp);
0136
0137 if (!isdigit(*cp))
0138 return CALLFUNC(g, handle_error) (g, cp, "number");
0139
0140 #ifdef WIN32
0141 *valp = strtol(cp, &cp, 0);
0142 #else
0143 *valp = atoi (cp);
0144
0145 for (cp++; isdigit(*cp); cp++) ;
0146 #endif
0147 return cp;
0148 }
0149
0150
0151 static const char *
0152 parse_value (g, cp, valp)
0153 IfParser *g;
0154 const char *cp;
0155 int *valp;
0156 {
0157 const char *var;
0158
0159 *valp = 0;
0160
0161 SKIPSPACE (cp);
0162 if (!*cp)
0163 return cp;
0164
0165 switch (*cp) {
0166 case '(':
0167 DO (cp = ParseIfExpression (g, cp + 1, valp));
0168 SKIPSPACE (cp);
0169 if (*cp != ')')
0170 return CALLFUNC(g, handle_error) (g, cp, ")");
0171
0172 return cp + 1;
0173
0174 case '!':
0175 DO (cp = parse_value (g, cp + 1, valp));
0176 *valp = !(*valp);
0177 return cp;
0178
0179 case '-':
0180 DO (cp = parse_value (g, cp + 1, valp));
0181 *valp = -(*valp);
0182 return cp;
0183
0184 case '#':
0185 DO (cp = parse_variable (g, cp + 1, &var));
0186 SKIPSPACE (cp);
0187 if (*cp != '(')
0188 return CALLFUNC(g, handle_error) (g, cp, "(");
0189 do {
0190 DO (cp = parse_variable (g, cp + 1, &var));
0191 SKIPSPACE (cp);
0192 } while (*cp && *cp != ')');
0193 if (*cp != ')')
0194 return CALLFUNC(g, handle_error) (g, cp, ")");
0195 *valp = 1;
0196 return cp + 1;
0197
0198 case 'd':
0199 if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) {
0200 int paren = 0;
0201 cp += 7;
0202 SKIPSPACE (cp);
0203 if (*cp == '(') {
0204 paren = 1;
0205 cp++;
0206 }
0207 DO (cp = parse_variable (g, cp, &var));
0208 SKIPSPACE (cp);
0209 if (paren && *cp != ')')
0210 return CALLFUNC(g, handle_error) (g, cp, ")");
0211 *valp = (*(g->funcs.eval_defined)) (g, var, cp - var);
0212 return cp + paren;
0213 }
0214
0215 }
0216
0217 if (isdigit(*cp)) {
0218 DO (cp = parse_number (g, cp, valp));
0219 } else if (!isvarfirstletter(*cp))
0220 return CALLFUNC(g, handle_error) (g, cp, "variable or number");
0221 else {
0222 DO (cp = parse_variable (g, cp, &var));
0223 *valp = (*(g->funcs.eval_variable)) (g, var, cp - var);
0224 }
0225
0226 return cp;
0227 }
0228
0229
0230
0231 static const char *
0232 parse_product (g, cp, valp)
0233 IfParser *g;
0234 const char *cp;
0235 int *valp;
0236 {
0237 int rightval;
0238
0239 DO (cp = parse_value (g, cp, valp));
0240 SKIPSPACE (cp);
0241
0242 switch (*cp) {
0243 case '*':
0244 DO (cp = parse_product (g, cp + 1, &rightval));
0245 *valp = (*valp * rightval);
0246 break;
0247
0248 case '/':
0249 DO (cp = parse_product (g, cp + 1, &rightval));
0250 *valp = (*valp / rightval);
0251 break;
0252
0253 case '%':
0254 DO (cp = parse_product (g, cp + 1, &rightval));
0255 *valp = (*valp % rightval);
0256 break;
0257 }
0258 return cp;
0259 }
0260
0261
0262 static const char *
0263 parse_sum (g, cp, valp)
0264 IfParser *g;
0265 const char *cp;
0266 int *valp;
0267 {
0268 int rightval;
0269
0270 DO (cp = parse_product (g, cp, valp));
0271 SKIPSPACE (cp);
0272
0273 switch (*cp) {
0274 case '+':
0275 DO (cp = parse_sum (g, cp + 1, &rightval));
0276 *valp = (*valp + rightval);
0277 break;
0278
0279 case '-':
0280 DO (cp = parse_sum (g, cp + 1, &rightval));
0281 *valp = (*valp - rightval);
0282 break;
0283 }
0284 return cp;
0285 }
0286
0287
0288 static const char *
0289 parse_shift (g, cp, valp)
0290 IfParser *g;
0291 const char *cp;
0292 int *valp;
0293 {
0294 int rightval;
0295
0296 DO (cp = parse_sum (g, cp, valp));
0297 SKIPSPACE (cp);
0298
0299 switch (*cp) {
0300 case '<':
0301 if (cp[1] == '<') {
0302 DO (cp = parse_shift (g, cp + 2, &rightval));
0303 *valp = (*valp << rightval);
0304 }
0305 break;
0306
0307 case '>':
0308 if (cp[1] == '>') {
0309 DO (cp = parse_shift (g, cp + 2, &rightval));
0310 *valp = (*valp >> rightval);
0311 }
0312 break;
0313 }
0314 return cp;
0315 }
0316
0317
0318 static const char *
0319 parse_inequality (g, cp, valp)
0320 IfParser *g;
0321 const char *cp;
0322 int *valp;
0323 {
0324 int rightval;
0325
0326 DO (cp = parse_shift (g, cp, valp));
0327 SKIPSPACE (cp);
0328
0329 switch (*cp) {
0330 case '<':
0331 if (cp[1] == '=') {
0332 DO (cp = parse_inequality (g, cp + 2, &rightval));
0333 *valp = (*valp <= rightval);
0334 } else {
0335 DO (cp = parse_inequality (g, cp + 1, &rightval));
0336 *valp = (*valp < rightval);
0337 }
0338 break;
0339
0340 case '>':
0341 if (cp[1] == '=') {
0342 DO (cp = parse_inequality (g, cp + 2, &rightval));
0343 *valp = (*valp >= rightval);
0344 } else {
0345 DO (cp = parse_inequality (g, cp + 1, &rightval));
0346 *valp = (*valp > rightval);
0347 }
0348 break;
0349 }
0350 return cp;
0351 }
0352
0353
0354 static const char *
0355 parse_equality (g, cp, valp)
0356 IfParser *g;
0357 const char *cp;
0358 int *valp;
0359 {
0360 int rightval;
0361
0362 DO (cp = parse_inequality (g, cp, valp));
0363 SKIPSPACE (cp);
0364
0365 switch (*cp) {
0366 case '=':
0367 if (cp[1] == '=')
0368 cp++;
0369 DO (cp = parse_equality (g, cp + 1, &rightval));
0370 *valp = (*valp == rightval);
0371 break;
0372
0373 case '!':
0374 if (cp[1] != '=')
0375 break;
0376 DO (cp = parse_equality (g, cp + 2, &rightval));
0377 *valp = (*valp != rightval);
0378 break;
0379 }
0380 return cp;
0381 }
0382
0383
0384 static const char *
0385 parse_band (g, cp, valp)
0386 IfParser *g;
0387 const char *cp;
0388 int *valp;
0389 {
0390 int rightval;
0391
0392 DO (cp = parse_equality (g, cp, valp));
0393 SKIPSPACE (cp);
0394
0395 switch (*cp) {
0396 case '&':
0397 if (cp[1] != '&') {
0398 DO (cp = parse_band (g, cp + 1, &rightval));
0399 *valp = (*valp & rightval);
0400 }
0401 break;
0402 }
0403 return cp;
0404 }
0405
0406
0407 static const char *
0408 parse_bor (g, cp, valp)
0409 IfParser *g;
0410 const char *cp;
0411 int *valp;
0412 {
0413 int rightval;
0414
0415 DO (cp = parse_band (g, cp, valp));
0416 SKIPSPACE (cp);
0417
0418 switch (*cp) {
0419 case '|':
0420 if (cp[1] != '|') {
0421 DO (cp = parse_bor (g, cp + 1, &rightval));
0422 *valp = (*valp | rightval);
0423 }
0424 break;
0425 }
0426 return cp;
0427 }
0428
0429
0430 static const char *
0431 parse_land (g, cp, valp)
0432 IfParser *g;
0433 const char *cp;
0434 int *valp;
0435 {
0436 int rightval;
0437
0438 DO (cp = parse_bor (g, cp, valp));
0439 SKIPSPACE (cp);
0440
0441 switch (*cp) {
0442 case '&':
0443 if (cp[1] != '&')
0444 return CALLFUNC(g, handle_error) (g, cp, "&&");
0445 DO (cp = parse_land (g, cp + 2, &rightval));
0446 *valp = (*valp && rightval);
0447 break;
0448 }
0449 return cp;
0450 }
0451
0452
0453 static const char *
0454 parse_lor (g, cp, valp)
0455 IfParser *g;
0456 const char *cp;
0457 int *valp;
0458 {
0459 int rightval;
0460
0461 DO (cp = parse_land (g, cp, valp));
0462 SKIPSPACE (cp);
0463
0464 switch (*cp) {
0465 case '|':
0466 if (cp[1] != '|')
0467 return CALLFUNC(g, handle_error) (g, cp, "||");
0468 DO (cp = parse_lor (g, cp + 2, &rightval));
0469 *valp = (*valp || rightval);
0470 break;
0471 }
0472 return cp;
0473 }
0474
0475
0476
0477
0478
0479
0480 const char *
0481 ParseIfExpression (g, cp, valp)
0482 IfParser *g;
0483 const char *cp;
0484 int *valp;
0485 {
0486 return parse_lor (g, cp, valp);
0487 }
0488
0489