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

Annotation of OpenXM_contrib2/windows/cpp/cpp_main.c, Revision 1.1

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

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