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