|
|
1.1 ! root 1: 0707070114030104531006660005500000040000010641070426654763700001000000015757COPYING ! 2: GNU CC GENERAL PUBLIC LICENSE ! 3: (Clarified 11 Feb 1988) ! 4: ! 5: Copyright (C) 1988 Richard M. Stallman ! 6: Everyone is permitted to copy and distribute verbatim copies ! 7: of this license, but changing it is not allowed. You can also ! 8: use this wording to make the terms for other programs. ! 9: ! 10: The license agreements of most software companies keep you at the ! 11: mercy of those companies. By contrast, our general public license is ! 12: intended to give everyone the right to share GNU CC. To make sure that ! 13: you get the rights we want you to have, we need to make restrictions ! 14: that forbid anyone to deny you these rights or to ask you to surrender ! 15: the rights. Hence this license agreement. ! 16: ! 17: Specifically, we want to make sure that you have the right to give ! 18: away copies of GNU CC, that you receive source code or else can get it ! 19: if you want it, that you can change GNU CC or use pieces of it in new ! 20: free programs, and that you know you can do these things. ! 21: ! 22: To make sure that everyone has such rights, we have to forbid you to ! 23: deprive anyone else of these rights. For example, if you distribute ! 24: copies of GNU CC, you must give the recipients all the rights that you ! 25: have. You must make sure that they, too, receive or can get the ! 26: source code. And you must tell them their rights. ! 27: ! 28: Also, for our own protection, we must make certain that everyone ! 29: finds out that there is no warranty for GNU CC. If GNU CC is modified by ! 30: someone else and passed on, we want its recipients to know that what ! 31: they have is not what we distributed, so that any problems introduced ! 32: by others will not reflect on our reputation. ! 33: ! 34: Therefore we (Richard Stallman and the Free Software Foundation, ! 35: Inc.) make the following terms which say what you must do to be ! 36: allowed to distribute or change GNU CC. ! 37: ! 38: ! 39: COPYING POLICIES ! 40: ! 41: 1. You may copy and distribute verbatim copies of GNU CC source code ! 42: as you receive it, in any medium, provided that you conspicuously and ! 43: appropriately publish on each copy a valid copyright notice "Copyright ! 44: (C) 1988 Free Software Foundation, Inc." (or with whatever year is ! 45: appropriate); keep intact the notices on all files that refer to this ! 46: License Agreement and to the absence of any warranty; and give any ! 47: other recipients of the GNU CC program a copy of this License ! 48: Agreement along with the program. You may charge a distribution fee ! 49: for the physical act of transferring a copy. ! 50: ! 51: 2. You may modify your copy or copies of GNU CC or any portion of it, ! 52: and copy and distribute such modifications under the terms of ! 53: Paragraph 1 above, provided that you also do the following: ! 54: ! 55: a) cause the modified files to carry prominent notices stating ! 56: that you changed the files and the date of any change; and ! 57: ! 58: b) cause the whole of any work that you distribute or publish, ! 59: that in whole or in part contains or is a derivative of GNU CC or ! 60: any part thereof, to be licensed at no charge to all third ! 61: parties on terms identical to those contained in this License ! 62: Agreement (except that you may choose to grant more extensive ! 63: warranty protection to some or all third parties, at your option). ! 64: ! 65: c) You may charge a distribution fee for the physical act of ! 66: transferring a copy, and you may at your option offer warranty ! 67: protection in exchange for a fee. ! 68: ! 69: Mere aggregation of another unrelated program with this program (or its ! 70: derivative) on a volume of a storage or distribution medium does not bring ! 71: the other program under the scope of these terms. ! 72: ! 73: 3. You may copy and distribute GNU CC (or a portion or derivative of it, ! 74: under Paragraph 2) in object code or executable form under the terms of ! 75: Paragraphs 1 and 2 above provided that you also do one of the following: ! 76: ! 77: a) accompany it with the complete corresponding machine-readable ! 78: source code, which must be distributed under the terms of ! 79: Paragraphs 1 and 2 above; or, ! 80: ! 81: b) accompany it with a written offer, valid for at least three ! 82: years, to give any third party free (except for a nominal ! 83: shipping charge) a complete machine-readable copy of the ! 84: corresponding source code, to be distributed under the terms of ! 85: Paragraphs 1 and 2 above; or, ! 86: ! 87: c) accompany it with the information you received as to where the ! 88: corresponding source code may be obtained. (This alternative is ! 89: allowed only for noncommercial distribution and only if you ! 90: received the program in object code or executable form alone.) ! 91: ! 92: For an executable file, complete source code means all the source code for ! 93: all modules it contains; but, as a special exception, it need not include ! 94: source code for modules which are standard libraries that accompany the ! 95: operating system on which the executable file runs. ! 96: ! 97: 4. You may not copy, sublicense, distribute or transfer GNU CC ! 98: except as expressly provided under this License Agreement. Any attempt ! 99: otherwise to copy, sublicense, distribute or transfer GNU CC is void and ! 100: your rights to use the program under this License agreement shall be ! 101: automatically terminated. However, parties who have received computer ! 102: software programs from you with this License Agreement will not have ! 103: their licenses terminated so long as such parties remain in full compliance. ! 104: ! 105: 5. If you wish to incorporate parts of GNU CC into other free programs ! 106: whose distribution conditions are different, write to the Free Software ! 107: Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet worked ! 108: out a simple rule that can be stated here, but we will often permit this. ! 109: We will be guided by the two goals of preserving the free status of all ! 110: derivatives of our free software and of promoting the sharing and reuse of ! 111: software. ! 112: ! 113: Your comments and suggestions about our licensing policies and our ! 114: software are welcome! Please contact the Free Software Foundation, Inc., ! 115: 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296. ! 116: ! 117: NO WARRANTY ! 118: ! 119: BECAUSE GNU CC IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO ! 120: WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT ! 121: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, ! 122: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GNU CC "AS IS" WITHOUT ! 123: WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT ! 124: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ! 125: A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND ! 126: PERFORMANCE OF GNU CC IS WITH YOU. SHOULD GNU CC PROVE DEFECTIVE, YOU ! 127: ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ! 128: ! 129: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. ! 130: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY ! 131: WHO MAY MODIFY AND REDISTRIBUTE GNU CC AS PERMITTED ABOVE, BE LIABLE TO ! 132: YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER ! 133: SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR ! 134: INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA ! 135: BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A ! 136: FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GNU CC, EVEN ! 137: IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ! 138: ANY CLAIM BY ANY OTHER PARTY. ! 139: 0707070114030170161006660005500000040000010614560426655020300001100000011751alloca.c /* ! 140: alloca -- (mostly) portable public-domain implementation ! 141: ! 142: last edit: 86/01/26 D A Gwyn ! 143: ! 144: This implementation of the PWB library alloca() function, ! 145: which is used to allocate space off the run-time stack so ! 146: that it is automatically reclaimed upon procedure exit, ! 147: was inspired by discussions with J. Q. Johnson of Cornell. ! 148: ! 149: It should work under any C implementation that uses an ! 150: actual procedure stack (as opposed to a linked list of ! 151: frames). There are some preprocessor constants that can ! 152: be defined when compiling for your specific system, for ! 153: improved efficiency; however, the defaults should be okay. ! 154: ! 155: The general concept of this implementation is to keep ! 156: track of all alloca()-allocated blocks, and reclaim any ! 157: that are found to be deeper in the stack than the current ! 158: invocation. This heuristic does not reclaim storage as ! 159: soon as it becomes invalid, but it will do so eventually. ! 160: ! 161: As a special case, alloca(0) reclaims storage without ! 162: allocating any. It is a good idea to use alloca(0) in ! 163: your main control loop, etc. to force garbage collection. ! 164: */ ! 165: #ifndef lint ! 166: static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ ! 167: #endif ! 168: ! 169: #ifdef X3J11 ! 170: typedef void *pointer; /* generic pointer type */ ! 171: #else ! 172: typedef char *pointer; /* generic pointer type */ ! 173: #endif ! 174: ! 175: #define NULL 0 /* null pointer constant */ ! 176: ! 177: extern void free(); ! 178: extern pointer xmalloc(); ! 179: ! 180: /* ! 181: Define STACK_DIRECTION if you know the direction of stack ! 182: growth for your system; otherwise it will be automatically ! 183: deduced at run-time. ! 184: ! 185: STACK_DIRECTION > 0 => grows toward higher addresses ! 186: STACK_DIRECTION < 0 => grows toward lower addresses ! 187: STACK_DIRECTION = 0 => direction of growth unknown ! 188: */ ! 189: ! 190: #ifndef STACK_DIRECTION ! 191: #define STACK_DIRECTION 0 /* direction unknown */ ! 192: #endif ! 193: ! 194: #if STACK_DIRECTION != 0 ! 195: ! 196: #define STACK_DIR STACK_DIRECTION /* known at compile-time */ ! 197: ! 198: #else /* STACK_DIRECTION == 0; need run-time code */ ! 199: ! 200: static int stack_dir; /* 1 or -1 once known */ ! 201: #define STACK_DIR stack_dir ! 202: ! 203: static void ! 204: find_stack_direction (/* void */) ! 205: { ! 206: static char *addr = NULL; /* address of first ! 207: `dummy', once known */ ! 208: auto char dummy; /* to get stack address */ ! 209: ! 210: if (addr == NULL) ! 211: { /* initial entry */ ! 212: addr = &dummy; ! 213: ! 214: find_stack_direction (); /* recurse once */ ! 215: } ! 216: else /* second entry */ ! 217: if (&dummy > addr) ! 218: stack_dir = 1; /* stack grew upward */ ! 219: else ! 220: stack_dir = -1; /* stack grew downward */ ! 221: } ! 222: ! 223: #endif /* STACK_DIRECTION == 0 */ ! 224: ! 225: /* ! 226: An "alloca header" is used to: ! 227: (a) chain together all alloca()ed blocks; ! 228: (b) keep track of stack depth. ! 229: ! 230: It is very important that sizeof(header) agree with malloc() ! 231: alignment chunk size. The following default should work okay. ! 232: */ ! 233: ! 234: #ifndef ALIGN_SIZE ! 235: #define ALIGN_SIZE sizeof(double) ! 236: #endif ! 237: ! 238: typedef union hdr ! 239: { ! 240: char align[ALIGN_SIZE]; /* to force sizeof(header) */ ! 241: struct ! 242: { ! 243: union hdr *next; /* for chaining headers */ ! 244: char *deep; /* for stack depth measure */ ! 245: } h; ! 246: } header; ! 247: ! 248: /* ! 249: alloca( size ) returns a pointer to at least `size' bytes of ! 250: storage which will be automatically reclaimed upon exit from ! 251: the procedure that called alloca(). Originally, this space ! 252: was supposed to be taken from the current stack frame of the ! 253: caller, but that method cannot be made to work for some ! 254: implementations of C, for example under Gould's UTX/32. ! 255: */ ! 256: ! 257: pointer ! 258: alloca (size) /* returns pointer to storage */ ! 259: unsigned size; /* # bytes to allocate */ ! 260: { ! 261: static header *last = NULL; /* -> last alloca header */ ! 262: auto char probe; /* probes stack depth: */ ! 263: register char *depth = &probe; ! 264: ! 265: #if STACK_DIRECTION == 0 ! 266: if (STACK_DIR == 0) /* unknown growth direction */ ! 267: find_stack_direction (); ! 268: #endif ! 269: ! 270: /* Reclaim garbage, defined as all alloca()ed storage that ! 271: was allocated from deeper in the stack than currently. */ ! 272: ! 273: { ! 274: register header *hp; /* traverses linked list */ ! 275: ! 276: for (hp = last; hp != NULL;) ! 277: if (STACK_DIR > 0 && hp->h.deep > depth ! 278: || STACK_DIR < 0 && hp->h.deep < depth) ! 279: { ! 280: register header *np = hp->h.next; ! 281: ! 282: free ((pointer) hp); /* collect garbage */ ! 283: ! 284: hp = np; /* -> next header */ ! 285: } ! 286: else ! 287: break; /* rest are not deeper */ ! 288: ! 289: last = hp; /* -> last valid storage */ ! 290: } ! 291: ! 292: if (size == 0) ! 293: return NULL; /* no allocation required */ ! 294: ! 295: /* Allocate combined header + user data storage. */ ! 296: ! 297: { ! 298: register pointer new = xmalloc (sizeof (header) + size); ! 299: /* address of header */ ! 300: ! 301: ((header *)new)->h.next = last; ! 302: ((header *)new)->h.deep = depth; ! 303: ! 304: last = (header *)new; ! 305: ! 306: /* User storage begins just after header. */ ! 307: ! 308: return (pointer)((char *)new + sizeof(header)); ! 309: } ! 310: } ! 311: ! 312: /* like malloc and realloc but check for no memory left */ ! 313: /* ! 314: pointer ! 315: xmalloc (size) ! 316: int size; ! 317: { ! 318: pointer val = (pointer) malloc (size); ! 319: if (!val) memory_full (); ! 320: return val; ! 321: } ! 322: ! 323: pointer ! 324: xrealloc (block, size) ! 325: long *block; ! 326: int size; ! 327: { ! 328: pointer val = (pointer) realloc (block, size); ! 329: if (!val) memory_full (); ! 330: return val; ! 331: } ! 332: memory_full () ! 333: { ! 334: error ("Memory exhausted"); ! 335: } ! 336: */ ! 337: 0707070114030157531006660005500000040000010274400426654765600000700000035321cexp.y /* Parse C expressions for CCCP. ! 338: Copyright (C) 1987 Free Software Foundation. ! 339: ! 340: NO WARRANTY ! 341: ! 342: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY ! 343: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT ! 344: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, ! 345: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" ! 346: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, ! 347: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ! 348: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY ! 349: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE ! 350: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR ! 351: CORRECTION. ! 352: ! 353: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. ! 354: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY ! 355: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE ! 356: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR ! 357: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE ! 358: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR ! 359: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR ! 360: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS ! 361: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH ! 362: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. ! 363: ! 364: GENERAL PUBLIC LICENSE TO COPY ! 365: ! 366: 1. You may copy and distribute verbatim copies of this source file ! 367: as you receive it, in any medium, provided that you conspicuously and ! 368: appropriately publish on each copy a valid copyright notice "Copyright ! 369: (C) 1987 Free Software Foundation"; and include following the ! 370: copyright notice a verbatim copy of the above disclaimer of warranty ! 371: and of this License. You may charge a distribution fee for the ! 372: physical act of transferring a copy. ! 373: ! 374: 2. You may modify your copy or copies of this source file or ! 375: any portion of it, and copy and distribute such modifications under ! 376: the terms of Paragraph 1 above, provided that you also do the following: ! 377: ! 378: a) cause the modified files to carry prominent notices stating ! 379: that you changed the files and the date of any change; and ! 380: ! 381: b) cause the whole of any work that you distribute or publish, ! 382: that in whole or in part contains or is a derivative of this ! 383: program or any part thereof, to be licensed at no charge to all ! 384: third parties on terms identical to those contained in this ! 385: License Agreement (except that you may choose to grant more extensive ! 386: warranty protection to some or all third parties, at your option). ! 387: ! 388: c) You may charge a distribution fee for the physical act of ! 389: transferring a copy, and you may at your option offer warranty ! 390: protection in exchange for a fee. ! 391: ! 392: Mere aggregation of another unrelated program with this program (or its ! 393: derivative) on a volume of a storage or distribution medium does not bring ! 394: the other program under the scope of these terms. ! 395: ! 396: 3. You may copy and distribute this program (or a portion or derivative ! 397: of it, under Paragraph 2) in object code or executable form under the terms ! 398: of Paragraphs 1 and 2 above provided that you also do one of the following: ! 399: ! 400: a) accompany it with the complete corresponding machine-readable ! 401: source code, which must be distributed under the terms of ! 402: Paragraphs 1 and 2 above; or, ! 403: ! 404: b) accompany it with a written offer, valid for at least three ! 405: years, to give any third party free (except for a nominal ! 406: shipping charge) a complete machine-readable copy of the ! 407: corresponding source code, to be distributed under the terms of ! 408: Paragraphs 1 and 2 above; or, ! 409: ! 410: c) accompany it with the information you received as to where the ! 411: corresponding source code may be obtained. (This alternative is ! 412: allowed only for noncommercial distribution and only if you ! 413: received the program in object code or executable form alone.) ! 414: ! 415: For an executable file, complete source code means all the source code for ! 416: all modules it contains; but, as a special exception, it need not include ! 417: source code for modules which are standard libraries that accompany the ! 418: operating system on which the executable file runs. ! 419: ! 420: 4. You may not copy, sublicense, distribute or transfer this program ! 421: except as expressly provided under this License Agreement. Any attempt ! 422: otherwise to copy, sublicense, distribute or transfer this program is void and ! 423: your rights to use the program under this License agreement shall be ! 424: automatically terminated. However, parties who have received computer ! 425: software programs from you with this License Agreement will not have ! 426: their licenses terminated so long as such parties remain in full compliance. ! 427: ! 428: 5. If you wish to incorporate parts of this program into other free ! 429: programs whose distribution conditions are different, write to the Free ! 430: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet ! 431: worked out a simple rule that can be stated here, but we will often permit ! 432: this. We will be guided by the two goals of preserving the free status of ! 433: all derivatives of our free software and of promoting the sharing and reuse of ! 434: software. ! 435: ! 436: ! 437: In other words, you are welcome to use, share and improve this program. ! 438: You are forbidden to forbid anyone else to use, share and improve ! 439: what you give them. Help stamp out software-hoarding! ! 440: ! 441: Adapted from expread.y of GDB by Paul Rubin, July 1986. ! 442: ! 443: /* Parse a C expression from text in a string */ ! 444: ! 445: %{ ! 446: #include "config.h" ! 447: #include <setjmp.h> ! 448: /* #define YYDEBUG 1 */ ! 449: ! 450: static int yylex (); ! 451: static yyerror (); ! 452: int expression_value; ! 453: ! 454: static jmp_buf parse_return_error; ! 455: ! 456: /* some external tables of character types */ ! 457: extern unsigned char is_idstart[], is_idchar[]; ! 458: ! 459: %} ! 460: ! 461: %union { ! 462: long lval; ! 463: int voidval; ! 464: char *sval; ! 465: } ! 466: ! 467: %type <lval> exp exp1 start ! 468: %token <lval> INT CHAR ! 469: %token <sval> NAME ! 470: %token <lval> ERROR ! 471: ! 472: %right '?' ':' ! 473: %left ',' ! 474: %left OR ! 475: %left AND ! 476: %left '|' ! 477: %left '^' ! 478: %left '&' ! 479: %left EQUAL NOTEQUAL ! 480: %left '<' '>' LEQ GEQ ! 481: %left LSH RSH ! 482: %left '+' '-' ! 483: %left '*' '/' '%' ! 484: %right UNARY ! 485: ! 486: /* %expect 40 */ ! 487: ! 488: %% ! 489: ! 490: start : exp1 ! 491: { expression_value = $1; } ! 492: ; ! 493: ! 494: /* Expressions, including the comma operator. */ ! 495: exp1 : exp ! 496: | exp1 ',' exp ! 497: { $$ = $3; } ! 498: ; ! 499: ! 500: /* Expressions, not including the comma operator. */ ! 501: exp : '-' exp %prec UNARY ! 502: { $$ = - $2; } ! 503: | '!' exp %prec UNARY ! 504: { $$ = ! $2; } ! 505: | '~' exp %prec UNARY ! 506: { $$ = ~ $2; } ! 507: | '(' exp1 ')' ! 508: { $$ = $2; } ! 509: ; ! 510: ! 511: /* Binary operators in order of decreasing precedence. */ ! 512: exp : exp '*' exp ! 513: { $$ = $1 * $3; } ! 514: | exp '/' exp ! 515: { $$ = $1 / $3; } ! 516: | exp '%' exp ! 517: { $$ = $1 % $3; } ! 518: | exp '+' exp ! 519: { $$ = $1 + $3; } ! 520: | exp '-' exp ! 521: { $$ = $1 - $3; } ! 522: | exp LSH exp ! 523: { $$ = $1 << $3; } ! 524: | exp RSH exp ! 525: { $$ = $1 >> $3; } ! 526: | exp EQUAL exp ! 527: { $$ = ($1 == $3); } ! 528: | exp NOTEQUAL exp ! 529: { $$ = ($1 != $3); } ! 530: | exp LEQ exp ! 531: { $$ = ($1 <= $3); } ! 532: | exp GEQ exp ! 533: { $$ = ($1 >= $3); } ! 534: | exp '<' exp ! 535: { $$ = ($1 < $3); } ! 536: | exp '>' exp ! 537: { $$ = ($1 > $3); } ! 538: | exp '&' exp ! 539: { $$ = ($1 & $3); } ! 540: | exp '^' exp ! 541: { $$ = ($1 ^ $3); } ! 542: | exp '|' exp ! 543: { $$ = ($1 | $3); } ! 544: | exp AND exp ! 545: { $$ = ($1 && $3); } ! 546: | exp OR exp ! 547: { $$ = ($1 || $3); } ! 548: | exp '?' exp ':' exp ! 549: { $$ = $1 ? $3 : $5; } ! 550: | INT ! 551: { $$ = yylval.lval; } ! 552: | CHAR ! 553: { $$ = yylval.lval; } ! 554: | NAME ! 555: { $$ = 0; } ! 556: ; ! 557: %% ! 558: ! 559: /* During parsing of a C expression, the pointer to the next character ! 560: is in this variable. */ ! 561: ! 562: static char *lexptr; ! 563: ! 564: /* Take care of parsing a number (anything that starts with a digit). ! 565: Set yylval and return the token type; update lexptr. ! 566: LEN is the number of characters in it. */ ! 567: ! 568: /* maybe needs to actually deal with floating point numbers */ ! 569: ! 570: static int ! 571: parse_number (olen) ! 572: int olen; ! 573: { ! 574: register char *p = lexptr; ! 575: register long n = 0; ! 576: register int c; ! 577: register int base = 10; ! 578: register len = olen; ! 579: char *err_copy; ! 580: ! 581: extern double atof (); ! 582: ! 583: for (c = 0; c < len; c++) ! 584: if (p[c] == '.') { ! 585: /* It's a float since it contains a point. */ ! 586: yyerror ("floating point numbers not allowed in #if expressions"); ! 587: return ERROR; ! 588: ! 589: /* **************** ! 590: yylval.dval = atof (p); ! 591: lexptr += len; ! 592: return FLOAT; ! 593: **************** */ ! 594: } ! 595: ! 596: if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) { ! 597: p += 2; ! 598: base = 16; ! 599: len -= 2; ! 600: } ! 601: else if (*p == '0') ! 602: base = 8; ! 603: ! 604: while (len-- > 0) { ! 605: c = *p++; ! 606: n *= base; ! 607: if (c >= '0' && c <= '9') ! 608: n += c - '0'; ! 609: else { ! 610: if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; ! 611: if (base == 16 && c >= 'a' && c <= 'f') ! 612: n += c - 'a' + 10; ! 613: else if (len == 0 && c == 'l') ! 614: ; ! 615: else { ! 616: yyerror ("Invalid number in #if expression"); ! 617: return ERROR; ! 618: } ! 619: } ! 620: } ! 621: ! 622: lexptr = p; ! 623: yylval.lval = n; ! 624: return INT; ! 625: } ! 626: ! 627: struct token { ! 628: char *operator; ! 629: int token; ! 630: }; ! 631: ! 632: #define NULL 0 ! 633: ! 634: static struct token tokentab2[] = { ! 635: {"&&", AND}, ! 636: {"||", OR}, ! 637: {"<<", LSH}, ! 638: {">>", RSH}, ! 639: {"==", EQUAL}, ! 640: {"!=", NOTEQUAL}, ! 641: {"<=", LEQ}, ! 642: {">=", GEQ}, ! 643: {NULL, ERROR} ! 644: }; ! 645: ! 646: /* Read one token, getting characters through lexptr. */ ! 647: ! 648: static int ! 649: yylex () ! 650: { ! 651: register int c; ! 652: register int namelen; ! 653: register char *tokstart; ! 654: register struct token *toktab; ! 655: ! 656: retry: ! 657: ! 658: tokstart = lexptr; ! 659: c = *tokstart; ! 660: /* See if it is a special token of length 2. */ ! 661: for (toktab = tokentab2; toktab->operator != NULL; toktab++) ! 662: if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) { ! 663: lexptr += 2; ! 664: return toktab->token; ! 665: } ! 666: ! 667: switch (c) { ! 668: case 0: ! 669: return 0; ! 670: ! 671: case ' ': ! 672: case '\t': ! 673: case '\n': ! 674: lexptr++; ! 675: goto retry; ! 676: ! 677: case '\'': ! 678: lexptr++; ! 679: c = *lexptr++; ! 680: if (c == '\\') ! 681: c = parse_escape (&lexptr); ! 682: yylval.lval = c; ! 683: c = *lexptr++; ! 684: if (c != '\'') { ! 685: yyerror ("Invalid character constant in #if"); ! 686: return ERROR; ! 687: } ! 688: ! 689: return CHAR; ! 690: ! 691: /* some of these chars are invalid in constant expressions; ! 692: maybe do something about them later */ ! 693: case '/': ! 694: case '+': ! 695: case '-': ! 696: case '*': ! 697: case '%': ! 698: case '|': ! 699: case '&': ! 700: case '^': ! 701: case '~': ! 702: case '!': ! 703: case '@': ! 704: case '<': ! 705: case '>': ! 706: case '(': ! 707: case ')': ! 708: case '[': ! 709: case ']': ! 710: case '.': ! 711: case '?': ! 712: case ':': ! 713: case '=': ! 714: case '{': ! 715: case '}': ! 716: case ',': ! 717: lexptr++; ! 718: return c; ! 719: ! 720: case '"': ! 721: yyerror ("double quoted strings not allowed in #if expressions"); ! 722: return ERROR; ! 723: } ! 724: if (c >= '0' && c <= '9') { ! 725: /* It's a number */ ! 726: for (namelen = 0; ! 727: c = tokstart[namelen], is_idchar[c] || c == '.'; ! 728: namelen++) ! 729: ; ! 730: return parse_number (namelen); ! 731: } ! 732: ! 733: if (!is_idstart[c]) { ! 734: yyerror ("Invalid token in expression"); ! 735: return ERROR; ! 736: } ! 737: ! 738: /* It is a name. See how long it is. */ ! 739: ! 740: for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++) ! 741: ; ! 742: ! 743: lexptr += namelen; ! 744: return NAME; ! 745: } ! 746: ! 747: ! 748: /* Parse a C escape sequence. STRING_PTR points to a variable ! 749: containing a pointer to the string to parse. That pointer ! 750: is updated past the characters we use. The value of the ! 751: escape sequence is returned. ! 752: ! 753: A negative value means the sequence \ newline was seen, ! 754: which is supposed to be equivalent to nothing at all. ! 755: ! 756: If \ is followed by a null character, we return a negative ! 757: value and leave the string pointer pointing at the null character. ! 758: ! 759: If \ is followed by 000, we return 0 and leave the string pointer ! 760: after the zeros. A value of 0 does not mean end of string. */ ! 761: ! 762: static int ! 763: parse_escape (string_ptr) ! 764: char **string_ptr; ! 765: { ! 766: register int c = *(*string_ptr)++; ! 767: switch (c) ! 768: { ! 769: case 'a': ! 770: return '\a'; ! 771: case 'b': ! 772: return '\b'; ! 773: case 'e': ! 774: return 033; ! 775: case 'f': ! 776: return '\f'; ! 777: case 'n': ! 778: return '\n'; ! 779: case 'r': ! 780: return '\r'; ! 781: case 't': ! 782: return '\t'; ! 783: case 'v': ! 784: return '\v'; ! 785: case '\n': ! 786: return -2; ! 787: case 0: ! 788: (*string_ptr)--; ! 789: return 0; ! 790: case '^': ! 791: c = *(*string_ptr)++; ! 792: if (c == '\\') ! 793: c = parse_escape (string_ptr); ! 794: if (c == '?') ! 795: return 0177; ! 796: return (c & 0200) | (c & 037); ! 797: ! 798: case '0': ! 799: case '1': ! 800: case '2': ! 801: case '3': ! 802: case '4': ! 803: case '5': ! 804: case '6': ! 805: case '7': ! 806: { ! 807: register int i = c - '0'; ! 808: register int count = 0; ! 809: while (++count < 3) ! 810: { ! 811: if ((c = *(*string_ptr)++) >= '0' && c <= '7') ! 812: { ! 813: i *= 8; ! 814: i += c - '0'; ! 815: } ! 816: else ! 817: { ! 818: (*string_ptr)--; ! 819: break; ! 820: } ! 821: } ! 822: return i; ! 823: } ! 824: default: ! 825: return c; ! 826: } ! 827: } ! 828: ! 829: static ! 830: yyerror (s) ! 831: char *s; ! 832: { ! 833: error (s); ! 834: longjmp (parse_return_error, 1); ! 835: } ! 836: ! 837: /* This page contains the entry point to this file. */ ! 838: ! 839: /* Parse STRING as an expression, and complain if this fails ! 840: to use up all of the contents of STRING. */ ! 841: /* We do not support C comments. They should be removed before ! 842: this function is called. */ ! 843: ! 844: int ! 845: parse_c_expression (string) ! 846: char *string; ! 847: { ! 848: lexptr = string; ! 849: ! 850: if (lexptr == 0 || *lexptr == 0) { ! 851: error ("empty #if expression"); ! 852: return 0; /* don't include the #if group */ ! 853: } ! 854: ! 855: /* if there is some sort of scanning error, just return 0 and assume ! 856: the parsing routine has printed an error message somewhere. ! 857: there is surely a better thing to do than this. */ ! 858: if (setjmp(parse_return_error)) ! 859: return 0; ! 860: ! 861: if (yyparse ()) ! 862: return 0; /* actually this is never reached ! 863: the way things stand. */ ! 864: if (*lexptr) ! 865: error ("Junk after end of expression."); ! 866: ! 867: return expression_value; /* set by yyparse() */ ! 868: } ! 869: ! 870: #ifdef TEST_EXP_READER ! 871: /* main program, for testing purposes. */ ! 872: main() ! 873: { ! 874: int n; ! 875: char buf[1024]; ! 876: extern int yydebug; ! 877: /* ! 878: yydebug = 1; ! 879: */ ! 880: initialize_random_junk (); ! 881: ! 882: for (;;) { ! 883: printf("enter expression: "); ! 884: n = 0; ! 885: while ((buf[n] = getchar()) != '\n') ! 886: n++; ! 887: buf[n] = '\0'; ! 888: printf("parser returned %d\n", parse_c_expression(buf)); ! 889: } ! 890: } ! 891: ! 892: /* table to tell if char can be part of a C identifier. */ ! 893: char is_idchar[256]; ! 894: /* table to tell if char can be first char of a c identifier. */ ! 895: char is_idstart[256]; ! 896: /* table to tell if c is horizontal space. isspace() thinks that ! 897: newline is space; this is not a good idea for this program. */ ! 898: char is_hor_space[256]; ! 899: ! 900: /* ! 901: * initialize random junk in the hash table and maybe other places ! 902: */ ! 903: initialize_random_junk() ! 904: { ! 905: register int i; ! 906: ! 907: /* ! 908: * Set up is_idchar and is_idstart tables. These should be ! 909: * faster than saying (is_alpha(c) || c == '_'), etc. ! 910: * Must do set up these things before calling any routines tthat ! 911: * refer to them. ! 912: */ ! 913: for (i = 'a'; i <= 'z'; i++) { ! 914: ++is_idchar[i - 'a' + 'A']; ! 915: ++is_idchar[i]; ! 916: ++is_idstart[i - 'a' + 'A']; ! 917: ++is_idstart[i]; ! 918: } ! 919: for (i = '0'; i <= '9'; i++) ! 920: ++is_idchar[i]; ! 921: ++is_idchar['_']; ! 922: ++is_idstart['_']; ! 923: #ifdef DOLLARS_IN_IDENTIFIERS ! 924: ++is_idchar['$']; ! 925: ++is_idstart['$']; ! 926: #endif ! 927: ! 928: /* horizontal space table */ ! 929: ++is_hor_space[' ']; ! 930: ++is_hor_space['\t']; ! 931: } ! 932: ! 933: error (msg) ! 934: { ! 935: printf("error: %s\n", msg); ! 936: } ! 937: #endif ! 938: 0707070114030157321006660005500000040000020640560426654766100001100000003137config.h /* Con
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.