Annotation of researchv10dc/cmd/gcc/gnucpp.cpio, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.