[BACK]Return to cpp.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2018 / parse

Annotation of OpenXM_contrib2/asir2018/parse/cpp.c, Revision 1.1

1.1     ! noro        1: /*
        !             2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
        !             6:  * non-exclusive and royalty-free license to use, copy, modify and
        !             7:  * redistribute, solely for non-commercial and non-profit purposes, the
        !             8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
        !             9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
        !            10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
        !            11:  * third party developer retains all rights, including but not limited to
        !            12:  * copyrights, in and to the SOFTWARE.
        !            13:  *
        !            14:  * (1) FLL does not grant you a license in any way for commercial
        !            15:  * purposes. You may use the SOFTWARE only for non-commercial and
        !            16:  * non-profit purposes only, such as academic, research and internal
        !            17:  * business use.
        !            18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
        !            19:  * international copyright treaties. If you make copies of the SOFTWARE,
        !            20:  * with or without modification, as permitted hereunder, you shall affix
        !            21:  * to all such copies of the SOFTWARE the above copyright notice.
        !            22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
        !            23:  * shall be made on your publication or presentation in any form of the
        !            24:  * results obtained by use of the SOFTWARE.
        !            25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
        !            26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
        !            27:  * for such modification or the source code of the modified part of the
        !            28:  * SOFTWARE.
        !            29:  *
        !            30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
        !            31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
        !            32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
        !            33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
        !            34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
        !            35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
        !            36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
        !            37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
        !            38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
        !            39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
        !            40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
        !            41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
        !            42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
        !            43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
        !            44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
        !            45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
        !            46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
        !            47:  *
        !            48:  * $OpenXM$
        !            49: */
        !            50: #include <stdio.h>
        !            51: #include <ctype.h>
        !            52: #include <setjmp.h>
        !            53: jmp_buf cpp_env;
        !            54:
        !            55: #if 0
        !            56: #include "accum.h"
        !            57: #include "expr.h"
        !            58: #include "if.h"
        !            59: #include "io.h"
        !            60: #include "is.h"
        !            61: #include "malloc.h"
        !            62: #include "stats.h"
        !            63: #include "symtbl.h"
        !            64: #include "unctrl.h"
        !            65: #endif
        !            66:
        !            67:
        !            68: #include "cpp.h"
        !            69:
        !            70: char *init_accum(void)
        !            71: {
        !            72:  ACCUM *a;
        !            73:
        !            74:  a = NEW(ACCUM);
        !            75:  check_malloc(a);
        !            76:  a->used = 0;
        !            77:  a->have = 8;
        !            78:  a->buf = malloc(8);
        !            79:  check_malloc(a->buf);
        !            80:  return((char *)a);
        !            81: }
        !            82:
        !            83: void accum_char(char *A, char c)
        !            84:
        !            85: #define a ((ACCUM *)A)
        !            86:
        !            87: {
        !            88:  while (a->used >= a->have)
        !            89:   { a->buf = realloc(a->buf,a->have+=8);
        !            90:     check_malloc(a->buf);
        !            91:   }
        !            92:  a->buf[a->used++] = c;
        !            93: }
        !            94: #undef a
        !            95:
        !            96: char accum_regret(char *A)
        !            97:
        !            98: #define a ((ACCUM *)A)
        !            99: {
        !           100:  if (a->used > 0)
        !           101:   { return(a->buf[--a->used]);
        !           102:   }
        !           103:  else
        !           104:   { return(0);
        !           105:   }
        !           106: }
        !           107: #undef a
        !           108:
        !           109: char *accum_result(char *A)
        !           110:
        !           111: #define a ((ACCUM *)A)
        !           112: {
        !           113:  char *cp;
        !           114:
        !           115:  cp = realloc(a->buf,a->used+1);
        !           116:  check_malloc(cp);
        !           117:  cp[a->used] = '\0';
        !           118:  OLD(a);
        !           119:  return(cp);
        !           120: }
        !           121: #undef a
        !           122:
        !           123: char *accum_sofar(char *A)
        !           124:
        !           125: #define a ((ACCUM *)A)
        !           126: {
        !           127:  char *cp;
        !           128:
        !           129:  cp = malloc(a->used+1);
        !           130:  check_malloc(cp);
        !           131:  Bcopy(a->buf,cp,a->used);
        !           132:  cp[a->used] = '\0';
        !           133:  return(cp);
        !           134: }
        !           135: #undef a
        !           136:
        !           137: char *accum_buf(char *A)
        !           138:
        !           139: #define a ((ACCUM *)A)
        !           140: {
        !           141:  return(a->buf);
        !           142: }
        !           143: #undef a
        !           144:
        !           145: int accum_howfar(char *A)
        !           146:
        !           147: #define a ((ACCUM *)A)
        !           148: {
        !           149:  return(a->used);
        !           150: }
        !           151: #undef a
        !           152:
        !           153: void do_at(void)
        !           154: {
        !           155:  char *w;
        !           156:
        !           157:  w = read_ctrl();
        !           158:  if (strcmp(w,"include") == 0)
        !           159:   { do_include(0);
        !           160:   }
        !           161:  else if (strcmp(w,"define") == 0)
        !           162:   { do_define(0,0);
        !           163:   }
        !           164:  else if (strcmp(w,"undef") == 0)
        !           165:   { do_undef(0);
        !           166:   }
        !           167:  else if (strcmp(w,"redefine") == 0)
        !           168:   { do_define(0,1);
        !           169:   }
        !           170:  else if (strcmp(w,"ifdef") == 0)
        !           171:   { do_ifdef(0);
        !           172:   }
        !           173:  else if (strcmp(w,"ifndef") == 0)
        !           174:   { do_ifndef(0);
        !           175:   }
        !           176:  else if (strcmp(w,"if") == 0)
        !           177:   { do_if(0);
        !           178:   }
        !           179:  else if (strcmp(w,"else") == 0)
        !           180:   { do_else(0);
        !           181:   }
        !           182:  else if (strcmp(w,"elif") == 0)
        !           183:   { do_elif(0);
        !           184:   }
        !           185:  else if (strcmp(w,"endif") == 0)
        !           186:   { do_endif(0);
        !           187:   }
        !           188:  else if (strcmp(w,"set") == 0)
        !           189:   { do_set();
        !           190:   }
        !           191:  else if (strcmp(w,"while") == 0)
        !           192:   { do_while();
        !           193:   }
        !           194:  else if (strcmp(w,"endwhile") == 0)
        !           195:   { do_endwhile();
        !           196:   }
        !           197:  else if (strcmp(w,"dump") == 0)
        !           198:   { do_dump();
        !           199:   }
        !           200:  else if (strcmp(w,"debug") == 0)
        !           201:   { do_debug();
        !           202:   }
        !           203:  else if (strcmp(w,"eval") == 0)
        !           204:   { do_eval();
        !           205:   }
        !           206:  else
        !           207:   { if (! in_false_if())
        !           208:      { err_head();
        !           209:        fprintf(stderr,"unknown control `%s'\n",w);
        !           210:      }
        !           211:   }
        !           212:  free(w);
        !           213: }
        !           214:
        !           215: static char *temp;
        !           216:
        !           217: void autodef_file(char *f)
        !           218: {
        !           219:  int i;
        !           220:
        !           221:  i = strlen(f);
        !           222:  temp = malloc(i+2+1);
        !           223:  check_malloc(temp);
        !           224:  sprintf(temp,"\"%s\"",f);
        !           225:  undef("__FILE__");
        !           226:  define("__FILE__",-1,(unsigned char *)temp,0);
        !           227: }
        !           228:
        !           229: void autodef_line(int l)
        !           230: {
        !           231:  defd("__LINE__",l);
        !           232: }
        !           233:
        !           234: char *copyofstr(char *str)
        !           235: {
        !           236:  char *cp;
        !           237:
        !           238:  if (str == 0)
        !           239:   { return(0);
        !           240:   }
        !           241:  cp = malloc(strlen(str)+1);
        !           242:  if (cp == 0)
        !           243:   { return(0);
        !           244:   }
        !           245:  strcpy(cp,str);
        !           246:  return(cp);
        !           247: }
        !           248:
        !           249: char *copyofblk(char *blk, int len)
        !           250: {
        !           251:  char *cp;
        !           252:
        !           253:  if (blk == 0)
        !           254:   { return(0);
        !           255:   }
        !           256:  cp = malloc(len);
        !           257:  if (cp == 0)
        !           258:   { return(0);
        !           259:   }
        !           260:  Bcopy(blk,cp,len);
        !           261:  return(cp);
        !           262: }
        !           263:
        !           264: /* these really don't beint here; they should be in their own file */
        !           265:
        !           266: #if 0
        !           267: char *malloc(nb)
        !           268: #undef malloc
        !           269: int nb;
        !           270: {
        !           271:  extern char *malloc();
        !           272:
        !           273:  return(malloc(nb?nb:1));
        !           274: }
        !           275:
        !           276: char *realloc(old,nb)
        !           277: #undef realloc
        !           278: char *old;
        !           279: int nb;
        !           280: {
        !           281:  extern char *realloc();
        !           282:
        !           283:  return(realloc(old,(nb?nb:1)));
        !           284: }
        !           285: #endif
        !           286:
        !           287: static char buf[BUFSIZ];
        !           288:
        !           289: int debugging = 0;
        !           290:
        !           291: void do_debug(void)
        !           292: {
        !           293:  char c;
        !           294:
        !           295:  fflush(outfile);
        !           296:  c = getnonspace();
        !           297:  switch (c)
        !           298:   { case '1':
        !           299:     case 'y':
        !           300:     case 'Y':
        !           301:        debugging = 1;
        !           302:        break;
        !           303:     default:
        !           304:        debugging = 0;
        !           305:        break;
        !           306:   }
        !           307:  setbuf(outfile,debugging?NULL:buf);
        !           308: }
        !           309:
        !           310: static int nargs;
        !           311: static int nfound;
        !           312: static char **argnames;
        !           313:
        !           314: void read_formals(void)
        !           315: {
        !           316:  char *arg;
        !           317:  char c;
        !           318:
        !           319:  nargs = 0;
        !           320:  argnames = (char **) malloc(1);
        !           321:  check_malloc(argnames);
        !           322:  while (1)
        !           323:   { arg = read_ident();
        !           324:     if (arg)
        !           325:      { argnames = (char **) realloc((char *)argnames,(nargs+1)*sizeof(char *));
        !           326:        check_malloc(argnames);
        !           327:        argnames[nargs] = arg;
        !           328:        nargs ++;
        !           329:        c = getnonspace();
        !           330:        if (c == ')')
        !           331:   { return;
        !           332:   }
        !           333:        else if (c != ',')
        !           334:   { err_head();
        !           335:     fprintf(stderr,"invalid macro parameter delimiter\n");
        !           336:   }
        !           337:      }
        !           338:     else
        !           339:      { c = Get();
        !           340:        if ((c == ')') && (nargs == 0))
        !           341:   { return;
        !           342:   }
        !           343:        else
        !           344:   { Push(c);
        !           345:   }
        !           346:        err_head();
        !           347:        fprintf(stderr,"missing/illegal macro parameter\n");
        !           348:        while (1)
        !           349:   { c = Get();
        !           350:     if (c == ')')
        !           351:      { return;
        !           352:      }
        !           353:     if (isbsymchar(c))
        !           354:      { Push(c);
        !           355:        break;
        !           356:      }
        !           357:   }
        !           358:      }
        !           359:   }
        !           360: }
        !           361:
        !           362: void do_define(int sharp, int redef)
        !           363: {
        !           364:  char *mac;
        !           365:  char c;
        !           366:  char *acc;
        !           367:  unsigned char *repl;
        !           368:  int quoted;
        !           369:  int incomment;
        !           370:  unsigned char *f;
        !           371:  unsigned char *t;
        !           372:  unsigned char *g;
        !           373:  int i;
        !           374:
        !           375:  if (in_false_if())
        !           376:   { char e = '\0';
        !           377:     if (sharp)
        !           378:      { while (1)
        !           379:   { c = e;
        !           380:     e = Get();
        !           381:     if (e == '\n')
        !           382:      { if (c == '\\')
        !           383:         { maybe_print('\n');
        !           384:         }
        !           385:        else
        !           386:         { break;
        !           387:         }
        !           388:      }
        !           389:   }
        !           390:      }
        !           391:     else
        !           392:      { do
        !           393:   { c = e;
        !           394:     e = Get();
        !           395:   } while ((c != '@') || (e == '@'));
        !           396:        Push(e);
        !           397:      }
        !           398:     return;
        !           399:   }
        !           400:  mac = read_ident();
        !           401:  if (! mac)
        !           402:   { err_head();
        !           403:     fprintf(stderr,"missing/illegal macro name\n");
        !           404:     flush_sharp_line();
        !           405:     return;
        !           406:   }
        !           407:  c = Get();
        !           408:  if (c == '(')
        !           409:   { read_formals();
        !           410:     nfound = nargs;
        !           411:     if (nargs > 128)
        !           412:      { err_head();
        !           413:        fprintf(stderr,"too many macro formals, more than 128 ignored\n");
        !           414:        nargs = 128;
        !           415:      }
        !           416:   }
        !           417:  else
        !           418:   { argnames = 0;
        !           419:     nargs = -1;
        !           420:     nfound = -1;
        !           421:     if ((c != ' ') && (c != '\t'))
        !           422:      { Push(c);
        !           423:      }
        !           424:   }
        !           425:  quoted = 0;
        !           426:  incomment = 0;
        !           427:  acc = init_accum();
        !           428:  if (sharp)
        !           429:   { while (1)
        !           430:      { c = Get();
        !           431:        if (quoted && (c == '\n'))
        !           432:   { quoted = 0;
        !           433:     maybe_print('\n');
        !           434:   }
        !           435:        else if (quoted)
        !           436:   { accum_char(acc,'\\');
        !           437:     accum_char(acc,c);
        !           438:     quoted = 0;
        !           439:   }
        !           440:        else if (c == '/')
        !           441:   { char d = Get();
        !           442:     accum_char(acc,'/');
        !           443:     if (d == '*')
        !           444:      { accum_char(acc,'*');
        !           445:        incomment = 1;
        !           446:      }
        !           447:     else
        !           448:      { Push(d);
        !           449:      }
        !           450:   }
        !           451:        else if (incomment)
        !           452:   { accum_char(acc,c);
        !           453:     if (c == '*')
        !           454:      { char d = Get();
        !           455:        if (d == '/')
        !           456:         { accum_char(acc,'/');
        !           457:     incomment = 0;
        !           458:         }
        !           459:        else
        !           460:         { Push(d);
        !           461:         }
        !           462:      }
        !           463:     else if (c == '\n')
        !           464:      { maybe_print('\n');
        !           465:      }
        !           466:   }
        !           467:        else if (c == '\\')
        !           468:   { quoted = 1;
        !           469:   }
        !           470:        else if (c == '\n')
        !           471:   { break;
        !           472:   }
        !           473:        else
        !           474:   { accum_char(acc,c);
        !           475:   }
        !           476:      }
        !           477:   }
        !           478:  else
        !           479:   { while (1)
        !           480:      { c = Get();
        !           481:        if (quoted && (c == '@'))
        !           482:   { accum_char(acc,'@');
        !           483:     quoted = 0;
        !           484:   }
        !           485:        else if (quoted)
        !           486:   { Push(c);
        !           487:     break;
        !           488:   }
        !           489:        else if (c == '/')
        !           490:   { char d = Get();
        !           491:     accum_char(acc,'/');
        !           492:     if (d == '*')
        !           493:      { accum_char(acc,'*');
        !           494:        incomment = 1;
        !           495:      }
        !           496:     else
        !           497:      { Push(d);
        !           498:      }
        !           499:   }
        !           500:        else if (incomment)
        !           501:   { accum_char(acc,c);
        !           502:     if (c == '*')
        !           503:      { char d = Get();
        !           504:        if (d == '/')
        !           505:         { accum_char(acc,'/');
        !           506:     incomment = 0;
        !           507:         }
        !           508:        else
        !           509:         { Push(d);
        !           510:         }
        !           511:      }
        !           512:     else if (c == '\n')
        !           513:      { maybe_print('\n');
        !           514:      }
        !           515:   }
        !           516:        else if (c == '@')
        !           517:   { quoted = 1;
        !           518:   }
        !           519:        else
        !           520:   { if (c == '\n')
        !           521:      { maybe_print('\n');
        !           522:      }
        !           523:     accum_char(acc,c);
        !           524:   }
        !           525:      }
        !           526:   }
        !           527:  repl = (unsigned char *) accum_result(acc);
        !           528:  f = repl;
        !           529:  t = repl;
        !           530:  while (*f)
        !           531:   { if (isbsymchar(*f) && !incomment)
        !           532:      { for (g=f;issymchar(*g);g++) ;
        !           533:        c = *g;
        !           534:        *g = '\0';
        !           535:        for (i=0;i<nargs;i++)
        !           536:   { if (strcmp((char *)f,argnames[i]) == 0)
        !           537:      { break;
        !           538:      }
        !           539:   }
        !           540:        if (i < nargs)
        !           541:   { *t++ = 0x80 | i;
        !           542:     f = g;
        !           543:   }
        !           544:        else
        !           545:   { while (*t++ = *f++) ;
        !           546:     f --;
        !           547:     t --;
        !           548:   }
        !           549:        *g = c;
        !           550:      }
        !           551:     else if ((f[0] == '/') && (f[1] == '*'))
        !           552:      { f += 2;
        !           553:        *t++ = '/';
        !           554:        *t++ = '*';
        !           555:        incomment = 1;
        !           556:      }
        !           557:     else if (incomment && (f[0] == '*') && (f[1] == '/'))
        !           558:      { f += 2;
        !           559:        *t++ = '*';
        !           560:        *t++ = '/';
        !           561:        incomment = 0;
        !           562:      }
        !           563:     else
        !           564:      { *t++ = *f++;
        !           565:      }
        !           566:   }
        !           567:  *t++ = '\0';
        !           568:  repl = (unsigned char *) realloc((char *)repl,t-repl);
        !           569:  check_malloc(repl);
        !           570:  if (redef)
        !           571:   { undef(mac);
        !           572:   }
        !           573:  n_defines ++;
        !           574:  define(mac,nargs,repl,DEF_DEFINE);
        !           575:  if (argnames)
        !           576:   { for (i=0;i<nfound;i++)
        !           577:      { free(argnames[i]);
        !           578:      }
        !           579:     free((char *)argnames);
        !           580:   }
        !           581:  free(mac);
        !           582: }
        !           583:
        !           584: void do_dump(void)
        !           585: {
        !           586:  int i;
        !           587:  DEF *d;
        !           588:  extern char *cur_incldir;
        !           589:  extern char *incldir[];
        !           590:  extern int fstackdepth;
        !           591:
        !           592:  fprintf(stderr,
        !           593:   "\n\n\tDump of definition table (%d entries in %d buckets):\n\n",
        !           594:             n_in_table,symtbl_size);
        !           595:  for (i=0;i<symtbl_size;i++)
        !           596:   { fprintf(stderr,"Bucket %d:\n",i);
        !           597:     for (d=symtbl[i];d;d=d->link)
        !           598:      { dump_single(d);
        !           599:        putc('\n',stderr);
        !           600:      }
        !           601:   }
        !           602:  fprintf(stderr,"\n\tInclude directory stack:\n\n");
        !           603:  for (i=0;i<fstackdepth;i++)
        !           604:   { fprintf(stderr,"\t\t%s\n",incldir[i]);
        !           605:   }
        !           606:  fprintf(stderr,"\t\t%s\n",cur_incldir);
        !           607: }
        !           608:
        !           609: void dump_single(DEF *d)
        !           610: {
        !           611:  unsigned char *cp;
        !           612:
        !           613:  fprintf(stderr,"\t%s",d->name);
        !           614:  if (d->nargs == 0)
        !           615:   { fprintf(stderr,"()");
        !           616:   }
        !           617:  else if (d->nargs > 0)
        !           618:   { int i;
        !           619:     for (i=0;i<d->nargs;i++)
        !           620:      { fprintf(stderr,"%c#%d",i?',':'(',i);
        !           621:      }
        !           622:     putc(')',stderr);
        !           623:   }
        !           624:  putc(' ',stderr);
        !           625:  for (cp=d->repl;*cp;cp++)
        !           626:   { if (*cp & 0x80)
        !           627:      { fprintf(stderr,"#%d",(*cp)&~0x80);
        !           628:      }
        !           629:     else
        !           630:      { putc(*cp,stderr);
        !           631:      }
        !           632:   }
        !           633: }
        !           634:
        !           635: void err_head(void)
        !           636: {
        !           637:  fprintf(stderr,"\"%s\", line %d: ",curfile(),curline());
        !           638: }
        !           639:
        !           640: void Check_malloc(char *ptr)
        !           641: {
        !           642:  if (ptr == 0)
        !           643:   { fprintf(stderr,"out of memory!\n");
        !           644:     abort();
        !           645:   }
        !           646: }
        !           647:
        !           648: void do_eval(void)
        !           649: {
        !           650:  char c;
        !           651:  char temp[64];
        !           652:  int i;
        !           653:
        !           654:  if (! in_false_if())
        !           655:   { c = getnonspace();
        !           656:     if (c != '(')
        !           657:      { err_head();
        !           658:        fprintf(stderr,"@eval must have ()s\n");
        !           659:        Push(c);
        !           660:        return;
        !           661:      }
        !           662:     sprintf(temp,"%d",eval_expr(0,1));
        !           663:     for (i=strlen(temp)-1;i>=0;i--)
        !           664:      { Push(temp[i]);
        !           665:      }
        !           666:   }
        !           667: }
        !           668:
        !           669: #define DEBUG_EXPAND/**/
        !           670:
        !           671: #ifdef DEBUG_EXPAND
        !           672: extern int debugging;
        !           673: #endif
        !           674:
        !           675: extern int keep_comments;
        !           676:
        !           677: static char **actuals;
        !           678: static int *actlens;
        !           679:
        !           680: void read_actuals(DEF *d)
        !           681: {
        !           682:  int n;
        !           683:  int i;
        !           684:  int pc;
        !           685:  char c;
        !           686:  char last;
        !           687:  char quote;
        !           688:  int backslash;
        !           689:  int comment;
        !           690:  char *acc;
        !           691:
        !           692:  n = d->nargs;
        !           693:  actuals = (char **) malloc(n*sizeof(char *));
        !           694:  check_malloc(actuals);
        !           695:  actlens = (int *) malloc(n*sizeof(int));
        !           696:  check_malloc(actlens);
        !           697:  c = getnonspace();
        !           698:  if (c != '(')
        !           699:   { err_head();
        !           700:     if (n == 0)
        !           701:      { fprintf(stderr,"missing () on %s\n",d->name);
        !           702:      }
        !           703:     else
        !           704:      { fprintf(stderr,"missing argument%s to %s\n",(n==1)?"":"s",d->name);
        !           705:      }
        !           706:     for (i=0;i<n;i++)
        !           707:      { actuals[i] = copyofstr("");
        !           708:        check_malloc(actuals[i]);
        !           709:        actlens[i] = 0;
        !           710:      }
        !           711:     Push(c);
        !           712:     return;
        !           713:   }
        !           714:  if (n == 0)
        !           715:   { c = getnonspace();
        !           716:     if (c != ')')
        !           717:      { err_head();
        !           718:        fprintf(stderr,"unwanted argument to %s\n",d->name);
        !           719:        Push(c);
        !           720:      }
        !           721:     return;
        !           722:   }
        !           723:  i = 0;
        !           724:  while (1)
        !           725:   { pc = 0;
        !           726:     quote = 0;
        !           727:     backslash = 0;
        !           728:     comment = 0;
        !           729:     c = 0;
        !           730:     acc = init_accum();
        !           731:     while (1)
        !           732:      { last = c;
        !           733:        c = Get();
        !           734:        accum_char(acc,c);
        !           735:        if (comment)
        !           736:   { if ((last == '*') && (c == '/'))
        !           737:      { comment = 0;
        !           738:      }
        !           739:   }
        !           740:        else
        !           741:   { if (backslash)
        !           742:      { backslash = 0;
        !           743:      }
        !           744:     else if (quote && (c == quote))
        !           745:      { quote = 0;
        !           746:      }
        !           747:     else if (c == '\\')
        !           748:      { backslash = 1;
        !           749:      }
        !           750:     else if (quote)
        !           751:      {
        !           752:      }
        !           753:     else if ((last == '/') && (c == '*'))
        !           754:      { comment = 1;
        !           755:      }
        !           756:     else if ((c == '\'') || (c == '"'))
        !           757:      { quote = c;
        !           758:      }
        !           759:     else if (c == '(')
        !           760:      { pc ++;
        !           761:      }
        !           762:     else if (c == ')')
        !           763:      { if (pc > 0)
        !           764:         { pc --;
        !           765:         }
        !           766:        else
        !           767:         { accum_regret(acc);
        !           768:     break;
        !           769:         }
        !           770:      }
        !           771:     else if ((c == ',') && (pc == 0))
        !           772:      { accum_regret(acc);
        !           773:        break;
        !           774:      }
        !           775:   }
        !           776:      }
        !           777:     if (i < n)
        !           778:      { actuals[i] = accum_result(acc);
        !           779:        actlens[i] = strlen(actuals[i]);
        !           780:        i ++;
        !           781:      }
        !           782:     else if (i == n)
        !           783:      { err_head();
        !           784:        fprintf(stderr,"too many arguments to %s\n",d->name);
        !           785:        i ++;
        !           786:      }
        !           787:     if (c == ')')
        !           788:      { break;
        !           789:      }
        !           790:   }
        !           791:  if (i < n)
        !           792:   { err_head();
        !           793:     fprintf(stderr,"too few arguments to %s\n",d->name);
        !           794:     for (;i<n;i++)
        !           795:      { actuals[i] = copyofstr("");
        !           796:        check_malloc(actuals[i]);
        !           797:        actlens[i] = 0;
        !           798:      }
        !           799:   }
        !           800: }
        !           801:
        !           802: void expand_def(DEF *d)
        !           803: {
        !           804:  unsigned char *cp;
        !           805:  char *dp;
        !           806:  char *ep;
        !           807:  char *result;
        !           808:  int ok;
        !           809:  int incomm;
        !           810:  char last;
        !           811:
        !           812:  if (d->nargs >= 0)
        !           813:   { read_actuals(d);
        !           814:   }
        !           815: #ifdef DEBUG_EXPAND
        !           816:  if (debugging)
        !           817:   { char *cp;
        !           818:     outputs("~EXPAND:");
        !           819:     outputs(d->name);
        !           820:     if (d->nargs == 0)
        !           821:      { outputs("()");
        !           822:      }
        !           823:     else if (d->nargs > 0)
        !           824:      { int i;
        !           825:        for (i=0;i<d->nargs;i++)
        !           826:   { outputc((char)(i?',':'('));
        !           827:     outputs(actuals[i]);
        !           828:   }
        !           829:        outputc(')');
        !           830:      }
        !           831:     outputs("-->");
        !           832:     for (cp=(char *)d->repl;*cp;cp++)
        !           833:      { outputs(unctrl(*cp));
        !           834:      }
        !           835:     outputc('~');
        !           836:   }
        !           837: #endif
        !           838:  result = init_accum();
        !           839:  for (cp=d->repl;*cp;cp++)
        !           840:   { if (*cp & 0x80)
        !           841:      { char *dp;
        !           842:        int i;
        !           843:        i = *cp & ~0x80;
        !           844:        for (dp=actuals[i];*dp;dp++)
        !           845:   { accum_char(result,*dp);
        !           846:   }
        !           847:      }
        !           848:     else
        !           849:      { accum_char(result,*cp);
        !           850:      }
        !           851:   }
        !           852:  dp = accum_result(result);
        !           853: #ifdef DEBUG_EXPAND
        !           854:  if (debugging)
        !           855:   { outputs("first:");
        !           856:     for (ep=dp;*ep;ep++)
        !           857:      { outputs(unctrl(*ep));
        !           858:      }
        !           859:     outputc('~');
        !           860:   }
        !           861: #endif
        !           862:  result = init_accum();
        !           863:  last = '\0';
        !           864:  ok = 1;
        !           865:  incomm = 0;
        !           866:  for (ep=dp;*ep;ep++)
        !           867:   { if (!incomm && (last == '/') && (*ep == '*'))
        !           868:      { incomm = 1;
        !           869:        if (!keep_comments || (strncmp(ep,"**/",3) == 0))
        !           870:   { accum_regret(result);
        !           871:     ok = 0;
        !           872:   }
        !           873:      }
        !           874:     if (ok)
        !           875:      { accum_char(result,*ep);
        !           876:      }
        !           877:     if ((last == '*') && (*ep == '/'))
        !           878:      { incomm = 0;
        !           879:        ok = 1;
        !           880:      }
        !           881:     last = *ep;
        !           882:   }
        !           883:  free(dp);
        !           884:  result = accum_result(result);
        !           885: #ifdef DEBUG_EXPAND
        !           886:  if (debugging)
        !           887:   { outputs("/**/strip:");
        !           888:     outputs(result);
        !           889:     outputc('~');
        !           890:   }
        !           891: #endif
        !           892:  for (dp=result+strlen(result)-1;dp>=result;dp--)
        !           893:   { Push(*dp);
        !           894:   }
        !           895:  free(result);
        !           896:  if (d->nargs >= 0)
        !           897:   { int i;
        !           898:     for (i=0;i<d->nargs;i++)
        !           899:      { free(actuals[i]);
        !           900:      }
        !           901:     free((char *)actuals);
        !           902:   }
        !           903: }
        !           904:
        !           905: #define DEBUG_EXPR/**/
        !           906:
        !           907: #define TWOCHAR(c1,c2) (((c1)<<8)|(c2))
        !           908: #define LSH TWOCHAR('<','<')
        !           909: #define RSH TWOCHAR('>','>')
        !           910: #define LEQ TWOCHAR('<','=')
        !           911: #define GEQ TWOCHAR('>','=')
        !           912: #define EQL TWOCHAR('=','=')
        !           913: #define NEQ TWOCHAR('!','=')
        !           914: #define AND TWOCHAR('&','&')
        !           915: #define OR  TWOCHAR('|','|')
        !           916:
        !           917: #define ALLBINS    \
        !           918:   BIN('*',*)  \
        !           919:   BIN('/',/)  \
        !           920:   BIN('%',%)  \
        !           921:   BIN('+',+)  \
        !           922:   BIN(LSH,<<)  \
        !           923:   BIN(RSH,>>)  \
        !           924:   BIN('<',<)  \
        !           925:   BIN('>',>)  \
        !           926:   BIN(LEQ,<=)  \
        !           927:   BIN(GEQ,>=)  \
        !           928:   BIN(EQL,==)  \
        !           929:   BIN(NEQ,!=)  \
        !           930:   BIN('&',&)  \
        !           931:   BIN('^',^)  \
        !           932:   BIN('|',|)  \
        !           933:   BIN(AND,&&)  \
        !           934:   BIN(OR ,||)
        !           935:
        !           936: char *Index(char *s, int c);
        !           937:
        !           938: static NODE *expr;
        !           939: int expr_sharp;
        !           940: #define sharp expr_sharp
        !           941: static int complain;
        !           942:
        !           943: #ifdef DEBUG_EXPR
        !           944: extern int debugging;
        !           945: #endif
        !           946:
        !           947: void free_expr(NODE *n)
        !           948: {
        !           949:  switch (n->op)
        !           950:   { case 0:
        !           951:        break;
        !           952:     case '-':
        !           953:        if (n->left)
        !           954:   { free_expr(n->left);
        !           955:   }
        !           956:        free_expr(n->right);
        !           957:        break;
        !           958:     case '!':
        !           959:     case '~':
        !           960:        free_expr(n->right);
        !           961:        break;
        !           962:     case 'd':
        !           963:        free(n->name);
        !           964:        break;
        !           965:     default:
        !           966:        free_expr(n->left);
        !           967:        free_expr(n->right);
        !           968:        break;
        !           969:   }
        !           970:  OLD(n);
        !           971: }
        !           972:
        !           973: int exec_free(NODE *n)
        !           974: {
        !           975:  int rv;
        !           976:  int l;
        !           977:  int r;
        !           978:
        !           979:  switch (n->op)
        !           980:   { case 0:
        !           981:        rv = n->leaf;
        !           982:        break;
        !           983:     case '-':
        !           984:        if (n->left)
        !           985:   { rv = exec_free(n->left);
        !           986:   }
        !           987:        else
        !           988:   { rv = 0;
        !           989:   }
        !           990:        rv -= exec_free(n->right);
        !           991:        break;
        !           992:     case '!':
        !           993:        rv = ! exec_free(n->right);
        !           994:        break;
        !           995:     case '~':
        !           996:        rv = ~ exec_free(n->right);
        !           997:        break;
        !           998:     case 'd':
        !           999:        rv = !! find_def(n->name);
        !          1000:        free(n->name);
        !          1001:        break;
        !          1002: #define BIN(key,op) case key:l=exec_free(n->left);r=exec_free(n->right);rv=l op r;break;
        !          1003:     ALLBINS
        !          1004: #undef BIN
        !          1005:   }
        !          1006:  OLD(n);
        !          1007:  return(rv);
        !          1008: }
        !          1009:
        !          1010: int exec_nofree(NODE *n)
        !          1011: {
        !          1012:  int rv;
        !          1013:
        !          1014:  switch (n->op)
        !          1015:   { case 0:
        !          1016:        rv = n->leaf;
        !          1017:        break;
        !          1018:     case '-':
        !          1019:        if (n->left)
        !          1020:   { rv = exec_nofree(n->left);
        !          1021:   }
        !          1022:        else
        !          1023:   { rv = 0;
        !          1024:   }
        !          1025:        rv -= exec_nofree(n->right);
        !          1026:        break;
        !          1027:     case '!':
        !          1028:        rv = ! exec_nofree(n->right);
        !          1029:        break;
        !          1030:     case '~':
        !          1031:        rv = ~ exec_nofree(n->right);
        !          1032:        break;
        !          1033:     case 'd':
        !          1034:        rv = !! find_def(n->name);
        !          1035:        free(n->name);
        !          1036:        break;
        !          1037: #define BIN(key,op) case key:rv=(exec_nofree(n->left)op exec_nofree(n->right));break;
        !          1038:     ALLBINS
        !          1039: #undef BIN
        !          1040:   }
        !          1041:  return(rv);
        !          1042: }
        !          1043:
        !          1044: NODE *newnode(NODE *l, int c, NODE *r)
        !          1045: {
        !          1046:  NODE *n;
        !          1047:
        !          1048:  n = NEW(NODE);
        !          1049:  check_malloc(n);
        !          1050:  n->left = l;
        !          1051:  n->right = r;
        !          1052:  n->op = c;
        !          1053:  return(n);
        !          1054: }
        !          1055:
        !          1056: NODE *newleaf(int v)
        !          1057: {
        !          1058:  NODE *n;
        !          1059:
        !          1060:  n = NEW(NODE);
        !          1061:  check_malloc(n);
        !          1062:  n->op = 0;
        !          1063:  n->left = 0;
        !          1064:  n->right = 0;
        !          1065:  n->leaf = v;
        !          1066:  return(n);
        !          1067: }
        !          1068:
        !          1069: NODE *newname(char *name)
        !          1070: {
        !          1071:  NODE *n;
        !          1072:
        !          1073:  n = NEW(NODE);
        !          1074:  check_malloc(n);
        !          1075:  n->op = 'd';
        !          1076:  n->name = copyofstr(name);
        !          1077:  check_malloc(n->name);
        !          1078:  return(n);
        !          1079: }
        !          1080:
        !          1081: int get_quote_char(void)
        !          1082: {
        !          1083:  char c;
        !          1084:  char d;
        !          1085:
        !          1086:  c = Get();
        !          1087:  if (c == '\'')
        !          1088:   { return(-1);
        !          1089:   }
        !          1090:  if (c == '\n')
        !          1091:   { err_head();
        !          1092:     fprintf(stderr,"newline in character constant\n");
        !          1093:     return(-1);
        !          1094:   }
        !          1095:  if (c != '\\')
        !          1096:   { return(0xff&(int)c);
        !          1097:   }
        !          1098:  c = Get();
        !          1099:  if ((c >= '0') && (c <= '7'))
        !          1100:   { d = c - '0';
        !          1101:     c = Get();
        !          1102:     if ((c >= '0') && (c <= '7'))
        !          1103:      { d = (d << 3) + c - '0';
        !          1104:        c = Get();
        !          1105:        if ((c >= '0') && (c <= '7'))
        !          1106:   { d = (d << 3) + c - '0';
        !          1107:   }
        !          1108:        else
        !          1109:   { Push(c);
        !          1110:   }
        !          1111:      }
        !          1112:     else
        !          1113:      { Push(c);
        !          1114:      }
        !          1115:     return(0xff&(int)d);
        !          1116:   }
        !          1117:  switch (c)
        !          1118:   { case 'n':
        !          1119:        return('\n');
        !          1120:        break;
        !          1121:     case 'r':
        !          1122:        return('\r');
        !          1123:        break;
        !          1124:     case 'e':
        !          1125:        return('\033');
        !          1126:        break;
        !          1127:     case 'f':
        !          1128:        return('\f');
        !          1129:        break;
        !          1130:     case 't':
        !          1131:        return('\t');
        !          1132:        break;
        !          1133:     case 'b':
        !          1134:        return('\b');
        !          1135:        break;
        !          1136:     case 'v':
        !          1137:        return('\v');
        !          1138:        break;
        !          1139:     default:
        !          1140:        return(0xff&(int)c);
        !          1141:        break;
        !          1142:   }
        !          1143: }
        !          1144:
        !          1145: NODE *read_expr_11(void)
        !          1146: {
        !          1147:  char c;
        !          1148:
        !          1149: #ifdef DEBUG_EXPR
        !          1150:  if (debugging)
        !          1151:   { outputs("~E11:");
        !          1152:   }
        !          1153: #endif
        !          1154:  while (1)
        !          1155:   { c = getnhsexpand();
        !          1156:     if (c == '(')
        !          1157:      { NODE *n;
        !          1158:        NODE *read_expr_(void);
        !          1159: #ifdef DEBUG_EXPR
        !          1160:        if (debugging)
        !          1161:   { outputs("()");
        !          1162:   }
        !          1163: #endif
        !          1164:        n = read_expr_();
        !          1165:        c = getnhsexpand();
        !          1166:        if (c != ')')
        !          1167:   { err_head();
        !          1168:     fprintf(stderr,"expression syntax error -- missing ) supplied\n");
        !          1169:     Push(c);
        !          1170:   }
        !          1171: #ifdef DEBUG_EXPR
        !          1172:        if (debugging)
        !          1173:   { outputs("~");
        !          1174:   }
        !          1175: #endif
        !          1176:        return(n);
        !          1177:      }
        !          1178:     else if (isdigit(c))
        !          1179:      { int base;
        !          1180:        static char digits[] = "0123456789abcdefABCDEF";
        !          1181:        static char values[] =
        !          1182:     "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\12\13\14\15\16\17";
        !          1183:        char *d;
        !          1184:        int v;
        !          1185: #ifdef DEBUG_EXPR
        !          1186:        if (debugging)
        !          1187:   { outputs("N");
        !          1188:   }
        !          1189: #endif
        !          1190:        base = 10;
        !          1191:        if (c == '0')
        !          1192:   { base = 8;
        !          1193:     c = Get();
        !          1194:     if ((c == 'x') || (c == 'X'))
        !          1195:      { base = 16;
        !          1196:        c = Get();
        !          1197:      }
        !          1198:   }
        !          1199:        v = 0;
        !          1200:        while (1)
        !          1201:   { d = Index(digits,c);
        !          1202:     if (d == 0)
        !          1203:      { Push(c);
        !          1204: #ifdef DEBUG_EXPR
        !          1205:        if (debugging)
        !          1206:         { outputd(v);
        !          1207:     outputs("~");
        !          1208:         }
        !          1209: #endif
        !          1210:        return(newleaf(v));
        !          1211:      }
        !          1212:     else if (values[d-digits] >= base)
        !          1213:      { err_head();
        !          1214:        fprintf(stderr,"warning: illegal %sdigit `%c'\n",
        !          1215:       (base==16)?"hex ":(base==8)?"octal ":"",c);
        !          1216:      }
        !          1217:     v = (v * base) + values[d-digits];
        !          1218:     c = Get();
        !          1219:   }
        !          1220:      }
        !          1221:     else if (c == '\'')
        !          1222:      { int i;
        !          1223:        int j;
        !          1224:        int n;
        !          1225:        i = 0;
        !          1226:        n = 0;
        !          1227:        while (1)
        !          1228:   { j = get_quote_char();
        !          1229:     if (j < 0)
        !          1230:      { break;
        !          1231:      }
        !          1232:     i = (i << 8) | j;
        !          1233:     n ++;
        !          1234:   }
        !          1235:        if (n > 4)
        !          1236:   { err_head();
        !          1237:     fprintf(stderr,"warning: too many characters in character constant\n");
        !          1238:   }
        !          1239:        return(newleaf(i));
        !          1240:      }
        !          1241:     else if ((c == '\n') && !sharp)
        !          1242:      {
        !          1243:      }
        !          1244:     else
        !          1245:      { char *id;
        !          1246:        if (complain)
        !          1247:   { err_head();
        !          1248:     fprintf(stderr,"expression syntax error -- number expected\n");
        !          1249:   }
        !          1250:        if (isbsymchar(c))
        !          1251:   { Push(c);
        !          1252:     id = read_ident();
        !          1253:   }
        !          1254:        else
        !          1255:   { id = 0;
        !          1256:   }
        !          1257: #ifdef DEBUG_EXPR
        !          1258:        if (debugging)
        !          1259:   { outputs("0(");
        !          1260:     outputc(c);
        !          1261:     outputs(":");
        !          1262:     outputs(id?id:"(none)");
        !          1263:     outputs(")~");
        !          1264:   }
        !          1265: #endif
        !          1266:        if (id)
        !          1267:   { free(id);
        !          1268:   }
        !          1269:        return(newleaf(0));
        !          1270:      }
        !          1271:   }
        !          1272: }
        !          1273:
        !          1274: NODE *read_expr_10(void)
        !          1275: {
        !          1276:  char c;
        !          1277:  char *w;
        !          1278:  NODE *n;
        !          1279:
        !          1280: #ifdef DEBUG_EXPR
        !          1281:  if (debugging)
        !          1282:   { outputs("~E10:");
        !          1283:   }
        !          1284: #endif
        !          1285:  while (1)
        !          1286:   { c = getnhsexpand();
        !          1287:     switch (c)
        !          1288:      { case '-':
        !          1289:        case '~':
        !          1290:        case '!':
        !          1291: #ifdef DEBUG_EXPR
        !          1292:     if (debugging)
        !          1293:      { outputc(c);
        !          1294:      }
        !          1295: #endif
        !          1296:     n = read_expr_10();
        !          1297: #ifdef DEBUG_EXPR
        !          1298:     if (debugging)
        !          1299:      { outputs("~");
        !          1300:      }
        !          1301: #endif
        !          1302:     return(newnode(0,c,n));
        !          1303:     break;
        !          1304:        case 'd':
        !          1305:     Push(c);
        !          1306:     input_mark();
        !          1307:     w = read_ident();
        !          1308:     if (strcmp(w,"defined") == 0)
        !          1309:      { c = getnonspace();
        !          1310:        if (c == '(')
        !          1311:         { char *id;
        !          1312:     id = read_ident();
        !          1313:     if (id)
        !          1314:      { c = getnonspace();
        !          1315:        if (c == ')')
        !          1316:         { input_unmark();
        !          1317: #ifdef DEBUG_EXPR
        !          1318:           if (debugging)
        !          1319:            { outputs("ifdef");
        !          1320:            }
        !          1321: #endif
        !          1322:           return(newname(id));
        !          1323:         }
        !          1324:      }
        !          1325:         }
        !          1326:        else if (isbsymchar(c))
        !          1327:         { char *id;
        !          1328:     Push(c);
        !          1329:     id = read_ident();
        !          1330:     if (id)
        !          1331:      { input_unmark();
        !          1332: #ifdef DEBUG_EXPR
        !          1333:        if (debugging)
        !          1334:         { outputs("ifdef");
        !          1335:         }
        !          1336: #endif
        !          1337:        return(newname(id));
        !          1338:      }
        !          1339:         }
        !          1340:      }
        !          1341:     input_recover();
        !          1342:     n = read_expr_11();
        !          1343: #ifdef DEBUG_EXPR
        !          1344:     if (debugging)
        !          1345:      { outputs("~");
        !          1346:      }
        !          1347: #endif
        !          1348:     return(n);
        !          1349:     break;
        !          1350:        default:
        !          1351:     Push(c);
        !          1352:     n = read_expr_11();
        !          1353: #ifdef DEBUG_EXPR
        !          1354:     if (debugging)
        !          1355:      { outputs("~");
        !          1356:      }
        !          1357: #endif
        !          1358:     return(n);
        !          1359:     break;
        !          1360:      }
        !          1361:   }
        !          1362: }
        !          1363:
        !          1364: NODE *read_expr_9(void)
        !          1365: {
        !          1366:  NODE *l;
        !          1367:  NODE *r;
        !          1368:  char c;
        !          1369:
        !          1370: #ifdef DEBUG_EXPR
        !          1371:  if (debugging)
        !          1372:   { outputs("~E9:");
        !          1373:   }
        !          1374: #endif
        !          1375:  l = read_expr_10();
        !          1376:  while (1)
        !          1377:   { c = getnhsexpand();
        !          1378:     switch (c)
        !          1379:      { case '*':
        !          1380:        case '/':
        !          1381:        case '%':
        !          1382: #ifdef DEBUG_EXPR
        !          1383:     if (debugging)
        !          1384:      { outputc(c);
        !          1385:      }
        !          1386: #endif
        !          1387:     r = read_expr_10();
        !          1388:     l = newnode(l,c,r);
        !          1389:     break;
        !          1390:        default:
        !          1391: #ifdef DEBUG_EXPR
        !          1392:     if (debugging)
        !          1393:      { outputs("~");
        !          1394:      }
        !          1395: #endif
        !          1396:     Push(c);
        !          1397:     return(l);
        !          1398:     break;
        !          1399:      }
        !          1400:   }
        !          1401: }
        !          1402:
        !          1403: NODE *read_expr_8(void)
        !          1404: {
        !          1405:  NODE *l;
        !          1406:  NODE *r;
        !          1407:  char c;
        !          1408:
        !          1409: #ifdef DEBUG_EXPR
        !          1410:  if (debugging)
        !          1411:   { outputs("~E8:");
        !          1412:   }
        !          1413: #endif
        !          1414:  l = read_expr_9();
        !          1415:  while (1)
        !          1416:   { c = getnhsexpand();
        !          1417:     switch (c)
        !          1418:      { case '+':
        !          1419:        case '-':
        !          1420: #ifdef DEBUG_EXPR
        !          1421:     if (debugging)
        !          1422:      { outputc(c);
        !          1423:      }
        !          1424: #endif
        !          1425:     r = read_expr_9();
        !          1426:     l = newnode(l,c,r);
        !          1427:     break;
        !          1428:        default:
        !          1429: #ifdef DEBUG_EXPR
        !          1430:     if (debugging)
        !          1431:      { outputs("~");
        !          1432:      }
        !          1433: #endif
        !          1434:     Push(c);
        !          1435:     return(l);
        !          1436:     break;
        !          1437:      }
        !          1438:   }
        !          1439: }
        !          1440:
        !          1441: NODE *read_expr_7(void)
        !          1442: {
        !          1443:  NODE *l;
        !          1444:  NODE *r;
        !          1445:  char c;
        !          1446:  char d;
        !          1447:
        !          1448: #ifdef DEBUG_EXPR
        !          1449:  if (debugging)
        !          1450:   { outputs("~E7:");
        !          1451:   }
        !          1452: #endif
        !          1453:  l = read_expr_8();
        !          1454:  while (1)
        !          1455:   { c = getnhsexpand();
        !          1456:     switch (c)
        !          1457:      { case '<':
        !          1458:        case '>':
        !          1459:     d = Get();
        !          1460:     if (d == c)
        !          1461:      {
        !          1462: #ifdef DEBUG_EXPR
        !          1463:        if (debugging)
        !          1464:         { outputc(c);
        !          1465:     outputc(d);
        !          1466:         }
        !          1467: #endif
        !          1468:        r = read_expr_8();
        !          1469:        l = newnode(l,(c=='<')?LSH:RSH,r);
        !          1470:        break;
        !          1471:      }
        !          1472:     Push(d);
        !          1473:     /* fall through ... */
        !          1474:        default:
        !          1475: #ifdef DEBUG_EXPR
        !          1476:     if (debugging)
        !          1477:      { outputs("~");
        !          1478:      }
        !          1479: #endif
        !          1480:     Push(c);
        !          1481:     return(l);
        !          1482:     break;
        !          1483:      }
        !          1484:   }
        !          1485: }
        !          1486:
        !          1487: NODE *read_expr_6(void)
        !          1488: {
        !          1489:  NODE *l;
        !          1490:  NODE *r;
        !          1491:  char c;
        !          1492:  char d;
        !          1493:
        !          1494: #ifdef DEBUG_EXPR
        !          1495:  if (debugging)
        !          1496:   { outputs("~E6:");
        !          1497:   }
        !          1498: #endif
        !          1499:  l = read_expr_7();
        !          1500:  while (1)
        !          1501:   { c = getnhsexpand();
        !          1502:     switch (c)
        !          1503:      { case '<':
        !          1504:        case '>':
        !          1505:     d = Get();
        !          1506:     if (d == '=')
        !          1507:      {
        !          1508: #ifdef DEBUG_EXPR
        !          1509:        if (debugging)
        !          1510:         { outputc(c);
        !          1511:     outputc(d);
        !          1512:         }
        !          1513: #endif
        !          1514:        r = read_expr_7();
        !          1515:        l = newnode(l,(c=='<')?LEQ:GEQ,r);
        !          1516:      }
        !          1517:     else
        !          1518:      {
        !          1519: #ifdef DEBUG_EXPR
        !          1520:        if (debugging)
        !          1521:         { outputc(c);
        !          1522:         }
        !          1523: #endif
        !          1524:        Push(d);
        !          1525:        r = read_expr_7();
        !          1526:        l = newnode(l,c,r);
        !          1527:      }
        !          1528:     break;
        !          1529:        default:
        !          1530: #ifdef DEBUG_EXPR
        !          1531:     if (debugging)
        !          1532:      { outputs("~");
        !          1533:      }
        !          1534: #endif
        !          1535:     Push(c);
        !          1536:     return(l);
        !          1537:     break;
        !          1538:      }
        !          1539:   }
        !          1540: }
        !          1541:
        !          1542: NODE *read_expr_5(void)
        !          1543: {
        !          1544:  NODE *l;
        !          1545:  NODE *r;
        !          1546:  char c;
        !          1547:  char d;
        !          1548:
        !          1549: #ifdef DEBUG_EXPR
        !          1550:  if (debugging)
        !          1551:   { outputs("~E5:");
        !          1552:   }
        !          1553: #endif
        !          1554:  l = read_expr_6();
        !          1555:  while (1)
        !          1556:   { c = getnhsexpand();
        !          1557:     switch (c)
        !          1558:      { case '=':
        !          1559:        case '!':
        !          1560:     d = Get();
        !          1561:     if (d == '=')
        !          1562:      {
        !          1563: #ifdef DEBUG_EXPR
        !          1564:        if (debugging)
        !          1565:         { outputc(c);
        !          1566:     outputc(d);
        !          1567:         }
        !          1568: #endif
        !          1569:        r = read_expr_6();
        !          1570:        l = newnode(l,(c=='=')?EQL:NEQ,r);
        !          1571:        break;
        !          1572:      }
        !          1573:     Push(d);
        !          1574:     /* fall through ... */
        !          1575:        default:
        !          1576: #ifdef DEBUG_EXPR
        !          1577:     if (debugging)
        !          1578:      { outputs("~");
        !          1579:      }
        !          1580: #endif
        !          1581:     Push(c);
        !          1582:     return(l);
        !          1583:     break;
        !          1584:      }
        !          1585:   }
        !          1586: }
        !          1587:
        !          1588: NODE *read_expr_4(void)
        !          1589: {
        !          1590:  NODE *l;
        !          1591:  NODE *r;
        !          1592:  char c;
        !          1593:  char d;
        !          1594:
        !          1595: #ifdef DEBUG_EXPR
        !          1596:  if (debugging)
        !          1597:   { outputs("~E4:");
        !          1598:   }
        !          1599: #endif
        !          1600:  l = read_expr_5();
        !          1601:  while (1)
        !          1602:   { c = getnhsexpand();
        !          1603:     switch (c)
        !          1604:      { case '&':
        !          1605:     d = Get();
        !          1606:     if (d != '&')
        !          1607:      {
        !          1608: #ifdef DEBUG_EXPR
        !          1609:        if (debugging)
        !          1610:         { outputc(c);
        !          1611:     outputc(d);
        !          1612:         }
        !          1613: #endif
        !          1614:        r = read_expr_5();
        !          1615:        l = newnode(l,c,r);
        !          1616:        break;
        !          1617:      }
        !          1618:     Push(d);
        !          1619:     /* fall through ... */
        !          1620:        default:
        !          1621: #ifdef DEBUG_EXPR
        !          1622:     if (debugging)
        !          1623:      { outputs("~");
        !          1624:      }
        !          1625: #endif
        !          1626:     Push(c);
        !          1627:     return(l);
        !          1628:     break;
        !          1629:      }
        !          1630:   }
        !          1631: }
        !          1632:
        !          1633: NODE *read_expr_3(void)
        !          1634: {
        !          1635:  NODE *l;
        !          1636:  NODE *r;
        !          1637:  char c;
        !          1638:
        !          1639: #ifdef DEBUG_EXPR
        !          1640:  if (debugging)
        !          1641:   { outputs("~E3:");
        !          1642:   }
        !          1643: #endif
        !          1644:  l = read_expr_4();
        !          1645:  while (1)
        !          1646:   { c = getnhsexpand();
        !          1647:     switch (c)
        !          1648:      { case '^':
        !          1649: #ifdef DEBUG_EXPR
        !          1650:     if (debugging)
        !          1651:      { outputc(c);
        !          1652:      }
        !          1653: #endif
        !          1654:     r = read_expr_4();
        !          1655:     l = newnode(l,c,r);
        !          1656:     break;
        !          1657:        default:
        !          1658: #ifdef DEBUG_EXPR
        !          1659:     if (debugging)
        !          1660:      { outputs("~");
        !          1661:      }
        !          1662: #endif
        !          1663:     Push(c);
        !          1664:     return(l);
        !          1665:     break;
        !          1666:      }
        !          1667:   }
        !          1668: }
        !          1669:
        !          1670: NODE *read_expr_2(void)
        !          1671: {
        !          1672:  NODE *l;
        !          1673:  NODE *r;
        !          1674:  char c;
        !          1675:  char d;
        !          1676:
        !          1677: #ifdef DEBUG_EXPR
        !          1678:  if (debugging)
        !          1679:   { outputs("~E2:");
        !          1680:   }
        !          1681: #endif
        !          1682:  l = read_expr_3();
        !          1683:  while (1)
        !          1684:   { c = getnhsexpand();
        !          1685:     switch (c)
        !          1686:      { case '|':
        !          1687:     d = Get();
        !          1688:     if (d != '|')
        !          1689:      { Push(d);
        !          1690: #ifdef DEBUG_EXPR
        !          1691:        if (debugging)
        !          1692:         { outputc(c);
        !          1693:         }
        !          1694: #endif
        !          1695:        r = read_expr_3();
        !          1696:        l = newnode(l,c,r);
        !          1697:        break;
        !          1698:      }
        !          1699:     Push(d);
        !          1700:     /* fall through ... */
        !          1701:        default:
        !          1702: #ifdef DEBUG_EXPR
        !          1703:     if (debugging)
        !          1704:      { outputs("~");
        !          1705:      }
        !          1706: #endif
        !          1707:     Push(c);
        !          1708:     return(l);
        !          1709:     break;
        !          1710:      }
        !          1711:   }
        !          1712: }
        !          1713:
        !          1714: NODE *read_expr_1(void)
        !          1715: {
        !          1716:  NODE *l;
        !          1717:  NODE *r;
        !          1718:  char c;
        !          1719:  char d;
        !          1720:
        !          1721: #ifdef DEBUG_EXPR
        !          1722:  if (debugging)
        !          1723:   { outputs("~E1:");
        !          1724:   }
        !          1725: #endif
        !          1726:  l = read_expr_2();
        !          1727:  while (1)
        !          1728:   { c = getnhsexpand();
        !          1729:     switch (c)
        !          1730:      { case '&':
        !          1731:     d = Get();
        !          1732:     if (d == c)
        !          1733:      {
        !          1734: #ifdef DEBUG_EXPR
        !          1735:        if (debugging)
        !          1736:         { outputc(c);
        !          1737:     outputc(d);
        !          1738:         }
        !          1739: #endif
        !          1740:        r = read_expr_2();
        !          1741:        l = newnode(l,AND,r);
        !          1742:        break;
        !          1743:      }
        !          1744:     Push(d);
        !          1745:     /* fall through ... */
        !          1746:        default:
        !          1747: #ifdef DEBUG_EXPR
        !          1748:     if (debugging)
        !          1749:      { outputs("~");
        !          1750:      }
        !          1751: #endif
        !          1752:     Push(c);
        !          1753:     return(l);
        !          1754:     break;
        !          1755:      }
        !          1756:   }
        !          1757: }
        !          1758:
        !          1759: NODE *read_expr_0(void)
        !          1760: {
        !          1761:  NODE *l;
        !          1762:  NODE *r;
        !          1763:  char c;
        !          1764:  char d;
        !          1765:
        !          1766: #ifdef DEBUG_EXPR
        !          1767:  if (debugging)
        !          1768:   { outputs("~E0:");
        !          1769:   }
        !          1770: #endif
        !          1771:  l = read_expr_1();
        !          1772:  while (1)
        !          1773:   { c = getnhsexpand();
        !          1774:     switch (c)
        !          1775:      { case '|':
        !          1776:     d = Get();
        !          1777:     if (d == c)
        !          1778:      {
        !          1779: #ifdef DEBUG_EXPR
        !          1780:        if (debugging)
        !          1781:         { outputc(c);
        !          1782:     outputc(d);
        !          1783:         }
        !          1784: #endif
        !          1785:        r = read_expr_1();
        !          1786:        l = newnode(l,OR,r);
        !          1787:        break;
        !          1788:      }
        !          1789:     Push(d);
        !          1790:     /* fall through ... */
        !          1791:        default:
        !          1792: #ifdef DEBUG_EXPR
        !          1793:     if (debugging)
        !          1794:      { outputs("~");
        !          1795:      }
        !          1796: #endif
        !          1797:     Push(c);
        !          1798:     return(l);
        !          1799:     break;
        !          1800:      }
        !          1801:   }
        !          1802: }
        !          1803:
        !          1804: NODE *read_expr_(void)
        !          1805: {
        !          1806:  NODE *l;
        !          1807:  NODE *r;
        !          1808:  char c;
        !          1809:
        !          1810: #ifdef DEBUG_EXPR
        !          1811:  if (debugging)
        !          1812:   { outputs("~E");
        !          1813:   }
        !          1814: #endif
        !          1815:  l = read_expr_0();
        !          1816:  while (1)
        !          1817:   { c = getnhsexpand();
        !          1818:     switch (c)
        !          1819:      { case '\n':
        !          1820:        case ')':
        !          1821:     Push(c);
        !          1822:     return(l);
        !          1823:     break;
        !          1824:        case ',':
        !          1825:     r = read_expr_0();
        !          1826:     l = newnode(l,c,r);
        !          1827:     break;
        !          1828:        default:
        !          1829:     err_head();
        !          1830:     fprintf(stderr,"expression syntax error -- bad operator `%c'\n",c);
        !          1831:     return(l);
        !          1832:     break;
        !          1833:      }
        !          1834:   }
        !          1835: }
        !          1836:
        !          1837: NODE *read_expr_p(void)
        !          1838: {
        !          1839:  char c;
        !          1840:  NODE *rv;
        !          1841:
        !          1842:  sharp = 0;
        !          1843:  complain = 1;
        !          1844:  c = getnonspace();
        !          1845:  if (c != '(')
        !          1846:   { Push(c);
        !          1847:     return(0);
        !          1848:   }
        !          1849:  rv = read_expr_();
        !          1850:  c = getnonspace();
        !          1851:  if (c != ')')
        !          1852:   { err_head();
        !          1853:     fprintf(stderr,"junk after expression\n");
        !          1854:   }
        !          1855:  return(rv);
        !          1856: }
        !          1857:
        !          1858: int eval_expr(int Sharp, int Complain)
        !          1859: {
        !          1860:  char c;
        !          1861:  char d;
        !          1862:  int rv;
        !          1863:
        !          1864:  sharp = Sharp;
        !          1865:  complain = Complain;
        !          1866:  expr = read_expr_();
        !          1867:  if (sharp)
        !          1868:   { c = getnonhspace();
        !          1869:     d = '\n';
        !          1870:   }
        !          1871:  else
        !          1872:   { c = getnonspace();
        !          1873:     d = ')';
        !          1874:   }
        !          1875:  if (c != d)
        !          1876:   { if (complain)
        !          1877:      { err_head();
        !          1878:        fprintf(stderr,"expression syntax error -- junk after expression\n");
        !          1879:      }
        !          1880:     while (Get() != d) ;
        !          1881:   }
        !          1882: #ifdef DEBUG_EXPR
        !          1883:  if (debugging)
        !          1884:   { outputc('<');
        !          1885:     dump_expr(expr);
        !          1886:     outputc('=');
        !          1887:     rv = exec_free(expr);
        !          1888:     outputd(rv);
        !          1889:     outputc('>');
        !          1890:   }
        !          1891:  else
        !          1892:   { rv = exec_free(expr);
        !          1893:   }
        !          1894:  return(rv);
        !          1895: #else
        !          1896:  return(exec_free(expr));
        !          1897: #endif
        !          1898: }
        !          1899:
        !          1900: #ifdef DEBUG_EXPR
        !          1901: void dump_expr(NODE *n)
        !          1902: {
        !          1903:  switch (n->op)
        !          1904:   { case 0:
        !          1905:        outputd(n->leaf);
        !          1906:        break;
        !          1907:     case '-':
        !          1908:        if (n->left)
        !          1909:   { dump_expr(n->left);
        !          1910:   }
        !          1911:        outputc('-');
        !          1912:        dump_expr(n->right);
        !          1913:        break;
        !          1914:     case '!':
        !          1915:        outputc('!');
        !          1916:        dump_expr(n->right);
        !          1917:        break;
        !          1918:     case '~':
        !          1919:        outputc('~');
        !          1920:        dump_expr(n->right);
        !          1921:        break;
        !          1922:     case 'd':
        !          1923:        outputs("defined(");
        !          1924:        outputs(n->name);
        !          1925:        outputc(')');
        !          1926:        break;
        !          1927: #define BIN(key,op) case key:dump_expr(n->left);\
        !          1928:        putx(key);\
        !          1929:        dump_expr(n->right);\
        !          1930:     break;
        !          1931:     ALLBINS
        !          1932: #undef BIN
        !          1933:   }
        !          1934: }
        !          1935:
        !          1936: void putx(int i)
        !          1937: {
        !          1938:  if (i > 0xff) outputc((char)(i>>8));
        !          1939:  outputc((char)(i&0xff));
        !          1940: }
        !          1941: #endif
        !          1942:
        !          1943: /*#define DEBUG_IF/**/
        !          1944:
        !          1945: #ifdef DEBUG_IF
        !          1946: extern int debugging;
        !          1947: #endif
        !          1948:
        !          1949: void do_if(int expr_sharp)
        !          1950: {
        !          1951:  char c;
        !          1952:  char d;
        !          1953:
        !          1954: #ifdef DEBUG_IF
        !          1955:  if (debugging)
        !          1956:   { outputc('<');
        !          1957:     outputc(sharp?'#':'@');
        !          1958:     outputs("if: ");
        !          1959:     fflush(outfile);
        !          1960:   }
        !          1961: #endif
        !          1962:  if (in_false_if())
        !          1963:   { n_skipped_ifs ++;
        !          1964: #ifdef DEBUG_IF
        !          1965:     if (debugging)
        !          1966:      { outputs("in-false, skipped>");
        !          1967:        fflush(outfile);
        !          1968:      }
        !          1969: #endif
        !          1970:     if (sharp)
        !          1971:      { d = '\0';
        !          1972:        do
        !          1973:   { c = d;
        !          1974:     d = Get();
        !          1975:   } while ((c == '\\') || (d != '\n'));
        !          1976:      }
        !          1977:     return;
        !          1978:   }
        !          1979:  if (! sharp)
        !          1980:   { c = getnonspace();
        !          1981:     if (c != '(')
        !          1982:      { err_head();
        !          1983:        fprintf(stderr,"@if must have ()s\n");
        !          1984:        Push(c);
        !          1985:        iffalse();
        !          1986: #ifdef DEBUG_IF
        !          1987:        if (debugging)
        !          1988:   { outputc('>');
        !          1989:     fflush(outfile);
        !          1990:   }
        !          1991: #endif
        !          1992:        return;
        !          1993:      }
        !          1994:   }
        !          1995:  if (eval_expr(sharp,0))
        !          1996:   { iftrue();
        !          1997:   }
        !          1998:  else
        !          1999:   { iffalse();
        !          2000:   }
        !          2001: #ifdef DEBUG_IF
        !          2002:  if (debugging)
        !          2003:   { outputc('>');
        !          2004:     fflush(outfile);
        !          2005:   }
        !          2006: #endif
        !          2007: }
        !          2008:
        !          2009: void do_ifdef(int expr_sharp)
        !          2010: {
        !          2011:  char *w;
        !          2012:
        !          2013: #ifdef DEBUG_IF
        !          2014:  if (debugging)
        !          2015:   { outputc('<');
        !          2016:     outputc(sharp?'#':'@');
        !          2017:     outputs("ifdef: ");
        !          2018:     fflush(outfile);
        !          2019:   }
        !          2020: #endif
        !          2021:  if (in_false_if())
        !          2022:   { n_skipped_ifs ++;
        !          2023: #ifdef DEBUG_IF
        !          2024:     if (debugging)
        !          2025:      { outputs("in-false, skipped>");
        !          2026:        fflush(outfile);
        !          2027:      }
        !          2028: #endif
        !          2029:   }
        !          2030:  else
        !          2031:   { w = read_ident();
        !          2032:     if (! w)
        !          2033:      {
        !          2034: #ifdef DEBUG_IF
        !          2035:        if (debugging)
        !          2036:   { outputs("no ident ");
        !          2037:     fflush(outfile);
        !          2038:   }
        !          2039: #endif
        !          2040:        iffalse();
        !          2041:      }
        !          2042:     else
        !          2043:      {
        !          2044: #ifdef DEBUG_IF
        !          2045:        if (debugging)
        !          2046:   { outputs(w);
        !          2047:     outputc(' ');
        !          2048:     fflush(outfile);
        !          2049:   }
        !          2050: #endif
        !          2051:        if (find_def(w))
        !          2052:   { iftrue();
        !          2053:   }
        !          2054:        else
        !          2055:   { iffalse();
        !          2056:   }
        !          2057:        free(w);
        !          2058:      }
        !          2059: #ifdef DEBUG_IF
        !          2060:     if (debugging)
        !          2061:      { outputc('>');
        !          2062:        fflush(outfile);
        !          2063:      }
        !          2064: #endif
        !          2065:   }
        !          2066:  if (sharp)
        !          2067:   { flush_sharp_line();
        !          2068:   }
        !          2069: }
        !          2070:
        !          2071: void do_ifndef(int expr_sharp)
        !          2072: {
        !          2073:  char *w;
        !          2074:
        !          2075: #ifdef DEBUG_IF
        !          2076:  if (debugging)
        !          2077:   { outputc('<');
        !          2078:     outputc(sharp?'#':'@');
        !          2079:     outputs("ifndef: ");
        !          2080:     fflush(outfile);
        !          2081:   }
        !          2082: #endif
        !          2083:  if (in_false_if())
        !          2084:   { n_skipped_ifs ++;
        !          2085: #ifdef DEBUG_IF
        !          2086:     if (debugging)
        !          2087:      { outputs("in-false, skipped>");
        !          2088:        fflush(outfile);
        !          2089:      }
        !          2090: #endif
        !          2091:   }
        !          2092:  else
        !          2093:   { w = read_ident();
        !          2094:     if (! w)
        !          2095:      {
        !          2096: #ifdef DEBUG_IF
        !          2097:        if (debugging)
        !          2098:   { outputs("no ident ");
        !          2099:     fflush(outfile);
        !          2100:   }
        !          2101: #endif
        !          2102:        iftrue();
        !          2103:      }
        !          2104:     else
        !          2105:      {
        !          2106: #ifdef DEBUG_IF
        !          2107:        if (debugging)
        !          2108:   { outputs(w);
        !          2109:     outputc(' ');
        !          2110:     fflush(outfile);
        !          2111:   }
        !          2112: #endif
        !          2113:        if (find_def(w))
        !          2114:   { iffalse();
        !          2115:   }
        !          2116:        else
        !          2117:   { iftrue();
        !          2118:   }
        !          2119:        free(w);
        !          2120:      }
        !          2121: #ifdef DEBUG_IF
        !          2122:     if (debugging)
        !          2123:      { outputc('>');
        !          2124:        fflush(outfile);
        !          2125:      }
        !          2126: #endif
        !          2127:   }
        !          2128:  if (sharp)
        !          2129:   { flush_sharp_line();
        !          2130:   }
        !          2131: }
        !          2132:
        !          2133: void do_else(int expr_sharp)
        !          2134: {
        !          2135: #ifdef DEBUG_IF
        !          2136:  if (debugging)
        !          2137:   { outputc('<');
        !          2138:     outputc(sharp?'#':'@');
        !          2139:     outputs("else: ");
        !          2140:     fflush(outfile);
        !          2141:   }
        !          2142: #endif
        !          2143:  if (n_skipped_ifs == 0)
        !          2144:   { if (ifstack)
        !          2145:      {
        !          2146: #ifdef DEBUG_IF
        !          2147:        if (debugging)
        !          2148:   { outputs("top ");
        !          2149:     output_ifstate(ifstack->condstate);
        !          2150:     fflush(outfile);
        !          2151:   }
        !          2152: #endif
        !          2153:        switch (ifstack->condstate)
        !          2154:   { case IFSTATE_TRUE:
        !          2155:        ifstack->condstate = IFSTATE_STAYFALSE;
        !          2156:        break;
        !          2157:     case IFSTATE_FALSE:
        !          2158:        ifstack->condstate = IFSTATE_TRUE;
        !          2159:        break;
        !          2160:   }
        !          2161: #ifdef DEBUG_IF
        !          2162:        if (debugging)
        !          2163:   { outputs(" now ");
        !          2164:     output_ifstate(ifstack->condstate);
        !          2165:     outputc('>');
        !          2166:     fflush(outfile);
        !          2167:   }
        !          2168: #endif
        !          2169:      }
        !          2170:     else
        !          2171:      {
        !          2172: #ifdef DEBUG_IF
        !          2173:        if (debugging)
        !          2174:   { outputs(" no if>");
        !          2175:     fflush(outfile);
        !          2176:   }
        !          2177: #endif
        !          2178:        err_head();
        !          2179:        fprintf(stderr,"if-less else\n");
        !          2180:      }
        !          2181:   }
        !          2182:  else
        !          2183:   {
        !          2184: #ifdef DEBUG_IF
        !          2185:     if (debugging)
        !          2186:      { outputs("in-false, forgetting>");
        !          2187:        fflush(outfile);
        !          2188:      }
        !          2189: #endif
        !          2190:   }
        !          2191:  if (sharp)
        !          2192:   { flush_sharp_line();
        !          2193:   }
        !          2194: }
        !          2195:
        !          2196: #ifdef DEBUG_IF
        !          2197: void output_ifstate(state)
        !          2198: int state;
        !          2199: {
        !          2200:  switch (state)
        !          2201:   { case IFSTATE_TRUE:
        !          2202:        outputs("TRUE");
        !          2203:        break;
        !          2204:     case IFSTATE_FALSE:
        !          2205:        outputs("FALSE");
        !          2206:        break;
        !          2207:     case IFSTATE_STAYFALSE:
        !          2208:        outputs("STAYFALSE");
        !          2209:        break;
        !          2210:     default:
        !          2211:        outputs("BAD");
        !          2212:        outputd(state);
        !          2213:        break;
        !          2214:   }
        !          2215: }
        !          2216: #endif
        !          2217:
        !          2218: void do_elif(int expr_sharp)
        !          2219: {
        !          2220:  char c;
        !          2221:  char d;
        !          2222:  int e;
        !          2223:
        !          2224: #ifdef DEBUG_IF
        !          2225:  if (debugging)
        !          2226:   { outputc('<');
        !          2227:     outputc(sharp?'#':'@');
        !          2228:     outputs("elif: ");
        !          2229:     fflush(outfile);
        !          2230:   }
        !          2231: #endif
        !          2232:  if (ifstack == 0)
        !          2233:   { err_head();
        !          2234:     fprintf(stderr,"if-less elif converted to normal if\n");
        !          2235:     iffalse();
        !          2236:   }
        !          2237:  if (n_skipped_ifs > 0)
        !          2238:   {
        !          2239: #ifdef DEBUG_IF
        !          2240:     if (debugging)
        !          2241:      { outputs("being skipped, ignoring>");
        !          2242:        fflush(outfile);
        !          2243:      }
        !          2244: #endif
        !          2245:     if (sharp)
        !          2246:      { d = '\0';
        !          2247:        do
        !          2248:   { c = d;
        !          2249:     d = Get();
        !          2250:   } while ((c == '\\') || (d != '\n'));
        !          2251:      }
        !          2252:     return;
        !          2253:   }
        !          2254:  if (! sharp)
        !          2255:   { c = getnonspace();
        !          2256:     if (c != '(')
        !          2257:      { err_head();
        !          2258:        fprintf(stderr,"@elif must have ()s\n");
        !          2259:        Push(c);
        !          2260:        ifstack->condstate = IFSTATE_STAYFALSE;
        !          2261: #ifdef DEBUG_IF
        !          2262:        if (debugging)
        !          2263:   { outputs("forcing STAYFALSE>");
        !          2264:     fflush(outfile);
        !          2265:   }
        !          2266: #endif
        !          2267:        return;
        !          2268:      }
        !          2269:   }
        !          2270:  e = eval_expr(sharp,0);
        !          2271: #ifdef DEBUG_IF
        !          2272:  if (debugging)
        !          2273:   { outputs("expr ");
        !          2274:     outputd(e);
        !          2275:     outputc(' ');
        !          2276:     fflush(outfile);
        !          2277:   }
        !          2278: #endif
        !          2279: #ifdef DEBUG_IF
        !          2280:  if (debugging)
        !          2281:   { outputs(" top ");
        !          2282:     output_ifstate(ifstack->condstate);
        !          2283:     fflush(outfile);
        !          2284:   }
        !          2285: #endif
        !          2286:  switch (ifstack->condstate)
        !          2287:   { case IFSTATE_TRUE:
        !          2288:        ifstack->condstate = IFSTATE_STAYFALSE;
        !          2289:        break;
        !          2290:     case IFSTATE_FALSE:
        !          2291:        if (e)
        !          2292:   { ifstack->condstate = IFSTATE_TRUE;
        !          2293:   }
        !          2294:        break;
        !          2295:   }
        !          2296: #ifdef DEBUG_IF
        !          2297:  if (debugging)
        !          2298:   { outputs(" now ");
        !          2299:     output_ifstate(ifstack->condstate);
        !          2300:     outputc('>');
        !          2301:     fflush(outfile);
        !          2302:   }
        !          2303: #endif
        !          2304: }
        !          2305:
        !          2306: void do_endif(int expr_sharp)
        !          2307: {
        !          2308:  IF *i;
        !          2309:
        !          2310: #ifdef DEBUG_IF
        !          2311:  if (debugging)
        !          2312:   { outputc('<');
        !          2313:     outputc(sharp?'#':'@');
        !          2314:     outputs("endif: ");
        !          2315:     fflush(outfile);
        !          2316:   }
        !          2317: #endif
        !          2318:  if (n_skipped_ifs > 0)
        !          2319:   { n_skipped_ifs --;
        !          2320: #ifdef DEBUG_IF
        !          2321:     if (debugging)
        !          2322:      { outputs("n_skipped -->");
        !          2323:        fflush(outfile);
        !          2324:      }
        !          2325: #endif
        !          2326:   }
        !          2327:  else if (ifstack)
        !          2328:   { i = ifstack->next;
        !          2329:     OLD(ifstack);
        !          2330:     ifstack = i;
        !          2331: #ifdef DEBUG_IF
        !          2332:     if (debugging)
        !          2333:      { outputs("popping stack>");
        !          2334:        fflush(outfile);
        !          2335:      }
        !          2336: #endif
        !          2337:   }
        !          2338:  else
        !          2339:   { err_head();
        !          2340:     fprintf(stderr,"if-less endif\n");
        !          2341: #ifdef DEBUG_IF
        !          2342:     if (debugging)
        !          2343:      { outputc('>');
        !          2344:        fflush(outfile);
        !          2345:      }
        !          2346: #endif
        !          2347:   }
        !          2348:  if (sharp)
        !          2349:   { flush_sharp_line();
        !          2350:   }
        !          2351: }
        !          2352:
        !          2353: void iftrue(void)
        !          2354: {
        !          2355:  IF *i;
        !          2356:
        !          2357:  i = NEW(IF);
        !          2358:  check_malloc(i);
        !          2359:  i->next = ifstack;
        !          2360:  ifstack = i;
        !          2361:  i->condstate = IFSTATE_TRUE;
        !          2362: #ifdef DEBUG_IF
        !          2363:  if (debugging)
        !          2364:   { outputs("IFTRUE");
        !          2365:     fflush(outfile);
        !          2366:   }
        !          2367: #endif
        !          2368: }
        !          2369:
        !          2370: void iffalse(void)
        !          2371: {
        !          2372:  IF *i;
        !          2373:
        !          2374:  i = NEW(IF);
        !          2375:  check_malloc(i);
        !          2376:  i->next = ifstack;
        !          2377:  ifstack = i;
        !          2378:  i->condstate = IFSTATE_FALSE;
        !          2379: #ifdef DEBUG_IF
        !          2380:  if (debugging)
        !          2381:   { outputs("IFFALSE");
        !          2382:     fflush(outfile);
        !          2383:   }
        !          2384: #endif
        !          2385: }
        !          2386:
        !          2387: int in_false_if(void)
        !          2388: {
        !          2389:  return(ifstack && (ifstack->condstate != IFSTATE_TRUE));
        !          2390: }
        !          2391:
        !          2392: void maybe_print(char c)
        !          2393: {
        !          2394:  extern int incldep;
        !          2395:
        !          2396:  if (incldep)
        !          2397:   { return;
        !          2398:   }
        !          2399:  if ((c == '\n') || !in_false_if())
        !          2400:   { outputc(c);
        !          2401:   }
        !          2402: }
        !          2403:
        !          2404: char *Rindex(char *s, int c);
        !          2405:
        !          2406: int nIfiles;
        !          2407: char **Ifiles;
        !          2408:
        !          2409: void init_include(void)
        !          2410: {
        !          2411:  nIfiles = 0;
        !          2412:  Ifiles = (char **) malloc(1);
        !          2413:  check_malloc(Ifiles);
        !          2414: }
        !          2415:
        !          2416: void Ifile(char *f)
        !          2417: {
        !          2418:  Ifiles = (char **) realloc((char *)Ifiles,(nIfiles+1)*sizeof(char *));
        !          2419:  check_malloc(Ifiles);
        !          2420:  Ifiles[nIfiles] = copyofstr(f);
        !          2421:  check_malloc(Ifiles[nIfiles]);
        !          2422:  nIfiles ++;
        !          2423: }
        !          2424:
        !          2425: void do_include(int expr_sharp)
        !          2426: {
        !          2427:  char c;
        !          2428:  char *acc;
        !          2429:
        !          2430:  if (in_false_if())
        !          2431:   { if (sharp)
        !          2432:      { flush_sharp_line();
        !          2433:      }
        !          2434:     return;
        !          2435:   }
        !          2436:  while (1)
        !          2437:   { c = getnonspace();
        !          2438:     if (isbsymchar(c))
        !          2439:      { char *cp;
        !          2440:        DEF *d;
        !          2441:        cp = init_accum();
        !          2442:        while (issymchar(c))
        !          2443:   { accum_char(cp,c);
        !          2444:     c = Get();
        !          2445:   }
        !          2446:        Push(c);
        !          2447:        cp = accum_result(cp);
        !          2448:        d = find_def(cp);
        !          2449:        if (d)
        !          2450:   { expand_def(d);
        !          2451:     n_hits ++;
        !          2452:   }
        !          2453:        else
        !          2454:   { char *dp;
        !          2455:     for (dp=cp+strlen(cp);dp>cp;dp--) Push(*dp);
        !          2456:     n_misses ++;
        !          2457:   }
        !          2458:      }
        !          2459:     else
        !          2460:      { break;
        !          2461:      }
        !          2462:   }
        !          2463:  acc = init_accum();
        !          2464:  if (c == '"')
        !          2465:   { while (1)
        !          2466:      { c = Get();
        !          2467:        if (c == '\n')
        !          2468:   { Push('\n');
        !          2469:     c = '"';
        !          2470:     err_head();
        !          2471:     fprintf(stderr,"warning: unterminated %cinclude filename\n",
        !          2472:               sharp?'#':'@');
        !          2473:   }
        !          2474:        if (c == '"')
        !          2475:   { break;
        !          2476:   }
        !          2477:        accum_char(acc,c);
        !          2478:      }
        !          2479:     if (sharp)
        !          2480:      { flush_sharp_line();
        !          2481:      }
        !          2482:     read_include_file(accum_result(acc),1,sharp);
        !          2483:   }
        !          2484:  else if (c == '<')
        !          2485:   { while (1)
        !          2486:      { c = Get();
        !          2487:        if (c == '\n')
        !          2488:   { Push('\n');
        !          2489:     c = '>';
        !          2490:     err_head();
        !          2491:     fprintf(stderr,"warning: unterminated %cinclude filename\n",
        !          2492:               sharp?'#':'@');
        !          2493:   }
        !          2494:        if (c == '>')
        !          2495:   { break;
        !          2496:   }
        !          2497:        accum_char(acc,c);
        !          2498:      }
        !          2499:     if (sharp)
        !          2500:      { flush_sharp_line();
        !          2501:      }
        !          2502:     read_include_file(accum_result(acc),0,sharp);
        !          2503:   }
        !          2504:  else
        !          2505:   { free(accum_result(acc));
        !          2506:     err_head();
        !          2507:     fprintf(stderr,"illegal %cinclude filename delimiter\n",sharp?'#':'@');
        !          2508:   }
        !          2509: }
        !          2510:
        !          2511: #if  defined(SYSV)
        !          2512: #else
        !          2513: #if defined(DELIM)
        !          2514: #undef DELIM
        !          2515: #endif
        !          2516: #define DELIM '/'
        !          2517: #endif
        !          2518:
        !          2519: #if defined(VISUAL) || defined(__MINGW32__)
        !          2520: #if defined(DELIM)
        !          2521: #undef DELIM
        !          2522: #endif
        !          2523: #define DELIM '\\'
        !          2524: #endif
        !          2525:
        !          2526: void read_include_file(char *name, int dohere, int expr_sharp)
        !          2527: {
        !          2528:  FILE *f;
        !          2529:  char *n;
        !          2530:  char temp[1024];
        !          2531:  char *cp;
        !          2532:  extern int incldep;
        !          2533:  extern char *incldep_o;
        !          2534:
        !          2535:  f = NULL;
        !          2536:  if (dohere)
        !          2537:   { if ((strcmp(curdir(),".") != 0) && (name[0] != DELIM))
        !          2538:      { sprintf(temp,"%s%c%s",curdir(),DELIM,name);
        !          2539:        n = temp;
        !          2540:      }
        !          2541:     else
        !          2542:      { n = name;
        !          2543:      }
        !          2544:     f = fopen(n,"r");
        !          2545:   }
        !          2546:  if (f == NULL)
        !          2547:   { if (name[0] == DELIM)
        !          2548:      { f = fopen(name,"r");
        !          2549:        n = name;
        !          2550:      }
        !          2551:     else
        !          2552:      { int i;
        !          2553:        n = temp;
        !          2554:        for (i=0;i<nIfiles;i++)
        !          2555:   { sprintf(temp,"%s%c%s",Ifiles[i],DELIM,name);
        !          2556:     f = fopen(temp,"r");
        !          2557:     if (f != NULL)
        !          2558:      { break;
        !          2559:      }
        !          2560:   }
        !          2561:      }
        !          2562:   }
        !          2563:  if (f == NULL)
        !          2564:   { err_head();
        !          2565:     fprintf(stderr,"can't find include file %s\n",name);
        !          2566:     free(name);
        !          2567:     return;
        !          2568:   }
        !          2569:  if (incldep)
        !          2570:   { printf("%s: %s\n",incldep_o,n);
        !          2571:   }
        !          2572:  out_at(!sharp,n);
        !          2573:  autodef_file(n);
        !          2574:  autodef_line(1);
        !          2575:  Push('\n');
        !          2576:  Get();
        !          2577:  push_new_file(n,f);
        !          2578:  cp = Rindex(n,DELIM);
        !          2579:  if (cp)
        !          2580:   { *cp = '\0';
        !          2581:     cp = copyofstr(n);
        !          2582:   }
        !          2583:  else
        !          2584:   { cp = copyofstr(".");
        !          2585:   }
        !          2586:  check_malloc(cp);
        !          2587:  *Curdir() = cp;
        !          2588:  free(name);
        !          2589:  return;
        !          2590: }
        !          2591:
        !          2592: /*#define DEBUG_IO/**/
        !          2593: /*#define DEBUG_INCL/**/
        !          2594:
        !          2595: #if defined(DEBUG_IO) || defined(DEBUG_INCL)
        !          2596: extern int debugging;
        !          2597: #endif
        !          2598:
        !          2599: extern int no_line_lines;
        !          2600:
        !          2601: int linefirst;
        !          2602: int willbefirst;
        !          2603: int lineno[MAXFILES];
        !          2604: FILE *fstack[MAXFILES];
        !          2605: int fstackdepth;
        !          2606: char *fn[MAXFILES];
        !          2607: int npushed[MAXFILES];
        !          2608: char pushback[MAXFILES][MAX_PUSHBACK];
        !          2609: char *incldir[MAXFILES];
        !          2610: FILE *outfile;
        !          2611:
        !          2612: char *cur_pushback;
        !          2613: int cur_npushed;
        !          2614: FILE *cur_fstack;
        !          2615: char *cur_fn;
        !          2616: char *cur_incldir;
        !          2617: int cur_lineno;
        !          2618:
        !          2619: typedef struct _mark {
        !          2620:     struct _mark *link;
        !          2621:     char *acc;
        !          2622:     int startdepth;
        !          2623:     int incs[MAXFILES];
        !          2624:     int nincs;
        !          2625:     int nignore; } MARK;
        !          2626:
        !          2627: static MARK *marks;
        !          2628: static int atline;
        !          2629: static char *atfile;
        !          2630: static int done_line;
        !          2631: static int nnls;
        !          2632:
        !          2633: /* XXX these definitions assume no input chars are 81, 82, 83 */
        !          2634: #define NOEXPAND ((char)0x81)
        !          2635: #define MARKLINE ((char)0x82)
        !          2636: #define MARKLEND ((char)0x83)
        !          2637:
        !          2638: void init_io(FILE *f, char *fnname)
        !          2639: {
        !          2640:  register int i;
        !          2641:
        !          2642:  fstackdepth = 0;
        !          2643:  cur_pushback = pushback[0];
        !          2644:  cur_npushed = 0;
        !          2645:  cur_fstack = f;
        !          2646:  cur_fn = copyofstr(fnname);
        !          2647:  check_malloc(cur_fn);
        !          2648:  cur_lineno = 1;
        !          2649:  nnls = 0;
        !          2650:  atfile = copyofstr("");
        !          2651:  check_malloc(atfile);
        !          2652:  for (i=0;i<MAXFILES;i++)
        !          2653:   { npushed[i] = 0;
        !          2654:   }
        !          2655:  marks = 0;
        !          2656: }
        !          2657:
        !          2658: void init_incldir(char *d)
        !          2659: {
        !          2660:  cur_incldir = copyofstr(d);
        !          2661:  check_malloc(cur_incldir);
        !          2662: }
        !          2663:
        !          2664: void change_fstackdepth(int delta)
        !          2665: {
        !          2666:  npushed[fstackdepth] = cur_npushed;
        !          2667:  fstack[fstackdepth] = cur_fstack;
        !          2668:  fn[fstackdepth] = cur_fn;
        !          2669:  incldir[fstackdepth] = cur_incldir;
        !          2670:  lineno[fstackdepth] = cur_lineno;
        !          2671:  fstackdepth += delta;
        !          2672:  cur_pushback = pushback[fstackdepth];
        !          2673:  cur_npushed = npushed[fstackdepth];
        !          2674:  cur_fstack = fstack[fstackdepth];
        !          2675:  cur_fn = fn[fstackdepth];
        !          2676:  cur_incldir = incldir[fstackdepth];
        !          2677:  cur_lineno = lineno[fstackdepth];
        !          2678: }
        !          2679:
        !          2680: #define GET() (cur_pushback[--cur_npushed])
        !          2681: #define PUSH() (cur_pushback[cur_npushed++])
        !          2682:
        !          2683: char Get(void)
        !          2684: {
        !          2685:  char c;
        !          2686:
        !          2687:  linefirst = willbefirst;
        !          2688:  willbefirst = 0;
        !          2689:  while (1)
        !          2690:   { if (cur_npushed > 0)
        !          2691:      { do
        !          2692:   { c = GET();
        !          2693:   } while (c == NOEXPAND);
        !          2694:        if (c == MARKLINE)
        !          2695:   { mark_get_line();
        !          2696:     continue;
        !          2697:   }
        !          2698:        mark_got_from_pushback(c);
        !          2699: #ifdef DEBUG_IO
        !          2700:        if (debugging)
        !          2701:   { outputc('(');
        !          2702:     outputs(unctrl(c));
        !          2703:     outputc(')');
        !          2704:     fflush(outfile);
        !          2705:   }
        !          2706: #endif
        !          2707:        break;
        !          2708:      }
        !          2709:     else
        !          2710:      { c = getc(cur_fstack);
        !          2711:        if (feof(cur_fstack))
        !          2712:   { if (fstackdepth > 0)
        !          2713:      {
        !          2714: #ifdef DEBUG_INCL
        !          2715:        if (debugging)
        !          2716:         { outputs("--eof:");
        !          2717:     outputs(cur_fn);
        !          2718:     outputs("--");
        !          2719:         }
        !          2720: #endif
        !          2721:        fclose(cur_fstack);
        !          2722:        free(cur_fn);
        !          2723:        free(cur_incldir);
        !          2724:        change_fstackdepth(-1);
        !          2725:        mark_file_ending();
        !          2726:        out_at(cur_lineno,cur_fn);
        !          2727:        autodef_file(curfile());
        !          2728:        autodef_line(curline());
        !          2729:        continue;
        !          2730:      }
        !          2731:     else
        !          2732:      { flush_final_nl();
        !          2733:        save_stats();
        !          2734: #if 0
        !          2735:        exit(0);
        !          2736: #endif
        !          2737:        longjmp(cpp_env,1);
        !          2738:      }
        !          2739:   }
        !          2740:        mark_got_from_file(c);
        !          2741: #ifdef DEBUG_IO
        !          2742:        if (debugging)
        !          2743:   { outputc('<');
        !          2744:     outputs(unctrl(c));
        !          2745:     outputc('>');
        !          2746:     fflush(outfile);
        !          2747:   }
        !          2748: #endif
        !          2749:        break;
        !          2750:      }
        !          2751:   }
        !          2752:  if (c == '\n')
        !          2753:   { cur_lineno ++;
        !          2754:     autodef_line(curline());
        !          2755:     willbefirst = 1;
        !          2756:   }
        !          2757:  return(c);
        !          2758: }
        !          2759:
        !          2760: void push_new_file(char *name, FILE *f)
        !          2761: {
        !          2762:  change_fstackdepth(1);
        !          2763:  cur_fn = copyofstr(name);
        !          2764:  check_malloc(cur_fn);
        !          2765:  cur_lineno = 1;
        !          2766:  cur_fstack = f;
        !          2767:  cur_npushed = 0;
        !          2768: #ifdef DEBUG_INCL
        !          2769:  if (debugging)
        !          2770:   { outputs("--newfile:");
        !          2771:     outputs(name);
        !          2772:     outputs("--");
        !          2773:   }
        !          2774: #endif
        !          2775:  mark_file_beginning();
        !          2776: }
        !          2777:
        !          2778: void Push(char c)
        !          2779: {
        !          2780:  if (cur_npushed > MAX_PUSHBACK)
        !          2781:   { fprintf(stderr,"too much pushback\n");
        !          2782:     cur_npushed = 0;
        !          2783:   }
        !          2784:  PUSH() = c;
        !          2785:  mark_charpushed();
        !          2786:  willbefirst = 0;
        !          2787:  if (c == '\n')
        !          2788:   { cur_lineno --;
        !          2789:     autodef_line(curline());
        !          2790:   }
        !          2791: #ifdef DEBUG_IO
        !          2792:  if (debugging)
        !          2793:   { outputc('[');
        !          2794:     outputs(unctrl(c));
        !          2795:     outputc(']');
        !          2796:     fflush(outfile);
        !          2797:   }
        !          2798: #endif
        !          2799: }
        !          2800:
        !          2801: char *curfile(void)
        !          2802: {
        !          2803:  return(cur_fn);
        !          2804: }
        !          2805:
        !          2806: char **Curfile(void)
        !          2807: {
        !          2808:  return(&cur_fn);
        !          2809: }
        !          2810:
        !          2811: int curline(void)
        !          2812: {
        !          2813:  return(cur_lineno);
        !          2814: }
        !          2815:
        !          2816: int *Curline(void)
        !          2817: {
        !          2818:  return(&cur_lineno);
        !          2819: }
        !          2820:
        !          2821: char *curdir(void)
        !          2822: {
        !          2823:  return(cur_incldir);
        !          2824: }
        !          2825:
        !          2826: char **Curdir(void)
        !          2827: {
        !          2828:  return(&cur_incldir);
        !          2829: }
        !          2830:
        !          2831: char getnonspace(void)
        !          2832: {
        !          2833:  char c;
        !          2834:
        !          2835:  while (isspace(c=Get())) ;
        !          2836:  return(c);
        !          2837: }
        !          2838:
        !          2839: char getnonhspace(void)
        !          2840: {
        !          2841:  char c;
        !          2842:
        !          2843:  while (ishspace(c=Get())) ;
        !          2844:  return(c);
        !          2845: }
        !          2846:
        !          2847: char getnhsexpand(void)
        !          2848: {
        !          2849:  char c;
        !          2850:
        !          2851:  while (1)
        !          2852:   { c = getexpand();
        !          2853:     if (ishspace(c))
        !          2854:      { continue;
        !          2855:      }
        !          2856:     if (expr_sharp && (c == '\\'))
        !          2857:      { c = Get();
        !          2858:        if (c == '\n')
        !          2859:   { continue;
        !          2860:   }
        !          2861:        else
        !          2862:   { Push(c);
        !          2863:     c = '\\';
        !          2864:   }
        !          2865:      }
        !          2866:     break;
        !          2867:   }
        !          2868:  return(c);
        !          2869: }
        !          2870:
        !          2871: char getexpand(void)
        !          2872: {
        !          2873:  char c;
        !          2874:  char *str;
        !          2875:  DEF *d;
        !          2876:
        !          2877:  while (1)
        !          2878:   { c = Get();
        !          2879:     if (c == '/')
        !          2880:      { char d;
        !          2881:        d = Get();
        !          2882:        if (d == '*')
        !          2883:   { d = '\0';
        !          2884:     do
        !          2885:      { c = d;
        !          2886:        d = Get();
        !          2887:      } while ((c != '*') || (d != '/'));
        !          2888:     continue;
        !          2889:   }
        !          2890:        else
        !          2891:   { Push(d);
        !          2892:     return('/');
        !          2893:   }
        !          2894:      }
        !          2895:     else if (c == NOEXPAND)
        !          2896:      { c = Get();
        !          2897:        if (issymchar(c))
        !          2898:   { Push(NOEXPAND);
        !          2899:   }
        !          2900:        return(c);
        !          2901:      }
        !          2902:     else if (! isbsymchar(c))
        !          2903:      {
        !          2904:        return(c);
        !          2905:      }
        !          2906:     str = init_accum();
        !          2907:     do
        !          2908:      { accum_char(str,c);
        !          2909:      } while (issymchar(c=Get()));
        !          2910:     Push(c);
        !          2911:     str = accum_result(str);
        !          2912:     if (d = find_def(str))
        !          2913:      { expand_def(d);
        !          2914:        free(str);
        !          2915:      }
        !          2916:     else
        !          2917:      { int i;
        !          2918:        for (i=strlen(str)-1;i>0;i--)
        !          2919:   { Push(str[i]);
        !          2920:   }
        !          2921:        Push(NOEXPAND);
        !          2922:        c = str[0];
        !          2923:        free(str);
        !          2924:        return(c);
        !          2925:      }
        !          2926:   }
        !          2927: }
        !          2928:
        !          2929: char *read_ctrl(void)
        !          2930: {
        !          2931:  char c;
        !          2932:  char *acc;
        !          2933:
        !          2934:  acc = init_accum();
        !          2935:  while (ishspace(c=Get())) ;
        !          2936:  Push(c);
        !          2937:  while (1)
        !          2938:   { c = Get();
        !          2939:     if (islower(c))
        !          2940:      { accum_char(acc,c);
        !          2941:      }
        !          2942:     else
        !          2943:      { Push(c);
        !          2944:        return(accum_result(acc));
        !          2945:      }
        !          2946:   }
        !          2947: }
        !          2948:
        !          2949: char *read_ident(void)
        !          2950: {
        !          2951:  char *acc;
        !          2952:  char c;
        !          2953:
        !          2954:  c = getnonspace();
        !          2955:  if (! isbsymchar(c))
        !          2956:   { Push(c);
        !          2957:     return(0);
        !          2958:   }
        !          2959:  acc = init_accum();
        !          2960:  do
        !          2961:   { accum_char(acc,c);
        !          2962:   } while (issymchar(c=Get()));
        !          2963:  Push(c);
        !          2964:  return(accum_result(acc));
        !          2965: }
        !          2966:
        !          2967: void out_at(int line, char *file)
        !          2968: {
        !          2969:  if ((line-nnls != atline) || strcmp(file,atfile))
        !          2970:   { free(atfile);
        !          2971:     atline = line - nnls;
        !          2972:     atfile = copyofstr(file);
        !          2973:     check_malloc(atfile);
        !          2974:     done_line = 0;
        !          2975:   }
        !          2976: }
        !          2977:
        !          2978: void outputc(char c)
        !          2979: {
        !          2980:  extern int incldep;
        !          2981:  static char *white = 0;
        !          2982:
        !          2983:  if (incldep)
        !          2984:   { return;
        !          2985:   }
        !          2986:  if (c == '\n')
        !          2987:   { nnls ++;
        !          2988:     if (white)
        !          2989:      { free(accum_result(white));
        !          2990:        white = 0;
        !          2991:      }
        !          2992:   }
        !          2993:  else if ((nnls > 0) && ((c == ' ') || (c == '\t')))
        !          2994:   { if (! white)
        !          2995:      { white = init_accum();
        !          2996:      }
        !          2997:     accum_char(white,c);
        !          2998:   }
        !          2999:  else
        !          3000:   { if ((nnls > 2) || !done_line)
        !          3001:      { atline += nnls;
        !          3002:        nnls = 0;
        !          3003:        if (no_line_lines)
        !          3004:   { fprintf(outfile,"\n");
        !          3005:   }
        !          3006:        else
        !          3007:   { fprintf(outfile,"\n# %d \"%s\"\n",atline,atfile);
        !          3008:   }
        !          3009:        done_line = 1;
        !          3010:      }
        !          3011:     for (;nnls;nnls--)
        !          3012:      { atline ++;
        !          3013:        putc('\n',outfile);
        !          3014:      }
        !          3015:     if (white)
        !          3016:      { white = accum_result(white);
        !          3017:        fputs(white,outfile);
        !          3018:        free(white);
        !          3019:        white = 0;
        !          3020:      }
        !          3021:     putc(c,outfile);
        !          3022:   }
        !          3023: }
        !          3024:
        !          3025: void flush_final_nl(void)
        !          3026: {
        !          3027:  if (nnls > 0)
        !          3028:   { putc('\n',outfile);
        !          3029:   }
        !          3030: }
        !          3031:
        !          3032: void outputs(char *s)
        !          3033: {
        !          3034:  for (;*s;s++)
        !          3035:   { outputc(*s);
        !          3036:   }
        !          3037: }
        !          3038:
        !          3039: void outputd(int n)
        !          3040: {
        !          3041:  char temp[64];
        !          3042:
        !          3043:  sprintf(temp,"%d",n);
        !          3044:  outputs(temp);
        !          3045: }
        !          3046:
        !          3047: void mark_push_here(MARK *,int,char *);
        !          3048:
        !          3049: void input_mark(void)
        !          3050: {
        !          3051:  MARK *m;
        !          3052:
        !          3053:  m = NEW(MARK);
        !          3054:  check_malloc(m);
        !          3055:  m->link = marks;
        !          3056:  marks = m;
        !          3057:  m->startdepth = fstackdepth;
        !          3058:  m->acc = init_accum();
        !          3059:  m->nignore = 0;
        !          3060:  m->nincs = 0;
        !          3061:  mark_push_here(m,curline(),curfile());
        !          3062: #ifdef DEBUG_IO
        !          3063:  if (debugging)
        !          3064:   { outputs("~MARK~");
        !          3065:   }
        !          3066: #endif
        !          3067: }
        !          3068:
        !          3069: void input_unmark(void)
        !          3070: {
        !          3071:  MARK *m;
        !          3072:
        !          3073:  if (marks)
        !          3074:   { m = marks;
        !          3075:     marks = m->link;
        !          3076:     free(accum_result(m->acc));
        !          3077:     OLD(m);
        !          3078: #ifdef DEBUG_IO
        !          3079:     if (debugging)
        !          3080:      { outputs("~UNMARK~");
        !          3081:      }
        !          3082: #endif
        !          3083:   }
        !          3084: }
        !          3085:
        !          3086: void input_recover(void)
        !          3087: {
        !          3088:  register MARK *m;
        !          3089:  register char *txt;
        !          3090:  register int i;
        !          3091:  register int l;
        !          3092:  char c;
        !          3093:
        !          3094:  if (marks)
        !          3095:   { m = marks;
        !          3096:     marks = m->link;
        !          3097: #ifdef DEBUG_IO
        !          3098:     if (debugging)
        !          3099:      { outputs("~RECOVER~");
        !          3100:      }
        !          3101: #endif
        !          3102:     for (;m->nignore>0;m->nignore--)
        !          3103:      { accum_regret(m->acc);
        !          3104:      }
        !          3105:     txt = accum_result(m->acc);
        !          3106:     i = strlen(txt) - 1;
        !          3107:     while (m->nincs > 0)
        !          3108:      { l = m->incs[--m->nincs];
        !          3109:        for (;i>=l;i--)
        !          3110:   { Push(txt[i]);
        !          3111:   }
        !          3112:        Push(MARKLEND);
        !          3113:        c = txt[i];
        !          3114:        for (i--;txt[i]!=c;i--)
        !          3115:   { Push(txt[i]);
        !          3116:   }
        !          3117:        Push('A');
        !          3118:        Push('@');
        !          3119:        Push('@');
        !          3120:        Push('@');
        !          3121:        Push('@');
        !          3122:        Push('@');
        !          3123:        Push('@');
        !          3124:        Push('@');
        !          3125:        for (;(txt[i]!='#')&&(txt[i]!='@');i--) ;
        !          3126:        Push(MARKLINE);
        !          3127:        i --;
        !          3128:      }
        !          3129:     for (;i>=0;i--)
        !          3130:      { Push(txt[i]);
        !          3131:      }
        !          3132:     free(txt);
        !          3133:     OLD(m);
        !          3134:   }
        !          3135: }
        !          3136:
        !          3137: void mark_file_beginning(void)
        !          3138: {
        !          3139:  register MARK *m;
        !          3140:
        !          3141:  for (m=marks;m;m=m->link)
        !          3142:   { m->incs[m->nincs++] = accum_howfar(m->acc);
        !          3143:   }
        !          3144: }
        !          3145:
        !          3146: void mark_file_ending(void)
        !          3147: {
        !          3148:  register MARK *m;
        !          3149:  register int i;
        !          3150:  register int to;
        !          3151:  register char *acc;
        !          3152:
        !          3153:  for (m=marks;m;m=m->link)
        !          3154:   { if (m->startdepth > fstackdepth)
        !          3155:      { m->startdepth = fstackdepth;
        !          3156:        mark_push_here(m,curline(),curfile());
        !          3157:      }
        !          3158:     else if (m->nincs <= 0)
        !          3159:      { fprintf(stderr,"INTERNAL BUG: nincs<0 in mark_file_ending\n");
        !          3160:        abort();
        !          3161:      }
        !          3162:     else
        !          3163:      { to = m->incs[--m->nincs];
        !          3164:        acc = m->acc;
        !          3165:        for (i=accum_howfar(acc);i>to;i--)
        !          3166:   { accum_regret(acc);
        !          3167:   }
        !          3168:      }
        !          3169:   }
        !          3170: }
        !          3171:
        !          3172: void mark_charpushed(void)
        !          3173: {
        !          3174:  register MARK *m;
        !          3175:
        !          3176:  for (m=marks;m;m=m->link)
        !          3177:   { m->nignore ++;
        !          3178:   }
        !          3179: }
        !          3180:
        !          3181: void mark_got_from_pushback(char c)
        !          3182: {
        !          3183:  mark_got(c);
        !          3184: }
        !          3185:
        !          3186: void mark_got_from_file(char c)
        !          3187: {
        !          3188:  mark_got(c);
        !          3189: }
        !          3190:
        !          3191: void mark_got(char c)
        !          3192: {
        !          3193:  register MARK *m;
        !          3194:
        !          3195:  for (m=marks;m;m=m->link)
        !          3196:   { if (m->nignore > 0)
        !          3197:      { m->nignore --;
        !          3198:      }
        !          3199:     else
        !          3200:      { accum_char(m->acc,c);
        !          3201:      }
        !          3202:   }
        !          3203: }
        !          3204:
        !          3205: void mark_push_here(MARK *m, int l, char *f)
        !          3206: {
        !          3207:  int i;
        !          3208:  char c;
        !          3209:
        !          3210:  switch (c=accum_regret(m->acc))
        !          3211:   { case 0:
        !          3212:        break;
        !          3213:     case MARKLEND:
        !          3214:        while (accum_regret(m->acc) != MARKLINE) ;
        !          3215:        break;
        !          3216:     default:
        !          3217:        accum_char(m->acc,c);
        !          3218:        break;
        !          3219:   }
        !          3220:  accum_char(m->acc,MARKLINE);
        !          3221:  for (i=28;i>=0;i-=4)
        !          3222:   { accum_char(m->acc,(char)('@'+((l>>i)&0xf)));
        !          3223:   }
        !          3224:  for (;*f;f++)
        !          3225:   { accum_char(m->acc,*f);
        !          3226:   }
        !          3227:  accum_char(m->acc,MARKLEND);
        !          3228: }
        !          3229:
        !          3230: void mark_get_line(void)
        !          3231: {
        !          3232:  int l;
        !          3233:  char *f;
        !          3234:  int i;
        !          3235:  char c;
        !          3236:  MARK *m;
        !          3237:
        !          3238:  l = 0;
        !          3239:  for (i=0;i<8;i++)
        !          3240:   { l = (l << 4) + (GET() & 0xf);
        !          3241:   }
        !          3242:  f = init_accum();
        !          3243:  while ((c=GET()) != MARKLEND)
        !          3244:   { accum_char(f,c);
        !          3245:   }
        !          3246:  f = accum_result(f);
        !          3247:  out_at(l,f);
        !          3248:  for (m=marks;m;m=m->link)
        !          3249:   { mark_push_here(m,l,f);
        !          3250:   }
        !          3251:  free(f);
        !          3252: }
        !          3253:
        !          3254: int ishspace(char c)
        !          3255: {
        !          3256:  return((c == ' ') || (c == '\t'));
        !          3257: }
        !          3258:
        !          3259: int isbsymchar(char c)
        !          3260: {
        !          3261:  return(isalpha(c) || (c == '_'));
        !          3262: }
        !          3263:
        !          3264: int issymchar(char c)
        !          3265: {
        !          3266:  return(isalnum(c) || (c == '_') || (c == '$'));
        !          3267: }
        !          3268:
        !          3269: void do_line(void)
        !          3270: {
        !          3271:  char c;
        !          3272:
        !          3273:  outputc('#');
        !          3274:  while ((c=Get()) != '\n')
        !          3275:   { outputc(c);
        !          3276:   }
        !          3277: }
        !          3278:
        !          3279: #define DEBUG_MAIN/**/
        !          3280:
        !          3281: extern char **argvec;
        !          3282:
        !          3283: char *Index(char *s, int c);
        !          3284: char *Rindex(char *s, int c);
        !          3285:
        !          3286: #ifdef DEBUG_MAIN
        !          3287: extern int debugging;
        !          3288: #endif
        !          3289:
        !          3290: static char quote;
        !          3291:
        !          3292: IF *ifstack;
        !          3293: int n_skipped_ifs;
        !          3294:
        !          3295: int keep_comments;
        !          3296: int no_line_lines;
        !          3297: int incldep;
        !          3298: char *incldep_o;
        !          3299: int do_at_ctrls;
        !          3300: extern char *predefs[];
        !          3301:
        !          3302: #if defined(SYSV)
        !          3303: void main(ac,av)
        !          3304: #else
        !          3305: void cpp_main(int ac, char **av)
        !          3306: #endif
        !          3307: {
        !          3308:  int argno;
        !          3309:  int rest;
        !          3310:  char *cp;
        !          3311:  static FILE *inf;
        !          3312:  static FILE *outf;
        !          3313:  char *inname;
        !          3314:  int backslash;
        !          3315:  int i;
        !          3316:
        !          3317:  if ( setjmp(cpp_env) ) {
        !          3318:    if ( inf != stdin )
        !          3319:      fclose(inf);
        !          3320:    if ( outf == stdout )
        !          3321:      fflush(outf);
        !          3322:    else
        !          3323:      fclose(outf);
        !          3324:    return;
        !          3325:  }
        !          3326:
        !          3327:  init_symtbl();
        !          3328: #define predef(str) ( (cp=copyofstr("1")), \
        !          3329:           check_malloc(cp), \
        !          3330:           define((str),-1,(unsigned char *)cp,DEF_PREDEF) )
        !          3331:  for (i=0;predefs[i];i++)
        !          3332:   { predef(predefs[i]);
        !          3333:   }
        !          3334:  init_include();
        !          3335:  inf = stdin;
        !          3336:  outf = stdout;
        !          3337:  inname = "";
        !          3338:  keep_comments = 0;
        !          3339:  no_line_lines = 0;
        !          3340:  do_at_ctrls = 0;
        !          3341:  incldep = 0;
        !          3342:  argno = 0;
        !          3343:  for (ac--,av++;ac;ac--,av++)
        !          3344:   { if (**av == '-')
        !          3345:      { rest = 0;
        !          3346:        if (!strcmp(*av,"-undef"))
        !          3347:   { undef_predefs();
        !          3348:   }
        !          3349:        else
        !          3350:   { for (++*av;(**av)&&!rest;++*av)
        !          3351:      { switch (**av)
        !          3352:         { case 'C':
        !          3353:        keep_comments = 1;
        !          3354:        break;
        !          3355:     case 'D':
        !          3356:        rest = 1;
        !          3357:        ++*av;
        !          3358:        if (strcmp(*av,"@") == 0)
        !          3359:         { do_at_ctrls = 1;
        !          3360:         }
        !          3361:        else
        !          3362:         { cp = Index(*av,'=');
        !          3363:           if (cp)
        !          3364:            { if (cp != *av)
        !          3365:         { char *dp;
        !          3366:           *cp++ = '\0';
        !          3367:           dp = copyofstr(cp);
        !          3368:           check_malloc(dp);
        !          3369:           define(*av,-1,(unsigned char *)dp,DEF_CMDLINE);
        !          3370:         }
        !          3371:        else
        !          3372:         { fprintf(stderr,"Must give a name for -D\n");
        !          3373:         }
        !          3374:            }
        !          3375:           else
        !          3376:            { char *dp;
        !          3377:        dp = copyofstr("1");
        !          3378:        check_malloc(dp);
        !          3379:        define(*av,-1,(unsigned char *)dp,DEF_CMDLINE);
        !          3380:            }
        !          3381:         }
        !          3382:        break;
        !          3383:     case 'E':
        !          3384:        break;
        !          3385:     case 'I':
        !          3386:        rest = 1;
        !          3387:        ++*av;
        !          3388:        if (**av)
        !          3389:         { Ifile(*av);
        !          3390:         }
        !          3391:        else
        !          3392:         { fprintf(stderr,"Must give a directory name for -I\n");
        !          3393:         }
        !          3394:        break;
        !          3395:     case 'M':
        !          3396:        incldep = 1;
        !          3397:        break;
        !          3398:     case 'P':
        !          3399:        no_line_lines = 1;
        !          3400:        break;
        !          3401:     case 'R':
        !          3402:        break;
        !          3403:     case 'U':
        !          3404:        rest = 1;
        !          3405:        ++*av;
        !          3406:        if (**av)
        !          3407:         { undef(*av);
        !          3408:         }
        !          3409:        else
        !          3410:         { fprintf(stderr,"Must give a name for -U\n");
        !          3411:         }
        !          3412:        break;
        !          3413:     default:
        !          3414:        fprintf(stderr,"Unknown flag -%c\n",**av);
        !          3415:        break;
        !          3416:         }
        !          3417:      }
        !          3418:   }
        !          3419:      }
        !          3420:     else
        !          3421:      { switch (argno++)
        !          3422:   { case 0:
        !          3423:        if (strcmp(*av,"-") != 0)
        !          3424:         { FILE *f;
        !          3425:     f = fopen(*av,"r");
        !          3426:     if (f == NULL)
        !          3427:      { fprintf(stderr,"Cannot open source file %s\n",*av);
        !          3428:      }
        !          3429:     else
        !          3430:      { inf = f;
        !          3431:        inname = *av;
        !          3432:      }
        !          3433:         }
        !          3434:        break;
        !          3435:     case 1:
        !          3436:        if (strcmp(*av,"-") != 0)
        !          3437:         { FILE *f;
        !          3438:     f = fopen(*av,"w");
        !          3439:     if (f == NULL)
        !          3440:      { fprintf(stderr,"Can't create %s\n",*av);
        !          3441:      }
        !          3442:     else
        !          3443:      { outf = f;
        !          3444:      }
        !          3445:         }
        !          3446:        break;
        !          3447:     default:
        !          3448:        fprintf(stderr,"Extra name %s ignored\n",*av);
        !          3449:        break;
        !          3450:   }
        !          3451:      }
        !          3452:   }
        !          3453:  if (incldep && !inname[0])
        !          3454:   { fprintf(stderr,"No input file for -M flag\n");
        !          3455: #if 0
        !          3456:     exit(1);
        !          3457: #endif
        !          3458:   longjmp(cpp_env,1);
        !          3459:   }
        !          3460:  if (do_at_ctrls)
        !          3461:   { predef("at_sign_ctrls");
        !          3462:   }
        !          3463:  Ifile("/local/include");
        !          3464:  Ifile("/usr/include");
        !          3465:  willbefirst = 1;
        !          3466:  quote = 0;
        !          3467:  backslash = 0;
        !          3468:  init_io(inf,inname);
        !          3469:  outfile = outf;
        !          3470:  ifstack = 0;
        !          3471:  n_skipped_ifs = 0;
        !          3472:  cp = Rindex(inname,'/');
        !          3473:  if (cp)
        !          3474:   { *cp = '\0';
        !          3475:     init_incldir(inname);
        !          3476:     *cp = '/';
        !          3477:   }
        !          3478:  else
        !          3479:   { init_incldir(".");
        !          3480:   }
        !          3481:  autodef_file(inname);
        !          3482:  autodef_line(1);
        !          3483:  out_at(1,inname);
        !          3484:  if (incldep)
        !          3485:   { char *dp;
        !          3486:     cp = Rindex(inname,'/');
        !          3487:     if (cp)
        !          3488:      { cp ++;
        !          3489:      }
        !          3490:     else
        !          3491:      { cp = inname;
        !          3492:      }
        !          3493:     dp = cp + strlen(cp) - 2;
        !          3494:     if ((dp < cp) || strcmp(dp,".c"))
        !          3495:      { fprintf(stderr,"Missing .c in %s\n",inname);
        !          3496: #if 0
        !          3497:        exit(1);
        !          3498: #endif
        !          3499:        longjmp(cpp_env,1);
        !          3500:      }
        !          3501:     incldep_o = copyofstr(cp);
        !          3502:     incldep_o[dp+1-cp] = 'o';
        !          3503:     fprintf(outfile,"%s: ",incldep_o);
        !          3504:     fprintf(outfile,"%s\n",inname);
        !          3505:   }
        !          3506:  init_stats();
        !          3507:  while (1)
        !          3508:   { char c;
        !          3509:     int haddigit;
        !          3510:     c = Get();
        !          3511:     if (backslash)
        !          3512:      { maybe_print(c);
        !          3513:        backslash = 0;
        !          3514:        continue;
        !          3515:      }
        !          3516:     if (!incldep && (isdigit(c) || (c == '.')))
        !          3517:      { haddigit = 0;
        !          3518:        while (isdigit(c) || (c == '.'))
        !          3519:   { haddigit |= isdigit(c);
        !          3520:     maybe_print(c);
        !          3521:     c = Get();
        !          3522:   }
        !          3523:        if (haddigit && ((c == 'e') || (c == 'E')))
        !          3524:   { maybe_print(c);
        !          3525:     c = Get();
        !          3526:     while (isdigit(c))
        !          3527:      { maybe_print(c);
        !          3528:        c = Get();
        !          3529:      }
        !          3530:   }
        !          3531:        Push(c);
        !          3532:        continue;
        !          3533:      }
        !          3534:     if (quote)
        !          3535:      { if (c == '\\')
        !          3536:   { maybe_print(c);
        !          3537:     backslash = 1;
        !          3538:     continue;
        !          3539:   }
        !          3540:        else if ((c == quote) || (c == '\n'))
        !          3541:   { maybe_print(c);
        !          3542:     quote = 0;
        !          3543:     continue;
        !          3544:   }
        !          3545:        else
        !          3546:   { maybe_print(c);
        !          3547:     continue;
        !          3548:   }
        !          3549:      }
        !          3550:     if (c == '\\') /* this weirdness is Reiser semantics.... */
        !          3551:      { backslash = 1;
        !          3552:        maybe_print(c);
        !          3553:        continue;
        !          3554:      }
        !          3555:     if ((c == '\'') || (c == '"'))
        !          3556:      { quote = c;
        !          3557:        maybe_print(c);
        !          3558:      }
        !          3559:     else if (linefirst && (c == '#'))
        !          3560:      { do_sharp();
        !          3561:      }
        !          3562:     else if (do_at_ctrls && (c == '@'))
        !          3563:      { do_at();
        !          3564:      }
        !          3565:     else if (! incldep)
        !          3566:      { if (isbsymchar(c) && !in_false_if())
        !          3567:   { char *cp;
        !          3568:     DEF *d;
        !          3569:     cp = init_accum();
        !          3570:     while (issymchar(c))
        !          3571:      { accum_char(cp,c);
        !          3572:        c = Get();
        !          3573:      }
        !          3574:     Push(c);
        !          3575:     cp = accum_result(cp);
        !          3576: #ifdef DEBUG_MAIN
        !          3577:     if (debugging)
        !          3578:      { outputs("<word:");
        !          3579:        outputs(cp);
        !          3580:        outputs(">");
        !          3581:      }
        !          3582: #endif
        !          3583:     d = find_def(cp);
        !          3584:     if (d)
        !          3585:      { expand_def(d);
        !          3586:        n_hits ++;
        !          3587:      }
        !          3588:     else
        !          3589:      { for (;*cp;cp++)
        !          3590:         { maybe_print(*cp);
        !          3591:         }
        !          3592:        n_misses ++;
        !          3593:      }
        !          3594:   }
        !          3595:        else if (c == '/')
        !          3596:   { char d;
        !          3597:     d = Get();
        !          3598:     if (d == '*')
        !          3599:      { d = '\0';
        !          3600:        if (keep_comments)
        !          3601:         { maybe_print('/');
        !          3602:     maybe_print('*');
        !          3603:         }
        !          3604:        do
        !          3605:         { c = d;
        !          3606:     d = Get();
        !          3607:     if ((d == '\n') || keep_comments)
        !          3608:      { maybe_print(d);
        !          3609:      }
        !          3610:         } while ((c != '*') || (d != '/'));
        !          3611:      }
        !          3612:     else
        !          3613:      { Push(d);
        !          3614:        maybe_print(c);
        !          3615:      }
        !          3616:   }
        !          3617:        else
        !          3618:   { maybe_print(c);
        !          3619:   }
        !          3620:      }
        !          3621:   }
        !          3622: }
        !          3623:
        !          3624: void do_pragma(void)
        !          3625: {
        !          3626:  char c;
        !          3627:
        !          3628:  if (in_false_if())
        !          3629:   { while ((c=Get()) != '\n') ;
        !          3630:   }
        !          3631:  else
        !          3632:   { outputc('#');
        !          3633:     outputc('p');
        !          3634:     outputc('r');
        !          3635:     outputc('a');
        !          3636:     outputc('g');
        !          3637:     outputc('m');
        !          3638:     outputc('a');
        !          3639:     outputc(' ');
        !          3640:     while ((c=Get()) != '\n')
        !          3641:      { outputc(c);
        !          3642:      }
        !          3643:   }
        !          3644: }
        !          3645:
        !          3646: char *predefs[] = {
        !          3647:         "mc68000",
        !          3648:         "unix",
        !          3649:         "NeXT",
        !          3650:         "__MACH__",
        !          3651:         0
        !          3652: };
        !          3653:
        !          3654: void do_set(void)
        !          3655: {
        !          3656:  char *mac;
        !          3657:  char c;
        !          3658:  char temp[64];
        !          3659:
        !          3660:  mac = read_ident();
        !          3661:  if (! mac)
        !          3662:   { err_head();
        !          3663:     fprintf(stderr,"@set: missing/illegal macro name\n");
        !          3664:     return;
        !          3665:   }
        !          3666:  if (! in_false_if())
        !          3667:   { char *cp;
        !          3668:     c = getnonspace();
        !          3669:     if (c != '(')
        !          3670:      { err_head();
        !          3671:        fprintf(stderr,"@set must have ()s\n");
        !          3672:        Push(c);
        !          3673:        return;
        !          3674:      }
        !          3675:     sprintf(temp,"%d",eval_expr(0,1));
        !          3676:     undef(mac);
        !          3677:     cp = copyofstr(temp);
        !          3678:     check_malloc(cp);
        !          3679:     define(mac,-1,(unsigned char *)cp,DEF_DEFINE);
        !          3680:   }
        !          3681:  free(mac);
        !          3682: }
        !          3683:
        !          3684: void do_sharp(void)
        !          3685: {
        !          3686:  char *w;
        !          3687:  char c;
        !          3688:
        !          3689:  w = read_ctrl();
        !          3690:  if (strcmp(w,"ifdef") == 0)
        !          3691:   { do_ifdef(1);
        !          3692:   }
        !          3693:  else if (strcmp(w,"ifndef") == 0)
        !          3694:   { do_ifndef(1);
        !          3695:   }
        !          3696:  else if (strcmp(w,"if") == 0)
        !          3697:   { do_if(1);
        !          3698:   }
        !          3699:  else if (strcmp(w,"else") == 0)
        !          3700:   { do_else(1);
        !          3701:   }
        !          3702:  else if (strcmp(w,"elif") == 0)
        !          3703:   { do_elif(1);
        !          3704:   }
        !          3705:  else if (strcmp(w,"endif") == 0)
        !          3706:   { do_endif(1);
        !          3707:   }
        !          3708:  else if (strcmp(w,"include") == 0)
        !          3709:   { do_include(1);
        !          3710:   }
        !          3711:  else if (strcmp(w,"define") == 0)
        !          3712:   { do_define(1,0);
        !          3713:   }
        !          3714:  else if (strcmp(w,"undef") == 0)
        !          3715:   { do_undef(1);
        !          3716:   }
        !          3717:  else if (strcmp(w,"line") == 0)
        !          3718:   { do_line();
        !          3719:   }
        !          3720:  else if (strcmp(w,"pragma") == 0)
        !          3721:   { do_pragma();
        !          3722:   }
        !          3723:  else if (strcmp(w,"") == 0)
        !          3724:   {
        !          3725:   }
        !          3726:  else
        !          3727:   { int isnull;
        !          3728:     isnull = 0;
        !          3729:     if (strcmp(w,"") == 0)
        !          3730:      { c = Get();
        !          3731:        if (c != '\n')
        !          3732:   { Push(c);
        !          3733:   }
        !          3734:        else
        !          3735:   { isnull = 1;
        !          3736:   }
        !          3737:      }
        !          3738:     if (!isnull && !in_false_if())
        !          3739:      { err_head();
        !          3740:        fprintf(stderr,"unknown control `%s'\n",w);
        !          3741:        flush_sharp_line();
        !          3742:      }
        !          3743:   }
        !          3744:  maybe_print('\n');
        !          3745:  free(w);
        !          3746: }
        !          3747:
        !          3748: void flush_sharp_line(void)
        !          3749: {
        !          3750:  int quote;
        !          3751:  int backslash;
        !          3752:  int comment;
        !          3753:  int lastc;
        !          3754:  int c;
        !          3755:
        !          3756:  quote = 0;
        !          3757:  backslash = 0;
        !          3758:  comment = 0;
        !          3759:  c = 'x';
        !          3760:  while (1)
        !          3761:   { lastc = c;
        !          3762:     c = Get();
        !          3763:     if (backslash)
        !          3764:      { backslash = 0;
        !          3765:        continue;
        !          3766:      }
        !          3767:     if (comment)
        !          3768:      { if (c == '\\')
        !          3769:   { backslash = 1;
        !          3770:   }
        !          3771:        else if ((c == '/') && (lastc == '*'))
        !          3772:   { comment = 0;
        !          3773:   }
        !          3774:        continue;
        !          3775:      }
        !          3776:     if (quote)
        !          3777:      { if (c == '\\')
        !          3778:   { backslash = 1;
        !          3779:   }
        !          3780:        else if (c == quote)
        !          3781:   { quote = 0;
        !          3782:   }
        !          3783:      }
        !          3784:     switch (c)
        !          3785:      { case '\\':
        !          3786:     backslash = 1;
        !          3787:     continue;
        !          3788:     break;
        !          3789:        case '"': case '\'':
        !          3790:     quote = c;
        !          3791:     continue;
        !          3792:     break;
        !          3793:        case '*':
        !          3794:     comment = (lastc == '/');
        !          3795:     continue;
        !          3796:     break;
        !          3797:        default:
        !          3798:     continue;
        !          3799:     break;
        !          3800:        case '\n':
        !          3801:     break;
        !          3802:      }
        !          3803:     break;
        !          3804:   }
        !          3805: }
        !          3806:
        !          3807:
        !          3808: int n_defines;
        !          3809: int n_undefines;
        !          3810: int n_hits;
        !          3811: int n_misses;
        !          3812:
        !          3813: void init_stats(void)
        !          3814: {
        !          3815:  n_defines = 0;
        !          3816:  n_undefines = 0;
        !          3817:  n_hits = 0;
        !          3818:  n_misses = 0;
        !          3819: }
        !          3820:
        !          3821: void save_stats(void)
        !          3822: {
        !          3823:  FILE *f;
        !          3824:
        !          3825:  f = fopen("/@larry/u1/mouse/Mouse-C/cpp.stats","a");
        !          3826:  if (f)
        !          3827:   { fprintf(f,"%d def, %d undef, %d hits, %d misses\n",
        !          3828:       n_defines,n_undefines,n_hits,n_misses);
        !          3829:     fclose(f);
        !          3830:   }
        !          3831: }
        !          3832:
        !          3833: DEF **symtbl;
        !          3834: int symtbl_size;
        !          3835: int n_in_table;
        !          3836:
        !          3837: static int size_index;
        !          3838: static int sizes[] = { 7, 37, 179, 719, 2003, 8009, 30011, 120011, 0 };
        !          3839:
        !          3840: static int hash(unsigned char *s)
        !          3841: {
        !          3842:  register unsigned int i;
        !          3843:
        !          3844:  for (i=0;*s;s++)
        !          3845:   { i = (i >> 8) + (i << 3) + *s;
        !          3846:   }
        !          3847:  i &= ~0x80000000;
        !          3848:  return(i%symtbl_size);
        !          3849: }
        !          3850:
        !          3851: void init_symtbl(void)
        !          3852: {
        !          3853:  int i;
        !          3854:
        !          3855:  symtbl_size = sizes[size_index=0];
        !          3856:  symtbl = (DEF **) malloc(symtbl_size*sizeof(DEF *));
        !          3857:  check_malloc(symtbl);
        !          3858:  for (i=0;i<symtbl_size;i++)
        !          3859:   { symtbl[i] = 0;
        !          3860:   }
        !          3861:  n_in_table = 0;
        !          3862: }
        !          3863:
        !          3864: static void rehash_up(void)
        !          3865: {
        !          3866:  int osize;
        !          3867:  DEF **otbl;
        !          3868:  int i;
        !          3869:  DEF *d;
        !          3870:  DEF *n;
        !          3871:  int h;
        !          3872:
        !          3873:  if ((sizes[size_index] == 0) || (sizes[++size_index] == 0))
        !          3874:   { return;
        !          3875:   }
        !          3876:  osize = symtbl_size;
        !          3877:  otbl = symtbl;
        !          3878:  symtbl_size = sizes[size_index];
        !          3879:  symtbl = (DEF **) malloc(symtbl_size*sizeof(DEF *));
        !          3880:  check_malloc(symtbl);
        !          3881:  for (i=0;i<symtbl_size;i++)
        !          3882:   { symtbl[i] = 0;
        !          3883:   }
        !          3884:  for (i=0;i<osize;i++)
        !          3885:   { for (d=otbl[i];d;d=n)
        !          3886:      { n = d->link;
        !          3887:        h = hash((unsigned char *)d->name);
        !          3888:        d->link = symtbl[h];
        !          3889:        symtbl[h] = d;
        !          3890:      }
        !          3891:   }
        !          3892:  free((char *)otbl);
        !          3893: }
        !          3894:
        !          3895: void define(char *name, int nargs, unsigned char *repl, int how)
        !          3896: {
        !          3897:  int h;
        !          3898:  DEF *d;
        !          3899:  char *n;
        !          3900:
        !          3901:  n = copyofstr(name);
        !          3902:  h = hash((unsigned char *)n);
        !          3903:  for (d=symtbl[h];d;d=d->link)
        !          3904:   { if (strcmp(d->name,n) == 0)
        !          3905:      { break;
        !          3906:      }
        !          3907:   }
        !          3908:  if (d)
        !          3909:   { if ( (nargs != d->nargs) || strcmp((char *)repl,(char *)d->repl) )
        !          3910:      { err_head();
        !          3911:        fprintf(stderr,"%s redefined\n",n);
        !          3912:      }
        !          3913:     free((char *)d->repl);
        !          3914:     free(d->name);
        !          3915:     d->name = n;
        !          3916:     d->nargs = nargs;
        !          3917:     d->repl = repl;
        !          3918:     d->how = how;
        !          3919:   }
        !          3920:  else
        !          3921:   { d = NEW(DEF);
        !          3922:     check_malloc(d);
        !          3923:     d->name = n;
        !          3924:     d->nargs = nargs;
        !          3925:     d->repl = repl;
        !          3926:     d->how = how;
        !          3927:     d->link = symtbl[h];
        !          3928:     symtbl[h] = d;
        !          3929:     n_in_table ++;
        !          3930:     if (n_in_table > 2*symtbl_size)
        !          3931:      { rehash_up();
        !          3932:      }
        !          3933:   }
        !          3934:  if (strcmp(n,"at_sign_ctrls") == 0)
        !          3935:   { extern int do_at_ctrls;
        !          3936:     do_at_ctrls = 1;
        !          3937:   }
        !          3938: }
        !          3939:
        !          3940: int undef(char *name)
        !          3941: {
        !          3942:  int h;
        !          3943:  DEF **D;
        !          3944:  DEF *d;
        !          3945:  int rv;
        !          3946:
        !          3947:  h = hash((unsigned char *)name);
        !          3948:  for (D=symtbl+h;*D;D= &(*D)->link)
        !          3949:   { if (strcmp((*D)->name,name) == 0)
        !          3950:      { break;
        !          3951:      }
        !          3952:   }
        !          3953:  rv = 0;
        !          3954:  if (d = *D)
        !          3955:   { *D = d->link;
        !          3956:     free(d->name);
        !          3957:     free((char *)d->repl);
        !          3958:     OLD(d);
        !          3959:     n_in_table --;
        !          3960:     rv = 1;
        !          3961:   }
        !          3962:  if (strcmp(name,"at_sign_ctrls") == 0)
        !          3963:   { extern int do_at_ctrls;
        !          3964:     do_at_ctrls = 0;
        !          3965:   }
        !          3966:   return rv;
        !          3967: }
        !          3968:
        !          3969: DEF *find_def(char *name)
        !          3970: {
        !          3971:  int h;
        !          3972:  DEF *d;
        !          3973:
        !          3974:  h = hash((unsigned char *)name);
        !          3975:  for (d=symtbl[h];d;d=d->link)
        !          3976:   { if (strcmp(d->name,name) == 0)
        !          3977:      { break;
        !          3978:      }
        !          3979:   }
        !          3980:  return(d);
        !          3981: }
        !          3982:
        !          3983: void defd(char *name, int value)
        !          3984: {
        !          3985:  char temp[64];
        !          3986:  char *cp;
        !          3987:
        !          3988:  sprintf(temp,"%d",value);
        !          3989:  undef(name);
        !          3990:  cp = copyofstr(temp);
        !          3991:  check_malloc(cp);
        !          3992:  define(name,-1,(unsigned char *)cp,DEF_DEFINE);
        !          3993: }
        !          3994:
        !          3995: void undef_predefs(void)
        !          3996: {
        !          3997:  int h;
        !          3998:  DEF **D;
        !          3999:  DEF *d;
        !          4000:
        !          4001:  for (h=symtbl_size-1;h>=0;h--)
        !          4002:   { D = symtbl + h;
        !          4003:     while (*D)
        !          4004:      { d = *D;
        !          4005:        if (d->how == DEF_PREDEF)
        !          4006:   { free(d->name);
        !          4007:     free((char *)d->repl);
        !          4008:     *D = d->link;
        !          4009:     OLD(d);
        !          4010:     n_in_table --;
        !          4011:   }
        !          4012:        else
        !          4013:   { D = &d->link;
        !          4014:   }
        !          4015:      }
        !          4016:   }
        !          4017: }
        !          4018:
        !          4019: char *_unctrl[0400] = { "^@",
        !          4020:       "^A",
        !          4021:       "^B",
        !          4022:       "^C",
        !          4023:       "^D",
        !          4024:       "^E",
        !          4025:       "^F",
        !          4026:       "^G",
        !          4027:       "^H",
        !          4028:       "^I",
        !          4029:       "^J",
        !          4030:       "^K",
        !          4031:       "^L",
        !          4032:       "^M",
        !          4033:       "^N",
        !          4034:       "^O",
        !          4035:       "^P",
        !          4036:       "^Q",
        !          4037:       "^R",
        !          4038:       "^S",
        !          4039:       "^T",
        !          4040:       "^U",
        !          4041:       "^V",
        !          4042:       "^W",
        !          4043:       "^X",
        !          4044:       "^Y",
        !          4045:       "^Z",
        !          4046:       "^[",
        !          4047:       "^\\",
        !          4048:       "^]",
        !          4049:       "^^",
        !          4050:       "^_",
        !          4051:       " ",
        !          4052:       "!",
        !          4053:       "\"",
        !          4054:       "#",
        !          4055:       "$",
        !          4056:       "%",
        !          4057:       "&",
        !          4058:       "'",
        !          4059:       "(",
        !          4060:       ")",
        !          4061:       "*",
        !          4062:       "+",
        !          4063:       ",",
        !          4064:       "-",
        !          4065:       ".",
        !          4066:       "/",
        !          4067:       "0",
        !          4068:       "1",
        !          4069:       "2",
        !          4070:       "3",
        !          4071:       "4",
        !          4072:       "5",
        !          4073:       "6",
        !          4074:       "7",
        !          4075:       "8",
        !          4076:       "9",
        !          4077:       ":",
        !          4078:       ";",
        !          4079:       "<",
        !          4080:       "=",
        !          4081:       ">",
        !          4082:       "?",
        !          4083:       "@",
        !          4084:       "A",
        !          4085:       "B",
        !          4086:       "C",
        !          4087:       "D",
        !          4088:       "E",
        !          4089:       "F",
        !          4090:       "G",
        !          4091:       "H",
        !          4092:       "I",
        !          4093:       "J",
        !          4094:       "K",
        !          4095:       "L",
        !          4096:       "M",
        !          4097:       "N",
        !          4098:       "O",
        !          4099:       "P",
        !          4100:       "Q",
        !          4101:       "R",
        !          4102:       "S",
        !          4103:       "T",
        !          4104:       "U",
        !          4105:       "V",
        !          4106:       "W",
        !          4107:       "X",
        !          4108:       "Y",
        !          4109:       "Z",
        !          4110:       "[",
        !          4111:       "\\",
        !          4112:       "]",
        !          4113:       "^",
        !          4114:       "_",
        !          4115:       "`",
        !          4116:       "a",
        !          4117:       "b",
        !          4118:       "c",
        !          4119:       "d",
        !          4120:       "e",
        !          4121:       "f",
        !          4122:       "g",
        !          4123:       "h",
        !          4124:       "i",
        !          4125:       "j",
        !          4126:       "k",
        !          4127:       "l",
        !          4128:       "m",
        !          4129:       "n",
        !          4130:       "o",
        !          4131:       "p",
        !          4132:       "q",
        !          4133:       "r",
        !          4134:       "s",
        !          4135:       "t",
        !          4136:       "u",
        !          4137:       "v",
        !          4138:       "w",
        !          4139:       "x",
        !          4140:       "y",
        !          4141:       "z",
        !          4142:       "{"/*}*/,
        !          4143:       "|",
        !          4144:       /*{*/"}",
        !          4145:       "~",
        !          4146:       "^?",
        !          4147:       "|^@",
        !          4148:       "|^A",
        !          4149:       "|^B",
        !          4150:       "|^C",
        !          4151:       "|^D",
        !          4152:       "|^E",
        !          4153:       "|^F",
        !          4154:       "|^G",
        !          4155:       "|^H",
        !          4156:       "|^I",
        !          4157:       "|^J",
        !          4158:       "|^K",
        !          4159:       "|^L",
        !          4160:       "|^M",
        !          4161:       "|^N",
        !          4162:       "|^O",
        !          4163:       "|^P",
        !          4164:       "|^Q",
        !          4165:       "|^R",
        !          4166:       "|^S",
        !          4167:       "|^T",
        !          4168:       "|^U",
        !          4169:       "|^V",
        !          4170:       "|^W",
        !          4171:       "|^X",
        !          4172:       "|^Y",
        !          4173:       "|^Z",
        !          4174:       "|^[",
        !          4175:       "|^\\",
        !          4176:       "|^]",
        !          4177:       "|^^",
        !          4178:       "|^_",
        !          4179:       "| ",
        !          4180:       "|!",
        !          4181:       "|\"",
        !          4182:       "|#",
        !          4183:       "|$",
        !          4184:       "|%",
        !          4185:       "|&",
        !          4186:       "|'",
        !          4187:       "|(",
        !          4188:       "|)",
        !          4189:       "|*",
        !          4190:       "|+",
        !          4191:       "|,",
        !          4192:       "|-",
        !          4193:       "|.",
        !          4194:       "|/",
        !          4195:       "|0",
        !          4196:       "|1",
        !          4197:       "|2",
        !          4198:       "|3",
        !          4199:       "|4",
        !          4200:       "|5",
        !          4201:       "|6",
        !          4202:       "|7",
        !          4203:       "|8",
        !          4204:       "|9",
        !          4205:       "|:",
        !          4206:       "|;",
        !          4207:       "|<",
        !          4208:       "|=",
        !          4209:       "|>",
        !          4210:       "|?",
        !          4211:       "|@",
        !          4212:       "|A",
        !          4213:       "|B",
        !          4214:       "|C",
        !          4215:       "|D",
        !          4216:       "|E",
        !          4217:       "|F",
        !          4218:       "|G",
        !          4219:       "|H",
        !          4220:       "|I",
        !          4221:       "|J",
        !          4222:       "|K",
        !          4223:       "|L",
        !          4224:       "|M",
        !          4225:       "|N",
        !          4226:       "|O",
        !          4227:       "|P",
        !          4228:       "|Q",
        !          4229:       "|R",
        !          4230:       "|S",
        !          4231:       "|T",
        !          4232:       "|U",
        !          4233:       "|V",
        !          4234:       "|W",
        !          4235:       "|X",
        !          4236:       "|Y",
        !          4237:       "|Z",
        !          4238:       "|[",
        !          4239:       "|\\",
        !          4240:       "|]",
        !          4241:       "|^",
        !          4242:       "|_",
        !          4243:       "|`",
        !          4244:       "|a",
        !          4245:       "|b",
        !          4246:       "|c",
        !          4247:       "|d",
        !          4248:       "|e",
        !          4249:       "|f",
        !          4250:       "|g",
        !          4251:       "|h",
        !          4252:       "|i",
        !          4253:       "|j",
        !          4254:       "|k",
        !          4255:       "|l",
        !          4256:       "|m",
        !          4257:       "|n",
        !          4258:       "|o",
        !          4259:       "|p",
        !          4260:       "|q",
        !          4261:       "|r",
        !          4262:       "|s",
        !          4263:       "|t",
        !          4264:       "|u",
        !          4265:       "|v",
        !          4266:       "|w",
        !          4267:       "|x",
        !          4268:       "|y",
        !          4269:       "|z",
        !          4270:       "|{"/*}*/,
        !          4271:       "||",
        !          4272:       /*{*/"|}",
        !          4273:       "|~",
        !          4274:       "|^?" };
        !          4275:
        !          4276: char *_Unctrl[0400] = { "^@",
        !          4277:       "^A",
        !          4278:       "^B",
        !          4279:       "^C",
        !          4280:       "^D",
        !          4281:       "^E",
        !          4282:       "^F",
        !          4283:       "^G",
        !          4284:       "^H",
        !          4285:       "^I",
        !          4286:       "^J",
        !          4287:       "^K",
        !          4288:       "^L",
        !          4289:       "^M",
        !          4290:       "^N",
        !          4291:       "^O",
        !          4292:       "^P",
        !          4293:       "^Q",
        !          4294:       "^R",
        !          4295:       "^S",
        !          4296:       "^T",
        !          4297:       "^U",
        !          4298:       "^V",
        !          4299:       "^W",
        !          4300:       "^X",
        !          4301:       "^Y",
        !          4302:       "^Z",
        !          4303:       "^[",
        !          4304:       "^\\",
        !          4305:       "^]",
        !          4306:       "^^",
        !          4307:       "^_",
        !          4308:       "sp",
        !          4309:       "!",
        !          4310:       "\"",
        !          4311:       "#",
        !          4312:       "$",
        !          4313:       "%",
        !          4314:       "&",
        !          4315:       "'",
        !          4316:       "(",
        !          4317:       ")",
        !          4318:       "*",
        !          4319:       "+",
        !          4320:       ",",
        !          4321:       "-",
        !          4322:       ".",
        !          4323:       "/",
        !          4324:       "0",
        !          4325:       "1",
        !          4326:       "2",
        !          4327:       "3",
        !          4328:       "4",
        !          4329:       "5",
        !          4330:       "6",
        !          4331:       "7",
        !          4332:       "8",
        !          4333:       "9",
        !          4334:       ":",
        !          4335:       ";",
        !          4336:       "<",
        !          4337:       "=",
        !          4338:       ">",
        !          4339:       "?",
        !          4340:       "@",
        !          4341:       "A",
        !          4342:       "B",
        !          4343:       "C",
        !          4344:       "D",
        !          4345:       "E",
        !          4346:       "F",
        !          4347:       "G",
        !          4348:       "H",
        !          4349:       "I",
        !          4350:       "J",
        !          4351:       "K",
        !          4352:       "L",
        !          4353:       "M",
        !          4354:       "N",
        !          4355:       "O",
        !          4356:       "P",
        !          4357:       "Q",
        !          4358:       "R",
        !          4359:       "S",
        !          4360:       "T",
        !          4361:       "U",
        !          4362:       "V",
        !          4363:       "W",
        !          4364:       "X",
        !          4365:       "Y",
        !          4366:       "Z",
        !          4367:       "[",
        !          4368:       "\\",
        !          4369:       "]",
        !          4370:       "^",
        !          4371:       "_",
        !          4372:       "`",
        !          4373:       "a",
        !          4374:       "b",
        !          4375:       "c",
        !          4376:       "d",
        !          4377:       "e",
        !          4378:       "f",
        !          4379:       "g",
        !          4380:       "h",
        !          4381:       "i",
        !          4382:       "j",
        !          4383:       "k",
        !          4384:       "l",
        !          4385:       "m",
        !          4386:       "n",
        !          4387:       "o",
        !          4388:       "p",
        !          4389:       "q",
        !          4390:       "r",
        !          4391:       "s",
        !          4392:       "t",
        !          4393:       "u",
        !          4394:       "v",
        !          4395:       "w",
        !          4396:       "x",
        !          4397:       "y",
        !          4398:       "z",
        !          4399:       "{"/*}*/,
        !          4400:       "|",
        !          4401:       /*{*/"}",
        !          4402:       "~",
        !          4403:       "^?",
        !          4404:       "|^@",
        !          4405:       "|^A",
        !          4406:       "|^B",
        !          4407:       "|^C",
        !          4408:       "|^D",
        !          4409:       "|^E",
        !          4410:       "|^F",
        !          4411:       "|^G",
        !          4412:       "|^H",
        !          4413:       "|^I",
        !          4414:       "|^J",
        !          4415:       "|^K",
        !          4416:       "|^L",
        !          4417:       "|^M",
        !          4418:       "|^N",
        !          4419:       "|^O",
        !          4420:       "|^P",
        !          4421:       "|^Q",
        !          4422:       "|^R",
        !          4423:       "|^S",
        !          4424:       "|^T",
        !          4425:       "|^U",
        !          4426:       "|^V",
        !          4427:       "|^W",
        !          4428:       "|^X",
        !          4429:       "|^Y",
        !          4430:       "|^Z",
        !          4431:       "|^[",
        !          4432:       "|^\\",
        !          4433:       "|^]",
        !          4434:       "|^^",
        !          4435:       "|^_",
        !          4436:       "|sp",
        !          4437:       "|!",
        !          4438:       "|\"",
        !          4439:       "|#",
        !          4440:       "|$",
        !          4441:       "|%",
        !          4442:       "|&",
        !          4443:       "|'",
        !          4444:       "|(",
        !          4445:       "|)",
        !          4446:       "|*",
        !          4447:       "|+",
        !          4448:       "|,",
        !          4449:       "|-",
        !          4450:       "|.",
        !          4451:       "|/",
        !          4452:       "|0",
        !          4453:       "|1",
        !          4454:       "|2",
        !          4455:       "|3",
        !          4456:       "|4",
        !          4457:       "|5",
        !          4458:       "|6",
        !          4459:       "|7",
        !          4460:       "|8",
        !          4461:       "|9",
        !          4462:       "|:",
        !          4463:       "|;",
        !          4464:       "|<",
        !          4465:       "|=",
        !          4466:       "|>",
        !          4467:       "|?",
        !          4468:       "|@",
        !          4469:       "|A",
        !          4470:       "|B",
        !          4471:       "|C",
        !          4472:       "|D",
        !          4473:       "|E",
        !          4474:       "|F",
        !          4475:       "|G",
        !          4476:       "|H",
        !          4477:       "|I",
        !          4478:       "|J",
        !          4479:       "|K",
        !          4480:       "|L",
        !          4481:       "|M",
        !          4482:       "|N",
        !          4483:       "|O",
        !          4484:       "|P",
        !          4485:       "|Q",
        !          4486:       "|R",
        !          4487:       "|S",
        !          4488:       "|T",
        !          4489:       "|U",
        !          4490:       "|V",
        !          4491:       "|W",
        !          4492:       "|X",
        !          4493:       "|Y",
        !          4494:       "|Z",
        !          4495:       "|[",
        !          4496:       "|\\",
        !          4497:       "|]",
        !          4498:       "|^",
        !          4499:       "|_",
        !          4500:       "|`",
        !          4501:       "|a",
        !          4502:       "|b",
        !          4503:       "|c",
        !          4504:       "|d",
        !          4505:       "|e",
        !          4506:       "|f",
        !          4507:       "|g",
        !          4508:       "|h",
        !          4509:       "|i",
        !          4510:       "|j",
        !          4511:       "|k",
        !          4512:       "|l",
        !          4513:       "|m",
        !          4514:       "|n",
        !          4515:       "|o",
        !          4516:       "|p",
        !          4517:       "|q",
        !          4518:       "|r",
        !          4519:       "|s",
        !          4520:       "|t",
        !          4521:       "|u",
        !          4522:       "|v",
        !          4523:       "|w",
        !          4524:       "|x",
        !          4525:       "|y",
        !          4526:       "|z",
        !          4527:       "|{"/*}*/,
        !          4528:       "||",
        !          4529:       /*{*/"|}",
        !          4530:       "|~",
        !          4531:       "|^?" };
        !          4532:
        !          4533: void do_undef(int expr_sharp)
        !          4534: {
        !          4535:  char *mac;
        !          4536:
        !          4537:  if (! in_false_if())
        !          4538:   { mac = read_ident();
        !          4539:     if (! mac)
        !          4540:      { err_head();
        !          4541:        fprintf(stderr,"missing/illegal macro name\n");
        !          4542:      }
        !          4543:     else
        !          4544:      { if (undef(mac))
        !          4545:   { n_undefines ++;
        !          4546:   }
        !          4547:      }
        !          4548:   }
        !          4549:  if (sharp)
        !          4550:   { flush_sharp_line();
        !          4551:   }
        !          4552: }
        !          4553: /*#define DEBUG_WHILE/**/
        !          4554:
        !          4555: #ifdef DEBUG_WHILE
        !          4556: extern int debugging;
        !          4557: #endif
        !          4558:
        !          4559: void do_while(void)
        !          4560: {
        !          4561:  input_mark();
        !          4562:  do_if(0);
        !          4563: }
        !          4564:
        !          4565: void do_endwhile(void)
        !          4566: {
        !          4567:  if (in_false_if())
        !          4568:   { do_endif(0);
        !          4569:     input_unmark();
        !          4570: #ifdef DEBUG_WHILE
        !          4571:     if (debugging)
        !          4572:      { outputs("//endwhile:");
        !          4573:        outputd(curline());
        !          4574:        outputs(",");
        !          4575:        outputs(curfile());
        !          4576:        outputs("\\\\");
        !          4577:      }
        !          4578: #endif
        !          4579:     out_at(curline(),curfile());
        !          4580:   }
        !          4581:  else
        !          4582:   { do_endif(0);
        !          4583:     input_recover();
        !          4584:     input_mark();
        !          4585:     do_if(0);
        !          4586:   }
        !          4587: }
        !          4588:
        !          4589: char *Index(char *s, int c)
        !          4590: {
        !          4591:   return strchr(s,c);
        !          4592: }
        !          4593:
        !          4594: char *Rindex(char *s, int c)
        !          4595: {
        !          4596:   return strrchr(s,c);
        !          4597: }
        !          4598:
        !          4599: void Bcopy(char *from, char *to, int len)
        !          4600: {
        !          4601: #if defined(GO32)
        !          4602:   bcopy(from,to,len);
        !          4603: #else
        !          4604:   memmove((void *)from,(void *)to,(int)len);
        !          4605: #endif
        !          4606: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>