home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / text / general / rcs_451 / rcs.lzh / rcs / RCS.RCSfiles / rcslex.c,v < prev   
Text File  |  1991-02-05  |  27KB  |  938 lines

  1. head     4.6;
  2. branch   4.6.2;
  3. access   ;
  4. symbols  amiga_rcs:4.6.2 cbmvax_source:4.6.1 uunet_june89_dist:4.6;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 4.6
  10. date     89.05.01.15.13.07;  author narten;  state Exp;
  11. branches 4.6.1.1 4.6.2.1;
  12. next     ;
  13.  
  14. 4.6.1.1
  15. date     89.08.11.01.42.52;  author rsbx;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19. 4.6.2.1
  20. date     89.10.13.19.18.54;  author rsbx;  state Exp;
  21. branches ;
  22. next     4.6.2.2;
  23.  
  24. 4.6.2.2
  25. date     89.10.15.15.44.48;  author rsbx;  state Exp;
  26. branches ;
  27. next     4.6.2.3;
  28.  
  29. 4.6.2.3
  30. date     90.07.28.14.04.41;  author rsbx;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @RCS file input.
  37. @
  38.  
  39.  
  40.  
  41. 4.6
  42. log
  43. @checked in with -k by rsbx at 89.08.10.16.22.16.
  44. @
  45. text
  46. @/*
  47.  *                     RCS file input
  48.  */
  49. #ifndef lint
  50. static char rcsid[]= "$Id: rcslex.c,v 4.6 89/05/01 15:13:07 narten Exp $ Purdue CS";
  51. #endif
  52. /*********************************************************************************
  53.  *                     Lexical Analysis.
  54.  *                     Character mapping table,
  55.  *                     hashtable, Lexinit, nextlex, getlex, getkey,
  56.  *                     getid, getnum, readstring, printstring, savestring,
  57.  *                     checkid, serror, fatserror, error, faterror, warn, diagnose
  58.  *                     fflsbuf, puts, fprintf
  59.  *                     Testprogram: define LEXDB
  60.  *********************************************************************************
  61.  */
  62.  
  63. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  64.  * All rights reserved.
  65.  *
  66.  * Redistribution and use in source and binary forms are permitted
  67.  * provided that the above copyright notice and this paragraph are
  68.  * duplicated in all such forms and that any documentation,
  69.  * advertising materials, and other materials related to such
  70.  * distribution and use acknowledge that the software was developed
  71.  * by Walter Tichy.
  72.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  73.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  74.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  75.  *
  76.  * Report all problems and direct all questions to:
  77.  *   rcs-bugs@@cs.purdue.edu
  78.  * 
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86. */
  87.  
  88.  
  89.  
  90. /* $Log:    rcslex.c,v $
  91.  * Revision 4.6  89/05/01  15:13:07  narten
  92.  * changed copyright header to reflect current distribution rules
  93.  * 
  94.  * Revision 4.5  88/11/08  12:00:54  narten
  95.  * changes from  eggert@@sm.unisys.com (Paul Eggert)
  96.  * 
  97.  * Revision 4.5  88/08/28  15:01:12  eggert
  98.  * Don't loop when writing error messages to a full filesystem.
  99.  * Flush stderr/stdout when mixing output.
  100.  * Yield exit status compatible with diff(1).
  101.  * Shrink stdio code size; allow cc -R; remove lint.
  102.  * 
  103.  * Revision 4.4  87/12/18  11:44:47  narten
  104.  * fixed to use "varargs" in "fprintf"; this is required if it is to
  105.  * work on a SPARC machine such as a Sun-4
  106.  * 
  107.  * Revision 4.3  87/10/18  10:37:18  narten
  108.  * Updating version numbers. Changes relative to 1.1 actually relative
  109.  * to version 4.1
  110.  * 
  111.  * Revision 1.3  87/09/24  14:00:17  narten
  112.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  113.  * warnings)
  114.  * 
  115.  * Revision 1.2  87/03/27  14:22:33  jenkins
  116.  * Port to suns
  117.  * 
  118.  * Revision 1.1  84/01/23  14:50:33  kcs
  119.  * Initial revision
  120.  * 
  121.  * Revision 4.1  83/03/25  18:12:51  wft
  122.  * Only changed $Header to $Id.
  123.  * 
  124.  * Revision 3.3  82/12/10  16:22:37  wft
  125.  * Improved error messages, changed exit status on error to 1.
  126.  *
  127.  * Revision 3.2  82/11/28  21:27:10  wft
  128.  * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h.
  129.  * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations
  130.  * properly in case there is an IO-error (e.g., file system full).
  131.  *
  132.  * Revision 3.1  82/10/11  19:43:56  wft
  133.  * removed unused label out:;
  134.  * made sure all calls to getc() return into an integer, not a char.
  135.  */
  136.  
  137.  
  138. /*
  139. #define LEXDB
  140. /* version LEXDB is for testing the lexical analyzer. The testprogram
  141.  * reads a stream of lexemes, enters the revision numbers into the
  142.  * hashtable, and prints the recognized tokens. Keywords are recognized
  143.  * as identifiers.
  144.  */
  145.  
  146.  
  147.  
  148. #include "rcsbase.h"
  149. #include <varargs.h>
  150.  
  151.  
  152.  
  153. /* character mapping table */
  154. enum tokens map[] = {
  155.         EOFILE,         /* this will end up at ctab[-1] */
  156.         UNKN,   INSERT, UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,
  157.         UNKN,   SPACE,  NEWLN,  UNKN,   SPACE,  UNKN,   UNKN,   UNKN,
  158.         UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,
  159.         UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,   UNKN,
  160.         SPACE,  EXCLA,  DQUOTE, HASH,   DOLLAR, PERCNT, AMPER,  SQUOTE,
  161.         LPARN,  RPARN,  TIMES,  PLUS,   COMMA,  MINUS,  PERIOD, DIVIDE,
  162.         DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,  DIGIT,
  163.         DIGIT,  DIGIT,  COLON,  SEMI,   LESS,   EQUAL,  GREAT,  QUEST,
  164.         AT,     LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  165.         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  166.         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  167.         LETTER, LETTER, LETTER, LBRACK, BACKSL, RBRACK, UPARR,  UNDER,
  168.         ACCENT, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  169.         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  170.         LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
  171.         LETTER, LETTER, LETTER, LBRACE, BAR,    RBRACE, TILDE,  UNKN
  172. };
  173.  
  174.  
  175.  
  176.  
  177. struct hshentry * nexthsh;  /*pointer to next hashtable-entry, set by lookup*/
  178.  
  179. enum tokens     nexttok;    /*next token, set by nextlex                    */
  180.  
  181. int             hshenter;   /*if true, next suitable lexeme will be entered */
  182.                             /*into the symbol table. Handle with care.      */
  183. int             nextc;      /*next input character, initialized by Lexinit  */
  184.  
  185. int             eof;        /*end-of-file indicator, set to >0 on end of file*/
  186. int             line;       /*current line-number of input                  */
  187. int             nerror;     /*counter for errors                            */
  188. int             nwarn;      /*counter for warnings                          */
  189. char *          cmdid;      /*command identification for error messages     */
  190. int             quietflag;  /*indicates quiet mode                          */
  191. FILE *          finptr;     /*input file descriptor                         */
  192.  
  193. FILE *          frewrite;   /*file descriptor for echoing input             */
  194.  
  195. int             rewriteflag;/*indicates whether to echo to frewrite         */
  196.  
  197. char            StringTab[strtsize]; /* string table and heap               */
  198.  
  199. char *          NextString;         /*pointer to next identifier in StringTab*/
  200. char *          Topchar;            /*pointer to next free byte in StringTab*/
  201.                                     /*set by nextlex, lookup                */
  202. struct hshentry hshtab[hshsize];    /*hashtable                             */
  203.  
  204.  
  205.  
  206.  
  207.  
  208. lookup() {
  209.  
  210. /* Function: Looks up the character string pointed to by NextString in the
  211.  * hashtable. If the string is not present, a new entry for it is created.
  212.  * If the string is present, TopChar is moved back to save the space for
  213.  * the string, and NextString is set to point to the original string.
  214.  * In any case, the address of the corresponding hashtable entry is placed
  215.  * into nexthsh.
  216.  * Algorithm: Quadratic hash, covering all entries.
  217.  * Assumptions: NextString points at the first character of the string.
  218.  * Topchar points at the first empty byte after the string.
  219.  */
  220.  
  221.         register int     ihash;      /* index into hashtable */
  222.         register char    * sp, * np;
  223.         int              c, delta, final, FirstScan; /*loop control*/
  224.  
  225.         /* calculate hash code */
  226.         sp = NextString;
  227.         ihash = 0;
  228.         while (*sp) ihash += *sp++;
  229.  
  230.         /* set up first search loop (c=0,step=1,until (hshsiz-1)/2 */
  231.         c=0;delta=1;final=(hshsize-1)/2;
  232.         FirstScan=true;   /*first loop */
  233.  
  234.         for (;;) {
  235.                 ihash = (ihash+c)%hshsize;   /*next index*/
  236.  
  237.                 if (hshtab[ihash].num == nil) {
  238.                         /*empty slot found*/
  239.                         hshtab[ihash].num = NextString;
  240.                         nexthsh= &hshtab[ihash];/*save hashtable address*/
  241. #                       ifdef LEXDB
  242.                         VOID printf("\nEntered: %s at %d ",nexthsh->num, ihash);
  243. #                       endif
  244.                         return;
  245.                 }
  246.                 /* compare strings */
  247.                 sp=NextString;np=hshtab[ihash].num;
  248.                 while (*sp == *np++) {
  249.                         if (*sp == 0) {
  250.                                 /* match found */
  251.                                 nexthsh= &hshtab[ihash];
  252.                                 Topchar = NextString;
  253.                                 NextString = nexthsh->num;
  254.                                 return;
  255.                         } else sp++;
  256.                 }
  257.  
  258.                 /* neither empty slot nor string found */
  259.                 /* calculate next index and repeat */
  260.                 if (c != final)
  261.                         c += delta;
  262.                 else {
  263.                         if (FirstScan) {
  264.                                 /*set up second sweep*/
  265.                                 delta = -1; final = 1; FirstScan= false;
  266.                         } else {
  267.                                 fatserror("Hashtable overflow");
  268.                         }
  269.                 }
  270.         }
  271. };
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278. Lexinit()
  279. /* Function: Initialization of lexical analyzer:
  280.  * initializes the hastable,
  281.  * initializes nextc, nexttok if finptr != NULL
  282.  */
  283. {       register int            c;
  284.  
  285.         for (c=hshsize-1; c>=0; c--) {
  286.                 hshtab[c].num = nil;
  287.         }
  288.  
  289.         hshenter=true; eof=0; line=1; nerror=0; nwarn=0;
  290.         NextString=nil; Topchar = &StringTab[0];
  291.         if (finptr) {
  292.                 nextc = GETC(finptr,frewrite,rewriteflag); /*initial character*/
  293.                 nextlex();            /*initial token*/
  294.         } else {
  295.                 nextc = '\0';
  296.                 nexttok=EOFILE;
  297.         }
  298. }
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306. nextlex()
  307.  
  308. /* Function: Reads the next token and sets nexttok to the next token code.
  309.  * Only if the hshenter==true, a revision number is entered into the
  310.  * hashtable and a pointer to it is placed into nexthsh.
  311.  * This is useful for avoiding that dates are placed into the hashtable.
  312.  * For ID's and NUM's, NextString is set to the character string in the
  313.  * string table. Assumption: nextc contains the next character.
  314.  */
  315. {       register c;
  316.     register FILE * fin, * frew;
  317.         register char * sp;
  318.         register enum tokens d;
  319.  
  320.         if (eof) {
  321.                 nexttok=EOFILE;
  322.                 return;
  323.         }
  324.     fin=finptr; frew=frewrite;
  325. loop:
  326.         switch(nexttok=ctab[nextc]) {
  327.  
  328.         case UNKN:
  329.         case IDCHAR:
  330.         case PERIOD:
  331.                 serror("unknown Character: %c",nextc);
  332.                 nextc=GETC(fin,frew,rewriteflag);
  333.                 goto loop;
  334.  
  335.         case NEWLN:
  336.                 line++;
  337. #               ifdef LEXDB
  338.                 VOID putchar('\n');
  339. #               endif
  340.                 /* Note: falls into next case */
  341.  
  342.         case SPACE:
  343.                 nextc=GETC(fin,frew,rewriteflag);
  344.                 goto loop;
  345.  
  346.         case EOFILE:
  347.                 eof++;
  348.                 nexttok=EOFILE;
  349.                 return;
  350.  
  351.         case DIGIT:
  352.                 NextString = sp = Topchar;
  353.                 *sp++ = nextc;
  354.                 while ((d=ctab[c=GETC(fin,frew,rewriteflag)])==DIGIT ||
  355.                         d==PERIOD) {
  356.                         *sp++ = c;         /* 1.2. and 1.2 are different */
  357.                 }
  358.                 *sp++ = '\0';
  359.                 if (sp >= StringTab+strtsize) {
  360.                         /*may have written outside stringtable already*/
  361.                         fatserror("Stringtable overflow");
  362.                 }
  363.                 Topchar = sp;
  364.                 nextc = c;
  365.                 if (hshenter == true)
  366.                         lookup();      /* lookup updates NextString, Topchar*/
  367.                 nexttok = NUM;
  368.                 return;
  369.  
  370.  
  371.         case LETTER:
  372.                 NextString = sp = Topchar;
  373.                 *sp++ = nextc;
  374.                 while ((d=ctab[c=GETC(fin,frew,rewriteflag)])==LETTER ||
  375.                         d==DIGIT || d==IDCHAR) {
  376.                         *sp++ = c;
  377.                 }
  378.                 *sp++ = '\0';
  379.                 if (sp >= StringTab+strtsize) {
  380.                         /*may have written outside stringtable already*/
  381.                         fatserror("Stringtable overflow");
  382.                 }
  383.                 Topchar = sp;
  384.                 nextc = c;
  385.                 nexttok = ID;  /* may be ID or keyword */
  386.                 return;
  387.  
  388.         case SBEGIN: /* long string */
  389.                 nexttok = STRING;
  390.                 /* note: only the initial SBEGIN has been read*/
  391.                 /* read the string, and reset nextc afterwards*/
  392.                 return;
  393.  
  394.         default:
  395.                 nextc=GETC(fin,frew,rewriteflag);
  396.                 return;
  397.         }
  398. }
  399.  
  400.  
  401. int getlex(token)
  402. enum tokens token;
  403. /* Function: Checks if nexttok is the same as token. If so,
  404.  * advances the input by calling nextlex and returns true.
  405.  * otherwise returns false.
  406.  * Doesn't work for strings and keywords; loses the character string for ids.
  407.  */
  408. {
  409.         if (nexttok==token) {
  410.                 nextlex();
  411.                 return(true);
  412.         } else  return(false);
  413. }
  414.  
  415. int getkey (key)
  416. char * key;
  417. /* Function: If the current token is a keyword identical to key,
  418.  * getkey advances the input by calling nextlex and returns true;
  419.  * otherwise returns false.
  420.  */
  421. {
  422.         register char *s1,*s2;
  423.  
  424.         if (nexttok==ID) {
  425.                 s1=key; s2=NextString;
  426.                 while(*s1 == *s2++)
  427.                      if (*s1++ == '\0') {
  428.                          /* match found */
  429.                          Topchar = NextString; /*reset Topchar */
  430.                          nextlex();
  431.                          return(true);
  432.                      }
  433.         }
  434.         return(false);
  435. }
  436.  
  437.  
  438.  
  439. char * getid()
  440. /* Function: Checks if nexttok is an identifier. If so,
  441.  * advances the input by calling nextlex and returns a pointer
  442.  * to the identifier; otherwise returns nil.
  443.  * Treats keywords as identifiers.
  444.  */
  445. {
  446.         register char * name;
  447.         if (nexttok==ID) {
  448.                 name = NextString;
  449.                 nextlex();
  450.                 return name;
  451.         } else  return nil;
  452. }
  453.  
  454.  
  455. struct hshentry * getnum()
  456. /* Function: Checks if nexttok is a number. If so,
  457.  * advances the input by calling nextlex and returns a pointer
  458.  * to the hashtable entry. Otherwise returns nil.
  459.  * Doesn't work if hshenter is false.
  460.  */
  461. {
  462.         register struct hshentry * num;
  463.         if (nexttok==NUM) {
  464.                 num=nexthsh;
  465.                 nextlex();
  466.                 return num;
  467.         } else  return nil;
  468. }
  469.  
  470.  
  471. readstring()
  472. /* skip over characters until terminating single SDELIM        */
  473. /* if rewriteflag==true, copy every character read to frewrite.*/
  474. /* Does not advance nextlex at the end.                        */
  475. {       register c;
  476.     register FILE * fin,  * frew;
  477.     fin=finptr; frew=frewrite;
  478.         if (rewriteflag) {
  479.                 /* copy string verbatim to frewrite */
  480.                 while ((c=getc(fin)) != EOF) {
  481.             VOID putc(c,frew);
  482.                         if (c==SDELIM) {
  483.                                 if ((c=getc(fin)) == EOF || putc(c,frew) != SDELIM) {
  484.                                         /* end of string */
  485.                                         nextc=c;
  486.                                         return;
  487.                                 }
  488.                         }
  489.                 }
  490.         } else {
  491.                 /* skip string */
  492.                 while ((c=getc(fin)) != EOF) {
  493.                         if (c==SDELIM) {
  494.                                 if ((c=getc(fin)) != SDELIM) {
  495.                                         /* end of string */
  496.                                         nextc=c;
  497.                                         return;
  498.                                 }
  499.                         }
  500.                 }
  501.         }
  502.         nextc = c;
  503.         error("Unterminated string");
  504. }
  505.  
  506.  
  507. printstring()
  508. /* Function: copy a string to stdout, until terminated with a single SDELIM.
  509.  * Does not advance nextlex at the end.
  510.  */
  511. {
  512.         register c;
  513.     register FILE * fin;
  514.     fin=finptr;
  515.     while ((c=getc(fin)) != EOF) {
  516.                 if (c==SDELIM) {
  517.             if ((c=getc(fin)) != SDELIM) {
  518.                                 /* end of string */
  519.                                 nextc=c;
  520.                                 return;
  521.                         }
  522.                 }
  523.                 VOID putchar(c);
  524.         }
  525.         nextc = c;
  526.         error("Unterminated string");
  527. }
  528.  
  529.  
  530.  
  531. savestring(target,length)
  532. char * target; int length;
  533. /* copies a string terminated with SDELIM from file finptr to buffer target,
  534.  * but not more than length bytes. If the string is longer than length,
  535.  * the extra characters are skipped. The string may be empty, in which
  536.  * case a '\0' is placed into target.
  537.  * Double SDELIM is replaced with SDELIM.
  538.  * If rewriteflag==true, the string is also copied unchanged to frewrite.
  539.  * Returns the length of the saved string.
  540.  * Does not advance nextlex at the end.
  541.  */
  542. {
  543.         register c;
  544.     register FILE * fin, * frew;
  545.         register char * tp, * max;
  546.  
  547.     fin=finptr; frew=frewrite;
  548.         tp=target; max= target+length; /*max is one too large*/
  549.         while ((c=GETC(fin,frew,rewriteflag))!=EOF) {
  550.         *tp++ =c;
  551.                 if (c== SDELIM) {
  552.                         if ((c=GETC(fin,frew,rewriteflag))!=SDELIM) {
  553.                                 /* end of string */
  554.                                 *(tp-1)='\0';
  555.                                 nextc=c;
  556.                                 return;
  557.                         }
  558.                 }
  559.                 if (tp >= max) {
  560.                         /* overflow */
  561.                         error("string buffer overflow -- truncating string");
  562.                         target[length-1]='\0';
  563.                         /* skip rest of string */
  564.                         while ((c=GETC(fin,frew,rewriteflag))!=EOF) {
  565.                                 if ((c==SDELIM) && ((c=GETC(fin,frew,rewriteflag))!=SDELIM)) {
  566.                                         /* end of string */
  567.                                         nextc=c;
  568.                                         return;
  569.                                 }
  570.                         }
  571.                         nextc = c;
  572.                         error("Can't find %c to terminate string before end of file",SDELIM);
  573.                         return;
  574.                 }
  575.         }
  576.         nextc = c;
  577.         error("Can't find %c to terminate string before end of file",SDELIM);
  578. }
  579.  
  580.  
  581. char  *checkid(id, delim)
  582. char    *id, delim;
  583. /*   Function:  check whether the string starting at id is an   */
  584. /*              identifier and return a pointer to the last char*/
  585. /*              of the identifer. White space, delim and '\0'   */
  586. /*              are legal delimeters. Aborts the program if not */
  587. /*              a legal identifier. Useful for checking commands*/
  588. {
  589.         register enum  tokens  d;
  590.         register char    *temp;
  591.         register char    c,tc;
  592.  
  593.         temp = id;
  594.         if ( ctab[*id] == LETTER ) {
  595.             while( (d=ctab[c=(*++id)]) == LETTER || d==DIGIT || d==IDCHAR) ;
  596.             if ( c!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) {
  597.                 /* append \0 to end of id before error message */
  598.                 tc = c;
  599.                 while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ;
  600.                 *id = '\0';
  601.                 faterror("Invalid character %c in identifier %s",tc,temp);
  602.                 return nil ;
  603.             } else
  604.                 return id;
  605.         } else {
  606.             /* append \0 to end of id before error message */
  607.             while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ;
  608.             *id = '\0';
  609.             faterror("Identifier %s does not start with letter",temp);
  610.             return nil;
  611.         }
  612. }
  613.  
  614. writeerror()
  615. {
  616.     static looping;
  617.     if (looping)
  618.         exit(2);
  619.     looping = 1;
  620.     faterror("write error");
  621. }
  622.  
  623. nlflush(iop)
  624. register FILE * iop;
  625. {
  626.     if (putc('\n',iop)==EOF || fflush(iop)==EOF)
  627.                 writeerror();
  628. }
  629.  
  630.  
  631. /*VARARGS1*/
  632. serror(e,e1,e2,e3,e4,e5)
  633. char * e, * e1, * e2, * e3, * e4, * e5;
  634. /* non-fatal syntax error */
  635. {       nerror++;
  636.         VOID fprintf(stderr,"%s error, line %d: ", cmdid, line);
  637.         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
  638.         nlflush(stderr);
  639. }
  640.  
  641. /*VARARGS1*/
  642. error(e,e1,e2,e3,e4,e5)
  643. char * e, * e1, * e2, * e3, * e4, * e5;
  644. /* non-fatal error */
  645. {       nerror++;
  646.         VOID fprintf(stderr,"%s error: ",cmdid);
  647.         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
  648.         nlflush(stderr);
  649. }
  650.  
  651. /*VARARGS1*/
  652. fatserror(e,e1,e2,e3,e4,e5)
  653. char * e, * e1, * e2, * e3, * e4, * e5;
  654. /* fatal syntax error */
  655. {       nerror++;
  656.         VOID fprintf(stderr,"%s error, line %d: ", cmdid,line);
  657.         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
  658.         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
  659.         VOID cleanup();
  660.         exit(2);
  661. }
  662.  
  663. /*VARARGS1*/
  664. faterror(e,e1,e2,e3,e4,e5)
  665. char * e, * e1, * e2, * e3, * e4, * e5;
  666. /* fatal error, terminates program after cleanup */
  667. {       nerror++;
  668.         VOID fprintf(stderr,"%s error: ",cmdid);
  669.         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
  670.         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
  671.         VOID cleanup();
  672.         exit(2);
  673. }
  674.  
  675. /*VARARGS1*/
  676. warn(e,e1,e2,e3,e4,e5)
  677. char * e, * e1, * e2, * e3, * e4, * e5;
  678. /* prints a warning message */
  679. {       nwarn++;
  680.         VOID fprintf(stderr,"%s warning: ",cmdid);
  681.         VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
  682.         nlflush(stderr);
  683. }
  684.  
  685.  
  686. /*VARARGS1*/
  687. diagnose(e,e1,e2,e3,e4,e5)
  688. char * e, * e1, * e2, * e3, * e4, * e5;
  689. /* prints a diagnostic message */
  690. {
  691.         if (!quietflag) {
  692.                 VOID fprintf(stderr,e, e1, e2, e3, e4, e5);
  693.                 nlflush(stderr);
  694.         }
  695. }
  696.  
  697.  
  698.  
  699. fflsbuf(c, iop)
  700. unsigned c; register FILE * iop;
  701. /* Function: Flush iop.
  702.  * Same routine as _flsbuf in stdio, but aborts program on error.
  703.  */
  704. {       register result;
  705.         if ((result=_flsbuf(c,iop))==EOF)
  706.                 writeerror();
  707.         return result;
  708. }
  709.  
  710.  
  711. fputs(s, iop)
  712. register char *s;
  713. register FILE *iop;
  714. /* Function: Put string s on file iop, abort on error.
  715.  * Same as puts in stdio, but with different putc macro.
  716.  */
  717. {
  718.     register r;
  719.     register c;
  720.  
  721.     while (c = *s++)
  722.         r = putc(c, iop);
  723.     return(r);
  724. }
  725.  
  726.  
  727.  
  728. fprintf(iop, fmt, va_alist)
  729. FILE *iop;
  730. char *fmt;
  731. va_dcl
  732. /* Function: formatted output. Same as fprintf in stdio,
  733.  * but aborts program on error
  734.  */
  735. {
  736.     register int value;
  737.     va_list ap;
  738.  
  739.     va_start(ap);
  740. #ifdef VFPRINTF
  741.     VOID vfprintf(iop, fmt, ap);
  742. #else
  743.     _doprnt(fmt, ap, iop);
  744. #endif
  745.         if (ferror(iop)) {
  746.         writeerror();
  747.                 value = EOF;
  748.         } else value = 0;
  749.     va_end(ap);
  750.     return value;
  751. }
  752.  
  753.  
  754.  
  755. #ifdef LEXDB
  756. /* test program reading a stream of lexems and printing the tokens.
  757.  */
  758.  
  759.  
  760.  
  761. main(argc,argv)
  762. int argc; char * argv[];
  763. {
  764.         cmdid="lextest";
  765.         if (argc<2) {
  766.                 VOID fputs("No input file\n",stderr);
  767.                 exit(1);
  768.         }
  769.         if ((finptr=fopen(argv[1], "r")) == NULL) {
  770.                 faterror("Can't open input file %s\n",argv[1]);
  771.         }
  772.         Lexinit();
  773.         rewriteflag=false;
  774.         while (nexttok != EOFILE) {
  775.         switch (nexttok) {
  776.  
  777.         case ID:
  778.                 VOID printf("ID: %s",NextString);
  779.                 break;
  780.  
  781.         case NUM:
  782.                 if (hshenter==true)
  783.                    VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab);
  784.                 else
  785.                    VOID printf("NUM, unentered: %s",NextString);
  786.                 hshenter = !hshenter; /*alternate between dates and numbers*/
  787.                 break;
  788.  
  789.         case COLON:
  790.                 VOID printf("COLON"); break;
  791.  
  792.         case SEMI:
  793.                 VOID printf("SEMI"); break;
  794.  
  795.         case STRING:
  796.                 readstring();
  797.                 VOID printf("STRING"); break;
  798.  
  799.         case UNKN:
  800.                 VOID printf("UNKN"); break;
  801.  
  802.         default:
  803.                 VOID printf("DEFAULT"); break;
  804.         }
  805.         VOID printf(" | ");
  806.         nextlex();
  807.         }
  808.         VOID printf("\nEnd of lexical analyzer test\n");
  809. }
  810.  
  811. cleanup()
  812. /* dummy */
  813. {}
  814.  
  815.  
  816. #endif
  817. @
  818.  
  819.  
  820. 4.6.2.1
  821. log
  822. @Start of Amiga RCS port branch.
  823. @
  824. text
  825. @d5 1
  826. a5 5
  827. <<<<<<< rcslex.c
  828. static char rcsid[]= "$Id: rcslex.c,v 4.6.1.1 89/08/11 01:42:52 rsbx Exp Locker: rsbx $ Purdue CS";
  829. =======
  830. static char rcsid[]= "$Id: rcslex.c,v 1.2 89/09/17 13:36:11 rick Exp $ Purdue CS";
  831. >>>>>>> 1.2
  832. a45 11
  833. <<<<<<< rcslex.c
  834.  * Revision 4.6.1.1  89/08/11  01:42:52  rsbx
  835.  * Start of cbmvax RCS source branch.
  836. =======
  837.  * Revision 1.2  89/09/17  13:36:11  rick
  838.  * Port to AmigaDos done by Rick Schaeffer (ricks@@iscuva.iscs.com)
  839.  * All changes done with conditional compile (#ifdef AMIGA).  This version
  840.  * compiles correctly with Lattice C version 5.02 or later.
  841. >>>>>>> 1.2
  842.  * 
  843. <<<<<<< rcslex.c
  844. a46 3
  845.  * checked in with -k by rsbx at 89.08.10.16.22.16.
  846.  * 
  847.  * Revision 4.6  89/05/01  15:13:07  narten
  848. a57 5
  849. =======
  850.  * Revision 1.2  88/09/03  15:11:38  rick
  851.  * Port to AmigaDos.  All done with conditional compiles
  852.  * 
  853. >>>>>>> 1.2
  854. a103 1
  855. #ifndef AMIGA
  856. a104 1
  857. #endif
  858. d226 1
  859. a226 1
  860. }
  861. a647 1
  862. <<<<<<< rcslex.c
  863. a648 4
  864. =======
  865.                 VOID putc('\n',stderr);
  866.                 fflush(stderr);
  867. >>>>>>> 1.2
  868. d653 1
  869. a653 1
  870. #ifndef AMIGA
  871. d682 1
  872. d707 1
  873. a707 1
  874. #endif
  875. @
  876.  
  877.  
  878. 4.6.2.2
  879. log
  880. @Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
  881. sources I have here (and are later than the ones Rick used).
  882. @
  883. text
  884. @d5 5
  885. a9 1
  886. static char rcsid[]= "$Id: rcslex.c,v 4.6.2.1 89/10/13 19:18:54 rsbx Exp Locker: rsbx $ Purdue CS";
  887. d50 1
  888. a50 3
  889.  * Revision 4.6.2.1  89/10/13  19:18:54  rsbx
  890.  * Start of Amiga RCS port branch.
  891.  * 
  892. d53 6
  893. d60 1
  894. d76 5
  895. d673 1
  896. d675 4
  897. @
  898.  
  899.  
  900. 4.6.2.3
  901. log
  902. @Now flush stdout before putting error messages.
  903. @
  904. text
  905. @d5 1
  906. a5 1
  907. static char rcsid[]= "$Id: rcslex.c,v 4.6.2.2 89/10/15 15:44:48 rsbx Exp Locker: rsbx $ Purdue CS";
  908. a45 4
  909.  * Revision 4.6.2.2  89/10/15  15:44:48  rsbx
  910.  * Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
  911.  * sources I have here (and are later than the ones Rick used).
  912.  * 
  913. a601 1
  914.     fflush(stdout);
  915. a611 1
  916.     fflush(stdout);
  917. a621 1
  918.     fflush(stdout);
  919. a633 1
  920.     fflush(stdout);
  921. a645 1
  922.     fflush(stdout);
  923. a657 1
  924.         fflush(stdout);
  925. @
  926.  
  927.  
  928. 4.6.1.1
  929. log
  930. @Start of cbmvax RCS source branch.
  931. @
  932. text
  933. @a46 3
  934.  * checked in with -k by rsbx at 89.08.10.16.22.16.
  935.  * 
  936.  * Revision 4.6  89/05/01  15:13:07  narten
  937. @
  938.