eval.c (de9b3b9034ee0d39f3bff03b8368361d80cf728f) | eval.c (e3d8671772982f3135d8d6997f3cd698cca4df19) |
---|---|
1/* $OpenBSD: eval.c,v 1.43 2002/02/16 21:27:48 millert Exp $ */ 2/* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */ 3 |
|
1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ozan Yigit at York University. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 22 unchanged lines hidden (view full) --- 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38#if 0 | 4/* 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Ozan Yigit at York University. 10 * 11 * Redistribution and use in source and binary forms, with or without --- 22 unchanged lines hidden (view full) --- 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 39 40#ifndef lint 41#if 0 |
39static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 6/6/93"; | 42static char sccsid[] = "@(#)eval.c 8.2 (Berkeley) 4/27/95"; 43#else 44static char rcsid[] = "$OpenBSD: eval.c,v 1.43 2002/02/16 21:27:48 millert Exp $"; |
40#endif | 45#endif |
41static const char rcsid[] = 42 "$FreeBSD$"; | |
43#endif /* not lint */ 44 45/* 46 * eval.c 47 * Facility: m4 macro processor 48 * by: oz 49 */ 50 51#include <sys/types.h> | 46#endif /* not lint */ 47 48/* 49 * eval.c 50 * Facility: m4 macro processor 51 * by: oz 52 */ 53 54#include <sys/types.h> |
52#include <err.h> | 55#include <errno.h> 56#include <unistd.h> |
53#include <stdio.h> 54#include <stdlib.h> | 57#include <stdio.h> 58#include <stdlib.h> |
59#include <stddef.h> |
|
55#include <string.h> | 60#include <string.h> |
56#include <unistd.h> | 61#include <fcntl.h> 62#include <err.h> |
57#include "mdef.h" 58#include "stdd.h" 59#include "extern.h" 60#include "pathnames.h" 61 | 63#include "mdef.h" 64#include "stdd.h" 65#include "extern.h" 66#include "pathnames.h" 67 |
68#define BUILTIN_MARKER "__builtin_" 69 70static void dodefn(const char *); 71static void dopushdef(const char *, const char *); 72static void dodump(const char *[], int); 73static void dotrace(const char *[], int, int); 74static void doifelse(const char *[], int); 75static int doincl(const char *); 76static int dopaste(const char *); 77static void gnu_dochq(const char *[], int); 78static void dochq(const char *[], int); 79static void gnu_dochc(const char *[], int); 80static void dochc(const char *[], int); 81static void dodiv(int); 82static void doundiv(const char *[], int); 83static void dosub(const char *[], int); 84static void map(char *, const char *, const char *, const char *); 85static const char *handledash(char *, char *, const char *); 86static void expand_builtin(const char *[], int, int); 87static void expand_macro(const char *[], int); 88static void dump_one_def(ndptr); 89 90unsigned long expansion_id; 91 |
|
62/* | 92/* |
63 * eval - evaluate built-in macros. | 93 * eval - eval all macros and builtins calls |
64 * argc - number of elements in argv. 65 * argv - element vector : 66 * argv[0] = definition of a user 67 * macro or nil if built-in. 68 * argv[1] = name of the macro or 69 * built-in. 70 * argv[2] = parameters to user-defined 71 * . macro or built-in. 72 * . 73 * | 94 * argc - number of elements in argv. 95 * argv - element vector : 96 * argv[0] = definition of a user 97 * macro or nil if built-in. 98 * argv[1] = name of the macro or 99 * built-in. 100 * argv[2] = parameters to user-defined 101 * . macro or built-in. 102 * . 103 * |
74 * Note that the minimum value for argc is 3. A call in the form 75 * of macro-or-builtin() will result in: | 104 * A call in the form of macro-or-builtin() will result in: |
76 * argv[0] = nullstr 77 * argv[1] = macro-or-builtin 78 * argv[2] = nullstr | 105 * argv[0] = nullstr 106 * argv[1] = macro-or-builtin 107 * argv[2] = nullstr |
108 * 109 * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin |
|
79 */ | 110 */ |
80 | |
81void 82eval(argv, argc, td) | 111void 112eval(argv, argc, td) |
83register char *argv[]; 84register int argc; 85register int td; | 113 const char *argv[]; 114 int argc; 115 int td; |
86{ | 116{ |
87 register int c, n; | 117 ssize_t mark = -1; 118 119 expansion_id++; 120 if (td & RECDEF) 121 errx(1, "%s at line %lu: expanding recursive definition for %s", 122 CURRENT_NAME, CURRENT_LINE, argv[1]); 123 if (traced_macros && is_traced(argv[1])) 124 mark = trace(argv, argc, infile+ilevel); 125 if (td == MACRTYPE) 126 expand_macro(argv, argc); 127 else 128 expand_builtin(argv, argc, td); 129 if (mark != -1) 130 finish_trace(mark); 131} 132 133/* 134 * expand_builtin - evaluate built-in macros. 135 */ 136void 137expand_builtin(argv, argc, td) 138 const char *argv[]; 139 int argc; 140 int td; 141{ 142 int c, n; 143 int ac; |
88 static int sysval = 0; | 144 static int sysval = 0; |
89 char *p; | |
90 91#ifdef DEBUG 92 printf("argc = %d\n", argc); 93 for (n = 0; n < argc; n++) 94 printf("argv[%d] = %s\n", n, argv[n]); | 145 146#ifdef DEBUG 147 printf("argc = %d\n", argc); 148 for (n = 0; n < argc; n++) 149 printf("argv[%d] = %s\n", n, argv[n]); |
150 fflush(stdout); |
|
95#endif | 151#endif |
152 |
|
96 /* 97 * if argc == 3 and argv[2] is null, then we 98 * have macro-or-builtin() type call. We adjust 99 * argc to avoid further checking.. 100 */ | 153 /* 154 * if argc == 3 and argv[2] is null, then we 155 * have macro-or-builtin() type call. We adjust 156 * argc to avoid further checking.. 157 */ |
158 ac = argc; 159 |
|
101 if (argc == 3 && !*(argv[2])) 102 argc--; 103 | 160 if (argc == 3 && !*(argv[2])) 161 argc--; 162 |
104 switch (td & ~STATIC) { | 163 switch (td & TYPEMASK) { |
105 106 case DEFITYPE: 107 if (argc > 2) 108 dodefine(argv[2], (argc > 3) ? argv[3] : null); 109 break; 110 111 case PUSDTYPE: 112 if (argc > 2) 113 dopushdef(argv[2], (argc > 3) ? argv[3] : null); 114 break; 115 116 case DUMPTYPE: 117 dodump(argv, argc); 118 break; 119 | 164 165 case DEFITYPE: 166 if (argc > 2) 167 dodefine(argv[2], (argc > 3) ? argv[3] : null); 168 break; 169 170 case PUSDTYPE: 171 if (argc > 2) 172 dopushdef(argv[2], (argc > 3) ? argv[3] : null); 173 break; 174 175 case DUMPTYPE: 176 dodump(argv, argc); 177 break; 178 |
179 case TRACEONTYPE: 180 dotrace(argv, argc, 1); 181 break; 182 183 case TRACEOFFTYPE: 184 dotrace(argv, argc, 0); 185 break; 186 |
|
120 case EXPRTYPE: 121 /* 122 * doexpr - evaluate arithmetic 123 * expression 124 */ 125 if (argc > 2) 126 pbnum(expr(argv[2])); 127 break; --- 42 unchanged lines hidden (view full) --- 170 if (argc > 2) 171 pbnum(atoi(argv[2]) - 1); 172 break; 173 174 case SYSCTYPE: 175 /* 176 * dosys - execute system command 177 */ | 187 case EXPRTYPE: 188 /* 189 * doexpr - evaluate arithmetic 190 * expression 191 */ 192 if (argc > 2) 193 pbnum(expr(argv[2])); 194 break; --- 42 unchanged lines hidden (view full) --- 237 if (argc > 2) 238 pbnum(atoi(argv[2]) - 1); 239 break; 240 241 case SYSCTYPE: 242 /* 243 * dosys - execute system command 244 */ |
178 /* Make sure m4 output is NOT interrupted */ 179 fflush(stdout); 180 fflush(stderr); | |
181 if (argc > 2) 182 sysval = system(argv[2]); 183 break; 184 185 case SYSVTYPE: 186 /* 187 * dosysval - return value of the last 188 * system call. | 245 if (argc > 2) 246 sysval = system(argv[2]); 247 break; 248 249 case SYSVTYPE: 250 /* 251 * dosysval - return value of the last 252 * system call. |
189 * | 253 * |
190 */ 191 pbnum(sysval); 192 break; 193 | 254 */ 255 pbnum(sysval); 256 break; 257 |
258 case ESYSCMDTYPE: 259 if (argc > 2) 260 doesyscmd(argv[2]); 261 break; |
|
194 case INCLTYPE: 195 if (argc > 2) 196 if (!doincl(argv[2])) | 262 case INCLTYPE: 263 if (argc > 2) 264 if (!doincl(argv[2])) |
197 err(1, "%s", argv[2]); | 265 err(1, "%s at line %lu: include(%s)", 266 CURRENT_NAME, CURRENT_LINE, argv[2]); |
198 break; 199 200 case SINCTYPE: 201 if (argc > 2) 202 (void) doincl(argv[2]); 203 break; 204#ifdef EXTENDED 205 case PASTTYPE: 206 if (argc > 2) 207 if (!dopaste(argv[2])) | 267 break; 268 269 case SINCTYPE: 270 if (argc > 2) 271 (void) doincl(argv[2]); 272 break; 273#ifdef EXTENDED 274 case PASTTYPE: 275 if (argc > 2) 276 if (!dopaste(argv[2])) |
208 err(1, "%s", argv[2]); | 277 err(1, "%s at line %lu: paste(%s)", 278 CURRENT_NAME, CURRENT_LINE, argv[2]); |
209 break; 210 211 case SPASTYPE: 212 if (argc > 2) 213 (void) dopaste(argv[2]); 214 break; 215#endif 216 case CHNQTYPE: | 279 break; 280 281 case SPASTYPE: 282 if (argc > 2) 283 (void) dopaste(argv[2]); 284 break; 285#endif 286 case CHNQTYPE: |
217 dochq(argv, argc); | 287 if (mimic_gnu) 288 gnu_dochq(argv, ac); 289 else 290 dochq(argv, argc); |
218 break; 219 220 case CHNCTYPE: | 291 break; 292 293 case CHNCTYPE: |
221 dochc(argv, argc); | 294 if (mimic_gnu) 295 gnu_dochc(argv, ac); 296 else 297 dochc(argv, argc); |
222 break; 223 224 case SUBSTYPE: 225 /* 226 * dosub - select substring | 298 break; 299 300 case SUBSTYPE: 301 /* 302 * dosub - select substring |
227 * | 303 * |
228 */ 229 if (argc > 3) 230 dosub(argv, argc); 231 break; 232 233 case SHIFTYPE: 234 /* 235 * doshift - push back all arguments 236 * except the first one (i.e. skip 237 * argv[2]) 238 */ 239 if (argc > 3) { 240 for (n = argc - 1; n > 3; n--) { | 304 */ 305 if (argc > 3) 306 dosub(argv, argc); 307 break; 308 309 case SHIFTYPE: 310 /* 311 * doshift - push back all arguments 312 * except the first one (i.e. skip 313 * argv[2]) 314 */ 315 if (argc > 3) { 316 for (n = argc - 1; n > 3; n--) { |
241 putback(rquote); | 317 pbstr(rquote); |
242 pbstr(argv[n]); | 318 pbstr(argv[n]); |
243 putback(lquote); 244 putback(','); | 319 pbstr(lquote); 320 putback(COMMA); |
245 } | 321 } |
246 putback(rquote); | 322 pbstr(rquote); |
247 pbstr(argv[3]); | 323 pbstr(argv[3]); |
248 putback(lquote); | 324 pbstr(lquote); |
249 } 250 break; 251 252 case DIVRTYPE: 253 if (argc > 2 && (n = atoi(argv[2])) != 0) 254 dodiv(n); 255 else { 256 active = stdout; --- 33 unchanged lines hidden (view full) --- 290 for (n = 2; n < argc; n++) 291 remhash(argv[n], TOP); 292 break; 293 294 case MKTMTYPE: 295 /* 296 * dotemp - create a temporary file 297 */ | 325 } 326 break; 327 328 case DIVRTYPE: 329 if (argc > 2 && (n = atoi(argv[2])) != 0) 330 dodiv(n); 331 else { 332 active = stdout; --- 33 unchanged lines hidden (view full) --- 366 for (n = 2; n < argc; n++) 367 remhash(argv[n], TOP); 368 break; 369 370 case MKTMTYPE: 371 /* 372 * dotemp - create a temporary file 373 */ |
298 if (argc > 2) 299 pbstr(mktemp(argv[2])); | 374 if (argc > 2) { 375 int fd; 376 char *temp; 377 378 temp = xstrdup(argv[2]); 379 380 fd = mkstemp(temp); 381 if (fd == -1) 382 err(1, 383 "%s at line %lu: couldn't make temp file %s", 384 CURRENT_NAME, CURRENT_LINE, argv[2]); 385 close(fd); 386 pbstr(temp); 387 free(temp); 388 } |
300 break; 301 302 case TRNLTYPE: 303 /* 304 * dotranslit - replace all characters in 305 * the source string that appears in the 306 * "from" string with the corresponding 307 * characters in the "to" string. 308 */ 309 if (argc > 3) { | 389 break; 390 391 case TRNLTYPE: 392 /* 393 * dotranslit - replace all characters in 394 * the source string that appears in the 395 * "from" string with the corresponding 396 * characters in the "to" string. 397 */ 398 if (argc > 3) { |
310 char temp[STRSPMAX+1]; | 399 char *temp; 400 401 temp = xalloc(strlen(argv[2])+1); |
311 if (argc > 4) 312 map(temp, argv[2], argv[3], argv[4]); 313 else 314 map(temp, argv[2], argv[3], null); 315 pbstr(temp); | 402 if (argc > 4) 403 map(temp, argv[2], argv[3], argv[4]); 404 else 405 map(temp, argv[2], argv[3], null); 406 pbstr(temp); |
316 } 317 else if (argc > 2) | 407 free(temp); 408 } else if (argc > 2) |
318 pbstr(argv[2]); 319 break; 320 321 case INDXTYPE: 322 /* 323 * doindex - find the index of the second 324 * argument string in the first argument 325 * string. -1 if not present. --- 22 unchanged lines hidden (view full) --- 348 ; 349 break; 350 351 case M4WRTYPE: 352 /* 353 * dom4wrap - set up for 354 * wrap-up/wind-down activity 355 */ | 409 pbstr(argv[2]); 410 break; 411 412 case INDXTYPE: 413 /* 414 * doindex - find the index of the second 415 * argument string in the first argument 416 * string. -1 if not present. --- 22 unchanged lines hidden (view full) --- 439 ; 440 break; 441 442 case M4WRTYPE: 443 /* 444 * dom4wrap - set up for 445 * wrap-up/wind-down activity 446 */ |
356 if ((p = strdup(argv[2])) == NULL) 357 err(1, "strdup"); 358 m4wraps = (argc > 2) ? p : null; | 447 m4wraps = (argc > 2) ? xstrdup(argv[2]) : null; |
359 break; 360 361 case EXITTYPE: 362 /* 363 * doexit - immediate exit from m4. 364 */ 365 killdiv(); 366 exit((argc > 2) ? atoi(argv[2]) : 0); 367 break; 368 369 case DEFNTYPE: 370 if (argc > 2) 371 for (n = 2; n < argc; n++) 372 dodefn(argv[n]); 373 break; 374 | 448 break; 449 450 case EXITTYPE: 451 /* 452 * doexit - immediate exit from m4. 453 */ 454 killdiv(); 455 exit((argc > 2) ? atoi(argv[2]) : 0); 456 break; 457 458 case DEFNTYPE: 459 if (argc > 2) 460 for (n = 2; n < argc; n++) 461 dodefn(argv[n]); 462 break; 463 |
375 case MACRTYPE: 376 pbstr(""); | 464 case INDIRTYPE: /* Indirect call */ 465 if (argc > 2) 466 doindir(argv, argc); |
377 break; | 467 break; |
468 469 case BUILTINTYPE: /* Builtins only */ 470 if (argc > 2) 471 dobuiltin(argv, argc); 472 break; |
|
378 | 473 |
474 case PATSTYPE: 475 if (argc > 2) 476 dopatsubst(argv, argc); 477 break; 478 case REGEXPTYPE: 479 if (argc > 2) 480 doregexp(argv, argc); 481 break; 482 case LINETYPE: 483 doprintlineno(infile+ilevel); 484 break; 485 case FILENAMETYPE: 486 doprintfilename(infile+ilevel); 487 break; 488 case SELFTYPE: 489 pbstr(rquote); 490 pbstr(argv[1]); 491 pbstr(lquote); 492 break; |
|
379 default: | 493 default: |
380 errx(1, "eval: major botch"); | 494 errx(1, "%s at line %lu: eval: major botch.", 495 CURRENT_NAME, CURRENT_LINE); |
381 break; 382 } 383} 384 | 496 break; 497 } 498} 499 |
385const char dumpfmt[] = "`%s'\t`%s'\n"; /* format string for dumpdef */ 386 | |
387/* | 500/* |
388 * expand - user-defined macro expansion | 501 * expand_macro - user-defined macro expansion |
389 */ 390void | 502 */ 503void |
391expand(argv, argc) 392register char *argv[]; 393register int argc; | 504expand_macro(argv, argc) 505 const char *argv[]; 506 int argc; |
394{ | 507{ |
395 register unsigned char *t; 396 register unsigned char *p; 397 register int n; 398 register int argno; | 508 const char *t; 509 const char *p; 510 int n; 511 int argno; |
399 400 t = argv[0]; /* defn string as a whole */ 401 p = t; 402 while (*p) 403 p++; 404 p--; /* last character of defn */ 405 while (p > t) { 406 if (*(p - 1) != ARGFLAG) | 512 513 t = argv[0]; /* defn string as a whole */ 514 p = t; 515 while (*p) 516 p++; 517 p--; /* last character of defn */ 518 while (p > t) { 519 if (*(p - 1) != ARGFLAG) |
407 putback(*p); | 520 PUTBACK(*p); |
408 else { 409 switch (*p) { 410 411 case '#': 412 pbnum(argc - 2); 413 break; 414 case '0': 415 case '1': --- 4 unchanged lines hidden (view full) --- 420 case '6': 421 case '7': 422 case '8': 423 case '9': 424 if ((argno = *p - '0') < argc - 1) 425 pbstr(argv[argno + 1]); 426 break; 427 case '*': | 521 else { 522 switch (*p) { 523 524 case '#': 525 pbnum(argc - 2); 526 break; 527 case '0': 528 case '1': --- 4 unchanged lines hidden (view full) --- 533 case '6': 534 case '7': 535 case '8': 536 case '9': 537 if ((argno = *p - '0') < argc - 1) 538 pbstr(argv[argno + 1]); 539 break; 540 case '*': |
428 for (n = argc - 1; n > 2; n--) { 429 pbstr(argv[n]); 430 putback(','); 431 } 432 pbstr(argv[2]); | 541 if (argc > 2) { 542 for (n = argc - 1; n > 2; n--) { 543 pbstr(argv[n]); 544 putback(COMMA); 545 } 546 pbstr(argv[2]); 547 } |
433 break; | 548 break; |
434 case '@': 435 for( n = argc - 1; n >= 2; n-- ) 436 { 437 putback(rquote); 438 pbstr(argv[n]); 439 putback(lquote); 440 if( n > 2 ) 441 putback(','); | 549 case '@': 550 if (argc > 2) { 551 for (n = argc - 1; n > 2; n--) { 552 pbstr(rquote); 553 pbstr(argv[n]); 554 pbstr(lquote); 555 putback(COMMA); 556 } 557 pbstr(rquote); 558 pbstr(argv[2]); 559 pbstr(lquote); |
442 } | 560 } |
443 break; | 561 break; |
444 default: | 562 default: |
445 putback(*p); 446 putback('$'); | 563 PUTBACK(*p); 564 PUTBACK('$'); |
447 break; 448 } 449 p--; 450 } 451 p--; 452 } 453 if (p == t) /* do last character */ | 565 break; 566 } 567 p--; 568 } 569 p--; 570 } 571 if (p == t) /* do last character */ |
454 putback(*p); | 572 PUTBACK(*p); |
455} 456 457/* 458 * dodefine - install definition in the table 459 */ 460void 461dodefine(name, defn) | 573} 574 575/* 576 * dodefine - install definition in the table 577 */ 578void 579dodefine(name, defn) |
462register char *name; 463register char *defn; | 580 const char *name; 581 const char *defn; |
464{ | 582{ |
465 register ndptr p; | 583 ndptr p; 584 int n; |
466 467 if (!*name) | 585 586 if (!*name) |
468 errx(1, "null definition"); 469 if (STREQ(name, defn)) 470 errx(1, "%s: recursive definition", name); | 587 errx(1, "%s at line %lu: null definition.", CURRENT_NAME, 588 CURRENT_LINE); |
471 if ((p = lookup(name)) == nil) 472 p = addent(name); 473 else if (p->defn != null) 474 free((char *) p->defn); | 589 if ((p = lookup(name)) == nil) 590 p = addent(name); 591 else if (p->defn != null) 592 free((char *) p->defn); |
593 if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0) { 594 n = builtin_type(defn+sizeof(BUILTIN_MARKER)-1); 595 if (n != -1) { 596 p->type = n & TYPEMASK; 597 if ((n & NOARGS) == 0) 598 p->type |= NEEDARGS; 599 p->defn = null; 600 return; 601 } 602 } |
|
475 if (!*defn) 476 p->defn = null; 477 else | 603 if (!*defn) 604 p->defn = null; 605 else |
478 if ((p->defn = strdup(defn)) == NULL) 479 err(1, "strdup"); | 606 p->defn = xstrdup(defn); |
480 p->type = MACRTYPE; | 607 p->type = MACRTYPE; |
608 if (STREQ(name, defn)) 609 p->type |= RECDEF; |
|
481} 482 483/* 484 * dodefn - push back a quoted definition of 485 * the given name. 486 */ | 610} 611 612/* 613 * dodefn - push back a quoted definition of 614 * the given name. 615 */ |
487void | 616static void |
488dodefn(name) | 617dodefn(name) |
489char *name; | 618 const char *name; |
490{ | 619{ |
491 register ndptr p; | 620 ndptr p; 621 char *real; |
492 | 622 |
493 if ((p = lookup(name)) != nil && p->defn != null) { 494 putback(rquote); 495 pbstr(p->defn); 496 putback(lquote); | 623 if ((p = lookup(name)) != nil) { 624 if (p->defn != null) { 625 pbstr(rquote); 626 pbstr(p->defn); 627 pbstr(lquote); 628 } else if ((real = builtin_realname(p->type)) != NULL) { 629 pbstr(real); 630 pbstr(BUILTIN_MARKER); 631 } |
497 } 498} 499 500/* 501 * dopushdef - install a definition in the hash table 502 * without removing a previous definition. Since 503 * each new entry is entered in *front* of the 504 * hash bucket, it hides a previous definition from 505 * lookup. 506 */ | 632 } 633} 634 635/* 636 * dopushdef - install a definition in the hash table 637 * without removing a previous definition. Since 638 * each new entry is entered in *front* of the 639 * hash bucket, it hides a previous definition from 640 * lookup. 641 */ |
507void | 642static void |
508dopushdef(name, defn) | 643dopushdef(name, defn) |
509register char *name; 510register char *defn; | 644 const char *name; 645 const char *defn; |
511{ | 646{ |
512 register ndptr p; | 647 ndptr p; |
513 514 if (!*name) | 648 649 if (!*name) |
515 errx(1, "null definition"); 516 if (STREQ(name, defn)) 517 errx(1, "%s: recursive definition", name); | 650 errx(1, "%s at line %lu: null definition", CURRENT_NAME, 651 CURRENT_LINE); |
518 p = addent(name); 519 if (!*defn) 520 p->defn = null; 521 else | 652 p = addent(name); 653 if (!*defn) 654 p->defn = null; 655 else |
522 if ((p->defn = strdup(defn)) == NULL) 523 err(1, "strdup"); | 656 p->defn = xstrdup(defn); |
524 p->type = MACRTYPE; | 657 p->type = MACRTYPE; |
658 if (STREQ(name, defn)) 659 p->type |= RECDEF; |
|
525} 526 527/* | 660} 661 662/* |
663 * dump_one_def - dump the specified definition. 664 */ 665static void 666dump_one_def(p) 667 ndptr p; 668{ 669 char *real; 670 671 if (mimic_gnu) { 672 if ((p->type & TYPEMASK) == MACRTYPE) 673 fprintf(traceout, "%s:\t%s\n", p->name, p->defn); 674 else { 675 real = builtin_realname(p->type); 676 if (real == NULL) 677 real = null; 678 fprintf(traceout, "%s:\t<%s>\n", p->name, real); 679 } 680 } else 681 fprintf(traceout, "`%s'\t`%s'\n", p->name, p->defn); 682} 683 684/* |
|
528 * dodumpdef - dump the specified definitions in the hash 529 * table to stderr. If nothing is specified, the entire 530 * hash table is dumped. 531 */ | 685 * dodumpdef - dump the specified definitions in the hash 686 * table to stderr. If nothing is specified, the entire 687 * hash table is dumped. 688 */ |
532void | 689static void |
533dodump(argv, argc) | 690dodump(argv, argc) |
534register char *argv[]; 535register int argc; | 691 const char *argv[]; 692 int argc; |
536{ | 693{ |
537 register int n; | 694 int n; |
538 ndptr p; 539 540 if (argc > 2) { 541 for (n = 2; n < argc; n++) 542 if ((p = lookup(argv[n])) != nil) | 695 ndptr p; 696 697 if (argc > 2) { 698 for (n = 2; n < argc; n++) 699 if ((p = lookup(argv[n])) != nil) |
543 fprintf(stderr, dumpfmt, p->name, 544 p->defn); 545 } 546 else { | 700 dump_one_def(p); 701 } else { |
547 for (n = 0; n < HASHSIZE; n++) 548 for (p = hashtab[n]; p != nil; p = p->nxtptr) | 702 for (n = 0; n < HASHSIZE; n++) 703 for (p = hashtab[n]; p != nil; p = p->nxtptr) |
549 fprintf(stderr, dumpfmt, p->name, 550 p->defn); | 704 dump_one_def(p); |
551 } 552} 553 554/* | 705 } 706} 707 708/* |
709 * dotrace - mark some macros as traced/untraced depending upon on. 710 */ 711static void 712dotrace(argv, argc, on) 713 const char *argv[]; 714 int argc; 715 int on; 716{ 717 int n; 718 719 if (argc > 2) { 720 for (n = 2; n < argc; n++) 721 mark_traced(argv[n], on); 722 } else 723 mark_traced(NULL, on); 724} 725 726/* |
|
555 * doifelse - select one of two alternatives - loop. 556 */ | 727 * doifelse - select one of two alternatives - loop. 728 */ |
557void | 729static void |
558doifelse(argv, argc) | 730doifelse(argv, argc) |
559register char *argv[]; 560register int argc; | 731 const char *argv[]; 732 int argc; |
561{ 562 cycle { 563 if (STREQ(argv[2], argv[3])) 564 pbstr(argv[4]); 565 else if (argc == 6) 566 pbstr(argv[5]); 567 else if (argc > 6) { 568 argv += 3; 569 argc -= 3; 570 continue; 571 } 572 break; 573 } 574} 575 576/* 577 * doinclude - include a given file. 578 */ | 733{ 734 cycle { 735 if (STREQ(argv[2], argv[3])) 736 pbstr(argv[4]); 737 else if (argc == 6) 738 pbstr(argv[5]); 739 else if (argc > 6) { 740 argv += 3; 741 argc -= 3; 742 continue; 743 } 744 break; 745 } 746} 747 748/* 749 * doinclude - include a given file. 750 */ |
579int | 751static int |
580doincl(ifile) | 752doincl(ifile) |
581char *ifile; | 753 const char *ifile; |
582{ 583 if (ilevel + 1 == MAXINP) | 754{ 755 if (ilevel + 1 == MAXINP) |
584 errx(1, "too many include files"); 585 if ((infile[ilevel + 1] = fopen(ifile, "r")) != NULL) { | 756 errx(1, "%s at line %lu: too many include files.", 757 CURRENT_NAME, CURRENT_LINE); 758 if (fopen_trypath(infile+ilevel+1, ifile) != NULL) { |
586 ilevel++; 587 bbase[ilevel] = bufbase = bp; 588 return (1); | 759 ilevel++; 760 bbase[ilevel] = bufbase = bp; 761 return (1); |
589 } 590 else | 762 } else |
591 return (0); 592} 593 594#ifdef EXTENDED 595/* 596 * dopaste - include a given file without any 597 * macro processing. 598 */ | 763 return (0); 764} 765 766#ifdef EXTENDED 767/* 768 * dopaste - include a given file without any 769 * macro processing. 770 */ |
599int | 771static int |
600dopaste(pfile) | 772dopaste(pfile) |
601char *pfile; | 773 const char *pfile; |
602{ 603 FILE *pf; | 774{ 775 FILE *pf; |
604 register int c; | 776 int c; |
605 606 if ((pf = fopen(pfile, "r")) != NULL) { 607 while ((c = getc(pf)) != EOF) 608 putc(c, active); 609 (void) fclose(pf); 610 return (1); | 777 778 if ((pf = fopen(pfile, "r")) != NULL) { 779 while ((c = getc(pf)) != EOF) 780 putc(c, active); 781 (void) fclose(pf); 782 return (1); |
611 } 612 else | 783 } else |
613 return (0); 614} 615#endif 616 | 784 return (0); 785} 786#endif 787 |
788static void 789gnu_dochq(argv, ac) 790 const char *argv[]; 791 int ac; 792{ 793 /* In gnu-m4 mode, the only way to restore quotes is to have no 794 * arguments at all. */ 795 if (ac == 2) { 796 lquote[0] = LQUOTE, lquote[1] = EOS; 797 rquote[0] = RQUOTE, rquote[1] = EOS; 798 } else { 799 strlcpy(lquote, argv[2], sizeof(lquote)); 800 if(ac > 3) 801 strlcpy(rquote, argv[3], sizeof(rquote)); 802 else 803 rquote[0] = EOS; 804 } 805} 806 |
|
617/* 618 * dochq - change quote characters 619 */ | 807/* 808 * dochq - change quote characters 809 */ |
620void | 810static void |
621dochq(argv, argc) | 811dochq(argv, argc) |
622register char *argv[]; 623register int argc; | 812 const char *argv[]; 813 int argc; |
624{ 625 if (argc > 2) { 626 if (*argv[2]) | 814{ 815 if (argc > 2) { 816 if (*argv[2]) |
627 lquote = *argv[2]; 628 else 629 lquote = LQUOTE; | 817 strlcpy(lquote, argv[2], sizeof(lquote)); 818 else { 819 lquote[0] = LQUOTE; 820 lquote[1] = EOS; 821 } |
630 if (argc > 3) { 631 if (*argv[3]) | 822 if (argc > 3) { 823 if (*argv[3]) |
632 rquote = *argv[3]; 633 else 634 rquote = RQUOTE; 635 } 636 else 637 rquote = lquote; | 824 strlcpy(rquote, argv[3], sizeof(rquote)); 825 } else 826 strcpy(rquote, lquote); 827 } else { 828 lquote[0] = LQUOTE, lquote[1] = EOS; 829 rquote[0] = RQUOTE, rquote[1] = EOS; |
638 } | 830 } |
639 else { 640 lquote = LQUOTE; 641 rquote = RQUOTE; 642 } | |
643} 644 | 831} 832 |
833static void 834gnu_dochc(argv, ac) 835 const char *argv[]; 836 int ac; 837{ 838 /* In gnu-m4 mode, no arguments mean no comment 839 * arguments at all. */ 840 if (ac == 2) { 841 scommt[0] = EOS; 842 ecommt[0] = EOS; 843 } else { 844 if (*argv[2]) 845 strlcpy(scommt, argv[2], sizeof(scommt)); 846 else 847 scommt[0] = SCOMMT, scommt[1] = EOS; 848 if(ac > 3 && *argv[3]) 849 strlcpy(ecommt, argv[3], sizeof(ecommt)); 850 else 851 ecommt[0] = ECOMMT, ecommt[1] = EOS; 852 } 853} |
|
645/* 646 * dochc - change comment characters 647 */ | 854/* 855 * dochc - change comment characters 856 */ |
648void | 857static void |
649dochc(argv, argc) | 858dochc(argv, argc) |
650register char *argv[]; 651register int argc; | 859 const char *argv[]; 860 int argc; |
652{ 653 if (argc > 2) { 654 if (*argv[2]) | 861{ 862 if (argc > 2) { 863 if (*argv[2]) |
655 scommt = *argv[2]; | 864 strlcpy(scommt, argv[2], sizeof(scommt)); |
656 if (argc > 3) { 657 if (*argv[3]) | 865 if (argc > 3) { 866 if (*argv[3]) |
658 ecommt = *argv[3]; | 867 strlcpy(ecommt, argv[3], sizeof(ecommt)); |
659 } 660 else | 868 } 869 else |
661 ecommt = ECOMMT; | 870 ecommt[0] = ECOMMT, ecommt[1] = EOS; |
662 } 663 else { | 871 } 872 else { |
664 scommt = SCOMMT; 665 ecommt = ECOMMT; | 873 scommt[0] = SCOMMT, scommt[1] = EOS; 874 ecommt[0] = ECOMMT, ecommt[1] = EOS; |
666 } 667} 668 669/* 670 * dodivert - divert the output to a temporary file 671 */ | 875 } 876} 877 878/* 879 * dodivert - divert the output to a temporary file 880 */ |
672void | 881static void |
673dodiv(n) | 882dodiv(n) |
674register int n; | 883 int n; |
675{ | 884{ |
885 int fd; 886 |
|
676 oindex = n; | 887 oindex = n; |
677 if (n < 0 || n >= MAXOUT) | 888 if (n >= maxout) { 889 if (mimic_gnu) 890 resizedivs(n + 10); 891 else 892 n = 0; /* bitbucket */ 893 } 894 895 if (n < 0) |
678 n = 0; /* bitbucket */ 679 if (outfile[n] == NULL) { | 896 n = 0; /* bitbucket */ 897 if (outfile[n] == NULL) { |
680 m4temp[UNIQUE] = n + '0'; 681 if ((outfile[n] = fopen(m4temp, "w")) == NULL) 682 errx(1, "%s: cannot divert", m4temp); | 898 char fname[] = _PATH_DIVNAME; 899 900 if ((fd = mkstemp(fname)) < 0 || 901 (outfile[n] = fdopen(fd, "w+")) == NULL) 902 err(1, "%s: cannot divert", fname); 903 if (unlink(fname) == -1) 904 err(1, "%s: cannot unlink", fname); |
683 } 684 active = outfile[n]; 685} 686 687/* 688 * doundivert - undivert a specified output, or all 689 * other outputs, in numerical order. 690 */ | 905 } 906 active = outfile[n]; 907} 908 909/* 910 * doundivert - undivert a specified output, or all 911 * other outputs, in numerical order. 912 */ |
691void | 913static void |
692doundiv(argv, argc) | 914doundiv(argv, argc) |
693register char *argv[]; 694register int argc; | 915 const char *argv[]; 916 int argc; |
695{ | 917{ |
696 register int ind; 697 register int n; | 918 int ind; 919 int n; |
698 699 if (argc > 2) { 700 for (ind = 2; ind < argc; ind++) { 701 n = atoi(argv[ind]); | 920 921 if (argc > 2) { 922 for (ind = 2; ind < argc; ind++) { 923 n = atoi(argv[ind]); |
702 if (n > 0 && n < MAXOUT && outfile[n] != NULL) | 924 if (n > 0 && n < maxout && outfile[n] != NULL) |
703 getdiv(n); 704 705 } 706 } 707 else | 925 getdiv(n); 926 927 } 928 } 929 else |
708 for (n = 1; n < MAXOUT; n++) | 930 for (n = 1; n < maxout; n++) |
709 if (outfile[n] != NULL) 710 getdiv(n); 711} 712 713/* 714 * dosub - select substring 715 */ | 931 if (outfile[n] != NULL) 932 getdiv(n); 933} 934 935/* 936 * dosub - select substring 937 */ |
716void | 938static void |
717dosub(argv, argc) | 939dosub(argv, argc) |
718register char *argv[]; 719register int argc; | 940 const char *argv[]; 941 int argc; |
720{ | 942{ |
721 register unsigned char *ap, *fc, *k; 722 register int nc; | 943 const char *ap, *fc, *k; 944 int nc; |
723 724 ap = argv[2]; /* target string */ 725#ifdef EXPR 726 fc = ap + expr(argv[3]); /* first char */ 727#else 728 fc = ap + atoi(argv[3]); /* first char */ 729#endif | 945 946 ap = argv[2]; /* target string */ 947#ifdef EXPR 948 fc = ap + expr(argv[3]); /* first char */ 949#else 950 fc = ap + atoi(argv[3]); /* first char */ 951#endif |
730 if (argc < 5) 731 nc = strlen(fc); 732 else | 952 nc = strlen(fc); 953 if (argc >= 5) |
733#ifdef EXPR | 954#ifdef EXPR |
734 nc = expr(argv[4]); | 955 nc = min(nc, expr(argv[4])); |
735#else | 956#else |
736 nc = atoi(argv[4]); | 957 nc = min(nc, atoi(argv[4])); |
737#endif 738 if (fc >= ap && fc < ap + strlen(ap)) 739 for (k = fc + nc - 1; k >= fc; k--) 740 putback(*k); 741} 742 743/* 744 * map: --- 15 unchanged lines hidden (view full) --- 760 * the character value stabilizes (i.e. sch = dch, in other words 761 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary 762 * character, it will stabilize, since mapvec[0] == 0 at all times. At the 763 * end, we restore mapvec* back to normal where mapvec[n] == n for 764 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is 765 * about 5 times faster than any algorithm that makes multiple passes over 766 * destination string. 767 */ | 958#endif 959 if (fc >= ap && fc < ap + strlen(ap)) 960 for (k = fc + nc - 1; k >= fc; k--) 961 putback(*k); 962} 963 964/* 965 * map: --- 15 unchanged lines hidden (view full) --- 981 * the character value stabilizes (i.e. sch = dch, in other words 982 * mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary 983 * character, it will stabilize, since mapvec[0] == 0 at all times. At the 984 * end, we restore mapvec* back to normal where mapvec[n] == n for 985 * 0 <= n <= 127. This strategy, along with the restoration of mapvec, is 986 * about 5 times faster than any algorithm that makes multiple passes over 987 * destination string. 988 */ |
768void | 989static void |
769map(dest, src, from, to) | 990map(dest, src, from, to) |
770register char *dest; 771register char *src; 772register char *from; 773register char *to; | 991 char *dest; 992 const char *src; 993 const char *from; 994 const char *to; |
774{ | 995{ |
775 register char *tmp; 776 register char sch, dch; 777 static char mapvec[128] = { 778 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 779 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 780 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 781 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 782 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 783 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 784 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 785 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 786 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 787 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 788 120, 121, 122, 123, 124, 125, 126, 127 | 996 const char *tmp; 997 unsigned char sch, dch; 998 static char frombis[257]; 999 static char tobis[257]; 1000 static unsigned char mapvec[256] = { 1001 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1002 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 1003 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 1004 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 1005 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 1006 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 1007 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 1008 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 1009 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 1010 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 1011 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 1012 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 1013 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 1014 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 1015 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 1016 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 1017 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 1018 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 |
789 }; 790 791 if (*src) { | 1019 }; 1020 1021 if (*src) { |
1022 if (mimic_gnu) { 1023 /* 1024 * expand character ranges on the fly 1025 */ 1026 from = handledash(frombis, frombis + 256, from); 1027 to = handledash(tobis, tobis + 256, to); 1028 } |
|
792 tmp = from; 793 /* 794 * create a mapping between "from" and 795 * "to" 796 */ 797 while (*from) | 1029 tmp = from; 1030 /* 1031 * create a mapping between "from" and 1032 * "to" 1033 */ 1034 while (*from) |
798 mapvec[*from++] = (*to) ? *to++ : (char) 0; | 1035 mapvec[(unsigned char)(*from++)] = (*to) ? 1036 (unsigned char)(*to++) : 0; |
799 800 while (*src) { | 1037 1038 while (*src) { |
801 sch = *src++; | 1039 sch = (unsigned char)(*src++); |
802 dch = mapvec[sch]; 803 while (dch != sch) { 804 sch = dch; 805 dch = mapvec[sch]; 806 } | 1040 dch = mapvec[sch]; 1041 while (dch != sch) { 1042 sch = dch; 1043 dch = mapvec[sch]; 1044 } |
807 if (*dest = dch) | 1045 if ((*dest = (char)dch)) |
808 dest++; 809 } 810 /* 811 * restore all the changed characters 812 */ 813 while (*tmp) { | 1046 dest++; 1047 } 1048 /* 1049 * restore all the changed characters 1050 */ 1051 while (*tmp) { |
814 mapvec[*tmp] = *tmp; | 1052 mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp); |
815 tmp++; 816 } 817 } | 1053 tmp++; 1054 } 1055 } |
818 *dest = (char) 0; | 1056 *dest = '\0'; |
819} | 1057} |
1058 1059 1060/* 1061 * handledash: 1062 * use buffer to copy the src string, expanding character ranges 1063 * on the way. 1064 */ 1065static const char * 1066handledash(buffer, end, src) 1067 char *buffer; 1068 char *end; 1069 const char *src; 1070{ 1071 char *p; 1072 1073 p = buffer; 1074 while(*src) { 1075 if (src[1] == '-' && src[2]) { 1076 unsigned char i; 1077 for (i = (unsigned char)src[0]; 1078 i <= (unsigned char)src[2]; i++) { 1079 *p++ = i; 1080 if (p == end) { 1081 *p = '\0'; 1082 return buffer; 1083 } 1084 } 1085 src += 3; 1086 } else 1087 *p++ = *src++; 1088 if (p == end) 1089 break; 1090 } 1091 *p = '\0'; 1092 return buffer; 1093} 1094 |
|