home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / lbl / src / scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.4 KB  |  159 lines

  1. /* (C) C.D.F. Miller, Heriot-Watt University, March 1984
  2.  *
  3.  *    Permission is hereby given to reproduce or modify this
  4.  *    software freely, provided that this notice be retained,
  5.  *    and that no use be made of the software for commercial
  6.  *    purposes without the express written permission of the
  7.  *    author.
  8.  */
  9.  
  10. /* scan.c:
  11.  *    scan an input file, recording label-definitions, etc.
  12.  *    All special actions are introduced by a line starting
  13.  *        .<macro>
  14.  *    where <macro> is "L=" unless redefined in the command-line.
  15.  *    Actions are
  16.  *        .L= <type> <level> <label>
  17.  *            define <label> by incrementing the <level>th
  18.  *            index of label-type <type>, e.g.
  19.  *            .L= table 1 profits_1983
  20.  *        .L= delimiter <char>
  21.  *            redefines the delimiter for the subsequent text.
  22.  *        .L= format <type> <string>
  23.  *            defines a format for displaying the given label <type>;
  24.  *            the latest definition in the input will be used for
  25.  *            ALL occurrences, including preceding ones.
  26.  *            e.g.
  27.  *            .L= format appendix %A-%1
  28.  *        .L= next <type> <value> <value> ...
  29.  *            set the value of the next label generated for <type>;
  30.  *            the <value>s give successive levels, with omitted
  31.  *            trailing values defaulting to 0.
  32.  */
  33.  
  34. #include    <lbl.h>
  35. #include    <ctype.h>
  36.  
  37. extern char    macroname[];
  38. extern char    *filename;
  39. extern int    sflag;
  40. extern FILE    *tempfile;
  41. extern long    fileline;
  42.  
  43. scan(fname, f)
  44.     rg char    *fname;
  45.     rg FILE    *f;
  46. {
  47.     char    line[BUFSIZ];
  48.     rg int    line_complete = 1;
  49.  
  50.     /* Mark start of file in temp file */
  51.     if (!sflag)
  52.         fprintf(tempfile, "%c%c%c%s\n", MAGIC1, MAGIC2, M_FILE, fname);
  53.     filename = fname;
  54.     fileline = 0L;
  55.  
  56.     while (fgets(line, BUFSIZ, f) != NULL)
  57.     {
  58.         if (!sflag)
  59.             fputs(line, tempfile);
  60.         if (line_complete)
  61.         {
  62.             fileline++;
  63.             line_complete = line[strlen(line)-1] == '\n';
  64.             if (line[0]=='.' && line[1]==macroname[0] &&
  65.                 line[2]==macroname[1])
  66.             {
  67.                 if (line_complete)
  68.                     process(line+3);
  69.                 else
  70.                     error(".%s line too long", macroname);
  71.             }
  72.         }
  73.         else
  74.             line_complete = line[strlen(line)-1] == '\n';
  75.     }
  76. }
  77.  
  78. process(line)
  79.     char    *line;
  80. {
  81.     us int    split();
  82.     keyword    *findkeyword();
  83.     us int    nargs;
  84.     char    *argvec[NLEVELS+2];
  85.     keyword    *key;
  86.  
  87.     if ((nargs = split(line, argvec)) == 0)
  88.     {
  89.         error("empty .%s line", macroname);
  90.         return;
  91.     }
  92.  
  93.     /* Check for and act upon reserved words */
  94.     if ((key = findkeyword(argvec[0])) != NULL)
  95.     {
  96.         if (nargs < key->k_minargs)
  97.         {
  98.             error("%s - too few arguments", key->k_name);
  99.             return;
  100.         }
  101.         if (nargs > key->k_maxargs)
  102.         {
  103.             error("%s - too many arguments", key->k_name);
  104.             return;
  105.         }
  106.         (*(key->k_action))(nargs, argvec);
  107.         return;
  108.     }
  109.  
  110.     /* Process a label definition */
  111.     if (nargs != 3)
  112.     {
  113.         error("too %s arguments in label definition",
  114.             nargs < 3 ? "few" : "many");
  115.         return;
  116.     }
  117.     addlbl(argvec[0], argvec[1], argvec[2]);
  118. }
  119.  
  120. /* split - split a line into arguments
  121.  *    N.B. successive calls of this invalidate earlier calls;
  122.  *    argvec is set to point to strings within the
  123.  *    static local buffer "copybuf" which is overwritten on
  124.  *    each call.
  125.  */
  126. us int
  127. split(line, argvec)
  128.     char    *line;
  129.     char    *argvec[];
  130. {
  131.     us int        nargs = 0;
  132.     static char    copybuf[BUFSIZ];
  133.     char        *ln = copybuf;
  134.  
  135.     strcpy(ln, line);
  136.     while (*ln)
  137.     {
  138.         while (isspace(*ln))
  139.             ln++;
  140.         if (*ln)
  141.         {
  142.             if (nargs > 2+NLEVELS)
  143.             {
  144.                 error("surplus arguments to .%s ignored",
  145.                     macroname);
  146.                 break;
  147.             }
  148.             argvec[nargs++] = ln;
  149.             while (*ln && !isspace(*ln))
  150.                 ln++;
  151.             if (*ln)
  152.                 *ln++ = '\0';
  153.         }
  154.     }
  155.     if (nargs > 2+NLEVELS)
  156.         nargs = 2+NLEVELS;
  157.     return nargs;
  158. }
  159.