home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / vgrind / vfontedpr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  15.6 KB  |  704 lines

  1. /*
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)vfontedpr.c    5.5 (Berkeley) 6/1/90";
  42. #endif /* not lint */
  43.  
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <ctype.h>
  47. #include <stdio.h>
  48. #include "pathnames.h"
  49.  
  50. #define boolean int
  51. #define TRUE 1
  52. #define FALSE 0
  53. #define NIL 0
  54. #define STANDARD 0
  55. #define ALTERNATE 1
  56.  
  57. /*
  58.  * Vfontedpr.
  59.  *
  60.  * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy)
  61.  *
  62.  */
  63.  
  64. #define STRLEN 10        /* length of strings introducing things */
  65. #define PNAMELEN 40        /* length of a function/procedure name */
  66. #define PSMAX 20        /* size of procedure name stacking */
  67.  
  68. /* regular expression routines */
  69.  
  70. char    *expmatch();        /* match a string to an expression */
  71. char    *STRNCMP();        /* a different kindof strncmp */
  72. char    *convexp();        /* convert expression to internal form */
  73. char    *tgetstr();
  74.  
  75. boolean    isproc();
  76.  
  77.  
  78. char    *ctime();
  79.  
  80. /*
  81.  *    The state variables
  82.  */
  83.  
  84. boolean    incomm;            /* in a comment of the primary type */
  85. boolean    instr;            /* in a string constant */
  86. boolean    inchr;            /* in a string constant */
  87. boolean    nokeyw = FALSE;        /* no keywords being flagged */
  88. boolean    index = FALSE;        /* form an index */
  89. boolean filter = FALSE;        /* act as a filter (like eqn) */
  90. boolean pass = FALSE;        /* when acting as a filter, pass indicates
  91.                  * whether we are currently processing
  92.                  * input.
  93.                  */
  94. boolean prccont;        /* continue last procedure */
  95. int    comtype;        /* type of comment */
  96. int    margin;
  97. int    psptr;            /* the stack index of the current procedure */
  98. char    pstack[PSMAX][PNAMELEN+1];    /* the procedure name stack */
  99. int    plstack[PSMAX];        /* the procedure nesting level stack */
  100. int    blklevel;        /* current nesting level */
  101. char    *defsfile = _PATH_VGRINDEFS;    /* name of language definitions file */
  102. char    pname[BUFSIZ+1];
  103.  
  104. /*
  105.  *    The language specific globals
  106.  */
  107.  
  108. char    *language = "c";    /* the language indicator */
  109. char    *l_keywds[BUFSIZ/2];    /* keyword table address */
  110. char    *l_prcbeg;        /* regular expr for procedure begin */
  111. char    *l_combeg;        /* string introducing a comment */
  112. char    *l_comend;        /* string ending a comment */
  113. char    *l_acmbeg;        /* string introducing a comment */
  114. char    *l_acmend;        /* string ending a comment */
  115. char    *l_blkbeg;        /* string begining of a block */
  116. char    *l_blkend;        /* string ending a block */
  117. char    *l_strbeg;        /* delimiter for string constant */
  118. char    *l_strend;        /* delimiter for string constant */
  119. char    *l_chrbeg;        /* delimiter for character constant */
  120. char    *l_chrend;        /* delimiter for character constant */
  121. char    l_escape;        /* character used to  escape characters */
  122. boolean    l_toplex;        /* procedures only defined at top lex level */
  123.  
  124. /*
  125.  *  global variables also used by expmatch
  126.  */
  127. boolean _escaped;        /* if last character was an escape */
  128. char *_start;            /* start of the current string */
  129. boolean    l_onecase;        /* upper and lower case are equivalent */
  130.  
  131. #define    ps(x)    printf("%s", x)
  132.  
  133. main(argc, argv)
  134.     int argc;
  135.     char *argv[];
  136. {
  137.     int lineno;
  138.     char *fname = "";
  139.     char *ptr;
  140.     struct stat stbuf;
  141.     char buf[BUFSIZ];
  142.     char strings[2 * BUFSIZ];
  143.     char defs[2 * BUFSIZ];
  144.     int needbp = 0;
  145.  
  146.     argc--, argv++;
  147.     do {
  148.     char *cp;
  149.     int i;
  150.  
  151.     if (argc > 0) {
  152.         if (!strcmp(argv[0], "-h")) {
  153.         if (argc == 1) {
  154.             printf("'ds =H\n");
  155.             argc = 0;
  156.             goto rest;
  157.         }
  158.         printf("'ds =H %s\n", argv[1]);
  159.         argc--, argv++;
  160.         argc--, argv++;
  161.         if (argc > 0)
  162.             continue;
  163.         goto rest;
  164.         }
  165.  
  166.         /* act as a filter like eqn */
  167.         if (!strcmp(argv[0], "-f")) {
  168.         filter++;
  169.         argv[0] = argv[argc-1];
  170.         argv[argc-1] = "-";
  171.         continue;
  172.         }
  173.  
  174.         /* take input from the standard place */
  175.         if (!strcmp(argv[0], "-")) {
  176.         argc = 0;
  177.         goto rest;
  178.         }
  179.  
  180.         /* build an index */
  181.         if (!strcmp(argv[0], "-x")) {
  182.         index++;
  183.         argv[0] = "-n";
  184.         }
  185.  
  186.         /* indicate no keywords */
  187.         if (!strcmp(argv[0], "-n")) {
  188.         nokeyw++;
  189.         argc--, argv++;
  190.         continue;
  191.         }
  192.  
  193.         /* specify the font size */
  194.         if (!strncmp(argv[0], "-s", 2)) {
  195.         i = 0;
  196.         cp = argv[0] + 2;
  197.         while (*cp)
  198.             i = i * 10 + (*cp++ - '0');
  199.         printf("'ps %d\n'vs %d\n", i, i+1);
  200.         argc--, argv++;
  201.         continue;
  202.         }
  203.  
  204.         /* specify the language */
  205.         if (!strncmp(argv[0], "-l", 2)) {
  206.         language = argv[0]+2;
  207.         argc--, argv++;
  208.         continue;
  209.         }
  210.  
  211.         /* specify the language description file */
  212.         if (!strncmp(argv[0], "-d", 2)) {
  213.         defsfile = argv[1];
  214.         argc--, argv++;
  215.         argc--, argv++;
  216.         continue;
  217.         }
  218.  
  219.         /* open the file for input */
  220.         if (freopen(argv[0], "r", stdin) == NULL) {
  221.         perror(argv[0]);
  222.         exit(1);
  223.         }
  224.         if (index)
  225.         printf("'ta 4i 4.25i 5.5iR\n'in .5i\n");
  226.         fname = argv[0];
  227.         argc--, argv++;
  228.     }
  229.     rest:
  230.  
  231.     /*
  232.      *  get the  language definition from the defs file
  233.      */
  234.     i = tgetent (defs, language, defsfile);
  235.     if (i == 0) {
  236.         fprintf (stderr, "no entry for language %s\n", language);
  237.         exit (0);
  238.     } else  if (i < 0) {
  239.         fprintf (stderr,  "cannot find vgrindefs file %s\n", defsfile);
  240.         exit (0);
  241.     }
  242.     cp = strings;
  243.     if (tgetstr ("kw", &cp) == NIL)
  244.         nokeyw = TRUE;
  245.     else  {
  246.         char **cpp;
  247.  
  248.         cpp = l_keywds;
  249.         cp = strings;
  250.         while (*cp) {
  251.         while (*cp == ' ' || *cp =='\t')
  252.             *cp++ = NULL;
  253.         if (*cp)
  254.             *cpp++ = cp;
  255.         while (*cp != ' ' && *cp  != '\t' && *cp)
  256.             cp++;
  257.         }
  258.         *cpp = NIL;
  259.     }
  260.     cp = buf;
  261.     l_prcbeg = convexp (tgetstr ("pb", &cp));
  262.     cp = buf;
  263.     l_combeg = convexp (tgetstr ("cb", &cp));
  264.     cp = buf;
  265.     l_comend = convexp (tgetstr ("ce", &cp));
  266.     cp = buf;
  267.     l_acmbeg = convexp (tgetstr ("ab", &cp));
  268.     cp = buf;
  269.     l_acmend = convexp (tgetstr ("ae", &cp));
  270.     cp = buf;
  271.     l_strbeg = convexp (tgetstr ("sb", &cp));
  272.     cp = buf;
  273.     l_strend = convexp (tgetstr ("se", &cp));
  274.     cp = buf;
  275.     l_blkbeg = convexp (tgetstr ("bb", &cp));
  276.     cp = buf;
  277.     l_blkend = convexp (tgetstr ("be", &cp));
  278.     cp = buf;
  279.     l_chrbeg = convexp (tgetstr ("lb", &cp));
  280.     cp = buf;
  281.     l_chrend = convexp (tgetstr ("le", &cp));
  282.     l_escape = '\\';
  283.     l_onecase = tgetflag ("oc");
  284.     l_toplex = tgetflag ("tl");
  285.  
  286.     /* initialize the program */
  287.  
  288.     incomm = FALSE;
  289.     instr = FALSE;
  290.     inchr = FALSE;
  291.     _escaped = FALSE;
  292.     blklevel = 0;
  293.     for (psptr=0; psptr<PSMAX; psptr++) {
  294.         pstack[psptr][0] = NULL;
  295.         plstack[psptr] = 0;
  296.     }
  297.     psptr = -1;
  298.     ps("'-F\n");
  299.     if (!filter) {
  300.         printf(".ds =F %s\n", fname);
  301.         ps("'wh 0 vH\n");
  302.         ps("'wh -1i vF\n");
  303.     }
  304.     if (needbp) {
  305.         needbp = 0;
  306.         printf(".()\n");
  307.         printf(".bp\n");
  308.     }
  309.     if (!filter) {
  310.         fstat(fileno(stdin), &stbuf);
  311.         cp = ctime(&stbuf.st_mtime);
  312.         cp[16] = '\0';
  313.         cp[24] = '\0';
  314.         printf(".ds =M %s %s\n", cp+4, cp+20);
  315.     }
  316.  
  317.     /*
  318.      *    MAIN LOOP!!!
  319.      */
  320.     while (fgets(buf, sizeof buf, stdin) != NULL) {
  321.         if (buf[0] == '\f') {
  322.         printf(".bp\n");
  323.         }
  324.         if (buf[0] == '.') {
  325.         printf("%s", buf);
  326.         if (!strncmp (buf+1, "vS", 2))
  327.             pass = TRUE;
  328.         if (!strncmp (buf+1, "vE", 2))
  329.             pass = FALSE;
  330.         continue;
  331.         }
  332.         prccont = FALSE;
  333.         if (!filter || pass)
  334.         putScp(buf);
  335.         else
  336.         printf("%s", buf);
  337.         if (prccont && (psptr >= 0)) {
  338.         ps("'FC ");
  339.         ps(pstack[psptr]);
  340.         ps("\n");
  341.         }
  342. #ifdef DEBUG
  343.         printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr);
  344. #endif
  345.         margin = 0;
  346.     }
  347.     needbp = 1;
  348.     } while (argc > 0);
  349.     exit(0);
  350. }
  351.  
  352. #define isidchr(c) (isalnum(c) || (c) == '_')
  353.  
  354. putScp(os)
  355.     char *os;
  356. {
  357.     register char *s = os;        /* pointer to unmatched string */
  358.     char dummy[BUFSIZ];            /* dummy to be used by expmatch */
  359.     char *comptr;            /* end of a comment delimiter */
  360.     char *acmptr;            /* end of a comment delimiter */
  361.     char *strptr;            /* end of a string delimiter */
  362.     char *chrptr;            /* end of a character const delimiter */
  363.     char *blksptr;            /* end of a lexical block start */
  364.     char *blkeptr;            /* end of a lexical block end */
  365.  
  366.     _start = os;            /* remember the start for expmatch */
  367.     _escaped = FALSE;
  368.     if (nokeyw || incomm || instr)
  369.     goto skip;
  370.     if (isproc(s)) {
  371.     ps("'FN ");
  372.     ps(pname);
  373.         ps("\n");
  374.     if (psptr < PSMAX) {
  375.         ++psptr;
  376.         strncpy (pstack[psptr], pname, PNAMELEN);
  377.         pstack[psptr][PNAMELEN] = NULL;
  378.         plstack[psptr] = blklevel;
  379.     }
  380.     } 
  381. skip:
  382.     do {
  383.     /* check for string, comment, blockstart, etc */
  384.     if (!incomm && !instr && !inchr) {
  385.  
  386.         blkeptr = expmatch (s, l_blkend, dummy);
  387.         blksptr = expmatch (s, l_blkbeg, dummy);
  388.         comptr = expmatch (s, l_combeg, dummy);
  389.         acmptr = expmatch (s, l_acmbeg, dummy);
  390.         strptr = expmatch (s, l_strbeg, dummy);
  391.         chrptr = expmatch (s, l_chrbeg, dummy);
  392.  
  393.         /* start of a comment? */
  394.         if (comptr != NIL)
  395.         if ((comptr < strptr || strptr == NIL)
  396.           && (comptr < acmptr || acmptr == NIL)
  397.           && (comptr < chrptr || chrptr == NIL)
  398.           && (comptr < blksptr || blksptr == NIL)
  399.           && (comptr < blkeptr || blkeptr == NIL)) {
  400.             putKcp (s, comptr-1, FALSE);
  401.             s = comptr;
  402.             incomm = TRUE;
  403.             comtype = STANDARD;
  404.             if (s != os)
  405.             ps ("\\c");
  406.             ps ("\\c\n'+C\n");
  407.             continue;
  408.         }
  409.  
  410.         /* start of a comment? */
  411.         if (acmptr != NIL)
  412.         if ((acmptr < strptr || strptr == NIL)
  413.           && (acmptr < chrptr || chrptr == NIL)
  414.           && (acmptr < blksptr || blksptr == NIL)
  415.           && (acmptr < blkeptr || blkeptr == NIL)) {
  416.             putKcp (s, acmptr-1, FALSE);
  417.             s = acmptr;
  418.             incomm = TRUE;
  419.             comtype = ALTERNATE;
  420.             if (s != os)
  421.             ps ("\\c");
  422.             ps ("\\c\n'+C\n");
  423.             continue;
  424.         }
  425.  
  426.         /* start of a string? */
  427.         if (strptr != NIL)
  428.         if ((strptr < chrptr || chrptr == NIL)
  429.           && (strptr < blksptr || blksptr == NIL)
  430.           && (strptr < blkeptr || blkeptr == NIL)) {
  431.             putKcp (s, strptr-1, FALSE);
  432.             s = strptr;
  433.             instr = TRUE;
  434.             continue;
  435.         }
  436.  
  437.         /* start of a character string? */
  438.         if (chrptr != NIL)
  439.         if ((chrptr < blksptr || blksptr == NIL)
  440.           && (chrptr < blkeptr || blkeptr == NIL)) {
  441.             putKcp (s, chrptr-1, FALSE);
  442.             s = chrptr;
  443.             inchr = TRUE;
  444.             continue;
  445.         }
  446.  
  447.         /* end of a lexical block */
  448.         if (blkeptr != NIL) {
  449.         if (blkeptr < blksptr || blksptr == NIL) {
  450.             putKcp (s, blkeptr - 1, FALSE);
  451.             s = blkeptr;
  452.             blklevel--;
  453.             if (psptr >= 0 && plstack[psptr] >= blklevel) {
  454.  
  455.             /* end of current procedure */
  456.             if (s != os)
  457.                 ps ("\\c");
  458.             ps ("\\c\n'-F\n");
  459.             blklevel = plstack[psptr];
  460.  
  461.             /* see if we should print the last proc name */
  462.             if (--psptr >= 0)
  463.                 prccont = TRUE;
  464.             else
  465.                 psptr = -1;
  466.             }
  467.             continue;
  468.         }
  469.         }
  470.  
  471.         /* start of a lexical block */
  472.         if (blksptr != NIL) {
  473.         putKcp (s, blksptr - 1, FALSE);
  474.         s = blksptr;
  475.         blklevel++;
  476.         continue;
  477.         }
  478.  
  479.     /* check for end of comment */
  480.     } else if (incomm) {
  481.         comptr = expmatch (s, l_comend, dummy);
  482.         acmptr = expmatch (s, l_acmend, dummy);
  483.         if (((comtype == STANDARD) && (comptr != NIL)) ||
  484.             ((comtype == ALTERNATE) && (acmptr != NIL))) {
  485.         if (comtype == STANDARD) {
  486.             putKcp (s, comptr-1, TRUE);
  487.             s = comptr;
  488.         } else {
  489.             putKcp (s, acmptr-1, TRUE);
  490.             s = acmptr;
  491.         }
  492.         incomm = FALSE;
  493.         ps("\\c\n'-C\n");
  494.         continue;
  495.         } else {
  496.         putKcp (s, s + strlen(s) -1, TRUE);
  497.         s = s + strlen(s);
  498.         continue;
  499.         }
  500.  
  501.     /* check for end of string */
  502.     } else if (instr) {
  503.         if ((strptr = expmatch (s, l_strend, dummy)) != NIL) {
  504.         putKcp (s, strptr-1, TRUE);
  505.         s = strptr;
  506.         instr = FALSE;
  507.         continue;
  508.         } else {
  509.         putKcp (s, s+strlen(s)-1, TRUE);
  510.         s = s + strlen(s);
  511.         continue;
  512.         }
  513.  
  514.     /* check for end of character string */
  515.     } else if (inchr) {
  516.         if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) {
  517.         putKcp (s, chrptr-1, TRUE);
  518.         s = chrptr;
  519.         inchr = FALSE;
  520.         continue;
  521.         } else {
  522.         putKcp (s, s+strlen(s)-1, TRUE);
  523.         s = s + strlen(s);
  524.         continue;
  525.         }
  526.     }
  527.  
  528.     /* print out the line */
  529.     putKcp (s, s + strlen(s) -1, FALSE);
  530.     s = s + strlen(s);
  531.     } while (*s);
  532. }
  533.  
  534. putKcp (start, end, force)
  535.     char    *start;        /* start of string to write */
  536.     char    *end;        /* end of string to write */
  537.     boolean    force;        /* true if we should force nokeyw */
  538. {
  539.     int i;
  540.     int xfld = 0;
  541.  
  542.     while (start <= end) {
  543.     if (index) {
  544.         if (*start == ' ' || *start == '\t') {
  545.         if (xfld == 0)    
  546.             printf("");
  547.         printf("\t");
  548.         xfld = 1;
  549.         while (*start == ' ' || *start == '\t')
  550.             start++;
  551.         continue;
  552.         }
  553.     }
  554.  
  555.     /* take care of nice tab stops */
  556.     if (*start == '\t') {
  557.         while (*start == '\t')
  558.         start++;
  559.         i = tabs(_start, start) - margin / 8;
  560.         printf("\\h'|%dn'", i * 10 + 1 - margin % 8);
  561.         continue;
  562.     }
  563.  
  564.     if (!nokeyw && !force)
  565.         if ((*start == '#' || isidchr(*start)) 
  566.         && (start == _start || !isidchr(start[-1]))) {
  567.         i = iskw(start);
  568.         if (i > 0) {
  569.             ps("\\*(+K");
  570.             do 
  571.             putcp(*start++);
  572.             while (--i > 0);
  573.             ps("\\*(-K");
  574.             continue;
  575.         }
  576.         }
  577.  
  578.     putcp (*start++);
  579.     }
  580. }
  581.  
  582.  
  583. tabs(s, os)
  584.     char *s, *os;
  585. {
  586.  
  587.     return (width(s, os) / 8);
  588. }
  589.  
  590. width(s, os)
  591.     register char *s, *os;
  592. {
  593.     register int i = 0;
  594.  
  595.     while (s < os) {
  596.         if (*s == '\t') {
  597.             i = (i + 8) &~ 7;
  598.             s++;
  599.             continue;
  600.         }
  601.         if (*s < ' ')
  602.             i += 2;
  603.         else
  604.             i++;
  605.         s++;
  606.     }
  607.     return (i);
  608. }
  609.  
  610. putcp(c)
  611.     register int c;
  612. {
  613.  
  614.     switch(c) {
  615.  
  616.     case 0:
  617.         break;
  618.  
  619.     case '\f':
  620.         break;
  621.  
  622.     case '{':
  623.         ps("\\*(+K{\\*(-K");
  624.         break;
  625.  
  626.     case '}':
  627.         ps("\\*(+K}\\*(-K");
  628.         break;
  629.  
  630.     case '\\':
  631.         ps("\\e");
  632.         break;
  633.  
  634.     case '_':
  635.         ps("\\*_");
  636.         break;
  637.  
  638.     case '-':
  639.         ps("\\*-");
  640.         break;
  641.  
  642.     case '`':
  643.         ps("\\`");
  644.         break;
  645.  
  646.     case '\'':
  647.         ps("\\'");
  648.         break;
  649.  
  650.     case '.':
  651.         ps("\\&.");
  652.         break;
  653.  
  654.     case '*':
  655.         ps("\\fI*\\fP");
  656.         break;
  657.  
  658.     case '/':
  659.         ps("\\fI\\h'\\w' 'u-\\w'/'u'/\\fP");
  660.         break;
  661.  
  662.     default:
  663.         if (c < 040)
  664.             putchar('^'), c |= '@';
  665.     case '\t':
  666.     case '\n':
  667.         putchar(c);
  668.     }
  669. }
  670.  
  671. /*
  672.  *    look for a process beginning on this line
  673.  */
  674. boolean
  675. isproc(s)
  676.     char *s;
  677. {
  678.     pname[0] = NULL;
  679.     if (!l_toplex || blklevel == 0)
  680.     if (expmatch (s, l_prcbeg, pname) != NIL) {
  681.         return (TRUE);
  682.     }
  683.     return (FALSE);
  684. }
  685.  
  686.  
  687. /*  iskw -    check to see if the next word is a keyword
  688.  */
  689.  
  690. iskw(s)
  691.     register char *s;
  692. {
  693.     register char **ss = l_keywds;
  694.     register int i = 1;
  695.     register char *cp = s;
  696.  
  697.     while (++cp, isidchr(*cp))
  698.         i++;
  699.     while (cp = *ss++)
  700.         if (!STRNCMP(s,cp,i) && !isidchr(cp[i]))
  701.             return (i);
  702.     return (0);
  703. }
  704.