home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / ease-3.5 / src / lexan.l < prev    next >
Encoding:
Lex Description  |  1991-05-16  |  8.6 KB  |  355 lines

  1. %{
  2.  
  3. #ifdef FLUKE
  4. # ifndef LINT
  5.     static char RCSid[] = "@(#)FLUKE  $Header: /home/kreskin/u0/barnett/Src/ease/src/RCS/lexan.l,v 3.2 1991/05/16 10:45:25 barnett Exp $";
  6. # endif LINT
  7. #endif FLUKE
  8.  
  9. /*
  10.  *    lexan.l -- Lexical Analyzer for EASE.
  11.  *
  12.  *           Contains code for lex(1) which generates a lexical
  13.  *           analyzer (lex.yy.c) for Ease, a high-level specification 
  14.  *           format for sendmail configuration files.
  15.  *
  16.  *    author -- James S. Schoner, Purdue University Computing Center,
  17.  *                    West Lafayette, Indiana  47907
  18.  *
  19.  *    date   -- July 1, 1985
  20.  *
  21.  *    Copyright (c) 1985 by Purdue Research Foundation
  22.  *
  23.  *    All rights reserved.
  24.  *
  25.  * $Log: lexan.l,v $
  26.  * Revision 3.2  1991/05/16  10:45:25  barnett
  27.  * Better support for System V machines
  28.  * Support for machines with read only text segments
  29.  *
  30.  * Revision 3.1  1991/02/25  22:09:52  barnett
  31.  * Fixed some portability problems
  32.  *
  33.  * Revision 3.0  1991/02/22  18:50:27  barnett
  34.  * Added support for HP/UX and IDA sendmail.
  35.  *
  36.  * Revision 2.3  1991/02/12  20:49:34  barnett
  37.  * Added several new tokens.
  38.  * Merged Jeff's changes with my own.
  39.  *
  40.  * Revision 2.2  1990/05/07  11:12:53  jeff
  41.  * Add support for the "Cflag" variable which controls whether or not
  42.  * input lines are passed through as comments in the output stream.
  43.  *
  44.  * Version 2.1  90/01/30  15:26:23  jeff
  45.  * If -C flag is specified, emit input as comments in the output stream.
  46.  * 
  47.  * Revision 2.0  88/06/15  15:11:30  root
  48.  * Baseline release for net posting. ADR.
  49.  * 
  50.  */
  51.  
  52. #include "fixstrings.h"
  53. #include "symtab.h"
  54. #include "lexdefs.h"
  55.  
  56. #define  LEXnewline '\n'
  57. #define     LEXeof        '\0'
  58. #define  MaxFN        200            /* maximum file name length */
  59.  
  60. extern int      EchoInputAsComments;
  61. extern struct he *LookupSymbol ();
  62. extern void      ErrorReport ();
  63. extern void      yymark();
  64. extern void      PrintError();
  65. extern char *      malloc ();
  66.  
  67. int  Lcount;                /* line counter            */
  68. char FNbuf[MaxFN];            /* file name buffer        */
  69. short RMatch  = FALSE;            /* ruleset match flag          */
  70.  
  71. #ifdef YYDEBUG
  72. extern int yychar;
  73. #else
  74. int   yychar;
  75. #endif
  76.  
  77. #undef input
  78. # define input() (((yytchar=yychar=yysptr>yysbuf?U(*--yysptr):Getc(yyin,yyout))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
  79.  
  80. int
  81. Getc (yyin, yyout)
  82.     FILE *yyin, *yyout;
  83. {
  84.     static char linbuf[BUFSIZ], *pc = linbuf;
  85.     char c;
  86.  
  87.     /* initialize buffer: first call only */
  88.     if (*pc == '\0' && pc == linbuf) {
  89.         if (fgets(linbuf, BUFSIZ, yyin)==NULL)
  90.             return EOF;
  91.         /* echo input as comment */
  92.         if (EchoInputAsComments) {
  93.             fprintf(yyout, "%s%s", (linbuf[0] == '#' ? "" : "# "), linbuf);
  94.         }
  95.     }
  96.     c = *pc++;
  97.     if (c == '\n') {
  98.         pc = linbuf;
  99.         if (fgets(linbuf, BUFSIZ, yyin) == NULL)
  100.             *pc = (char) EOF;
  101.         else
  102.             /* echo input as comment (except cpp comments) */
  103.             if (EchoInputAsComments) {
  104.                 fprintf(yyout, "%s%s",
  105.                 (linbuf[0] == '#' ? "" : "# "), linbuf);
  106.             }
  107.     }
  108.      return (c == (char) EOF) ? EOF : c;
  109. }
  110.  
  111. /*
  112.  * Table of keywords. NOTE: This is in sorted order, and
  113.  * must stay that way if anything else is added to it.
  114.  */
  115. static struct resword {
  116.     char    *r_text;
  117.     int    r_tokval;
  118. } reswords[] = {
  119.     { "Argv",        MARGV },
  120.     { "Eol",        MEOL },
  121.     { "Flags",        MFLAGS },
  122.     { "Maxsize",        MMAXSIZE },
  123.     { "Path",        MPATH },
  124.     { "Recipient",        MRECIPIENT },
  125.     { "Sender",        MSENDER },
  126.      { "alias",        ALIAS },
  127.      { "asm",        ASM },
  128.     { "bind",        BIND },
  129.     { "canon",        CANON },
  130.     { "class",        CLASS },
  131.     { "concat",        CONCAT },
  132.     { "d_background",    DOPTB },
  133.     { "d_interactive",    DOPTI },
  134.     { "d_queue",        DOPTQ },
  135.     { "dbm",        DBM },       /* IDA */
  136.     { "default",        DEFAULT }, /* IDA */
  137.     { "define",        DEFINE },
  138.      { "eval",        EVAL },
  139.     { "f_addrw",        CCFLAG },
  140.     { "f_arpa",        AAFLAG },
  141.      { "f_bsmtp",        BBFLAG },    /* IDA */
  142.     { "f_date",        DDFLAG },
  143.     { "f_dot",        XXFLAG },
  144.     { "f_escape",        EEFLAG },
  145.     { "f_expensive",    EFLAG },
  146.     { "f_ffrom",        FFLAG },
  147.     { "f_from",        FFFLAG },
  148.     { "f_full",        XFLAG },
  149.     { "f_llimit",        LLFLAG },
  150.     { "f_locm",        LFLAG },
  151.     { "f_mail11",        HHFLAG },  /* Ultrix */
  152.     { "f_mesg",        MMFLAG },
  153.     { "f_mult",        MFLAG },
  154.     { "f_noreset",        SSFLAG },
  155.     { "f_noufrom",        NFLAG },
  156.      { "f_relativize",    VVFLAG },    /* IDA */
  157.     { "f_retsmtp",        PFLAG },
  158.     { "f_return",        PPFLAG },
  159.     { "f_rfrom",        RFLAG },
  160.     { "f_rport",        RRFLAG },
  161.     { "f_smtp",        IIFLAG },
  162.     { "f_strip",        SFLAG },
  163.     { "f_ufrom",        UUFLAG },
  164.     { "f_upperh",        HFLAG },
  165.     { "f_upperu",        UFLAG },
  166.     { "field",        FIELD },
  167.     { "for",        FOR },
  168.     { "h_exit",        EOPTE },
  169.     { "h_mail",        EOPTM },
  170.     { "h_mailz",        EOPTZ },
  171.     { "h_print",        EOPTP },
  172.     { "h_write",        EOPTW },
  173.     { "header",        HEADER },
  174.     { "host",        HOST },
  175.     { "hostnum",        HOSTNUM },
  176.     { "if",            IF },
  177.     { "ifset",        IFSET },
  178.     { "in",            IN },
  179.     { "macro",        MACRO },
  180.     { "mailer",        MAILER },
  181.     { "map",        MAP },
  182.     { "match",        MATCH },
  183.     { "next",        NEXT },
  184.     { "o_alias",        AAOPT },
  185.      { "o_aliasfile",    YYOPT },    /* SunOS */
  186.     { "o_bsub",        BBOPT },
  187.     { "o_checkpoint",    CCOPT },
  188.     { "o_delivery",        DOPT },
  189.     { "o_dmuid",        UOPT },
  190.     { "o_dnet",        NNOPT },
  191.      { "o_envelope",        SLOPT },    /* IDA */
  192.     { "o_ewait",        AOPT },
  193.     { "o_flog",        SSOPT },
  194.     { "o_fsmtp",        HHOPT },
  195.     { "o_gid",        GOPT },
  196.     { "o_handling",        EOPT },
  197.     { "o_hformat",        OOPT },
  198.     { "o_loadnc",        XXOPT },
  199.     { "o_loadq",        XOPT },
  200.     { "o_maxempty",        BOPT },    /* SunOS */
  201.      { "o_maxhops",        HOPT }, /* SunOS */
  202.       { "o_nameserver",    IIOPT }, /* HP/UX */
  203.       { "o_newproc",        YYOPT },
  204.      { "o_nfs",        RROPT },    /* SunOS 4.0 */
  205.     { "o_pmaster",        PPOPT },
  206.     { "o_prifactor",    ZOPT },
  207.     { "o_qdir",        QQOPT },
  208.     { "o_qfactor",        QOPT },
  209.     { "o_qtimeout",        TTOPT },
  210.     { "o_qwait",        COPT },
  211.     { "o_rebuild",        DDOPT },
  212.     { "o_recipfactor",    YOPT },
  213.     { "o_rsend",        MOPT },
  214.     { "o_safe",        SOPT },
  215.     { "o_skipd",        IOPT },
  216.     { "o_slog",        LLOPT },
  217.     { "o_timezone",        TOPT },
  218.     { "o_tmode",        FFOPT },
  219.     { "o_tread",        ROPT },
  220.     { "o_usave",        FOPT },
  221.     { "o_validate",        NOPT },
  222.     { "o_verbose",        VOPT },
  223.     { "o_waitfactor",    ZZOPT },
  224.     { "o_wizpass",        WWOPT },
  225.     { "options",        OPTIONS },
  226.     { "precedence",        PRECEDENCE },
  227.      { "program",        PROGRAM },    /* HP/UX */
  228.      { "quote",        QUOTE },
  229.     { "readclass",        READCLASS },
  230.     { "resolve",        RESOLVE },
  231.      { "resolved",        RESOLVED },
  232.     { "retry",        RETRY },
  233.     { "return",        RETURN },
  234.     { "ruleset",        RULESET },
  235.     { "trusted",        TRUSTED },
  236.     { "user",        USER },
  237.     { "while",        IF },
  238.      { "ypalias",        YPALIAS },    /* Ultrix */
  239.      { "ypmap",        YPMAP },    /* SunOS */
  240.      { "yppasswd",        YPPASSWD },    /* Ultrix */
  241. };
  242. %}
  243.  
  244. %%
  245.     int INch;            /* any input character */
  246.  
  247. [ \t\f]+            ;     /* discard whitepsace  */
  248. [\n]                Lcount++;
  249. ^\#[ \t]*[0-9]+[ \t]*\".*\"[ \t]*.*[\n]    {
  250. /*                    sscanf (yytext, "%*c%d%s", &Lcount, FNbuf); */
  251.                             yymark();
  252.                     }
  253. [A-Za-z_][A-Za-z0-9_-]*        {
  254.                 register int l, h, m, r, c;
  255.  
  256.                 l = 0;
  257.                 h = (sizeof (reswords) / sizeof(reswords[0])) - 1;
  258.                 while (l <= h) {
  259.                     m = (h + l) / 2;
  260.                     c = yytext[0] - reswords[m].r_text[0];
  261.                     r = c ? c : strcmp (yytext, reswords[m].r_text);
  262.                     if (r < 0)
  263.                         h = m - 1;
  264.                     else if (r > 0)
  265.                         l = m + 1;
  266.                     else
  267.                         return reswords[m].r_tokval;
  268.                 }
  269.  
  270.                 /* not a keyword */
  271.  
  272.                 /* store identifiers in symbol table */
  273.                 yylval.phe = LookupSymbol (yytext);
  274.                 return (IDENT);
  275.                 }
  276. ["]((\\\n)|(\\\")|[^"\n])*    {
  277.                 if ((INch = input()) == LEXnewline) {
  278.                     ErrorReport ("End of line in string.\n");
  279.                     unput (INch);
  280.                 }
  281.                 fixquotes ();
  282.                 yylval.psb = (char *) malloc (strlen (yytext) + 1);
  283.                 strcpy (yylval.psb, yytext + 1);
  284.                 return (SCONST);
  285.                 }
  286. [0][0-7]*            {
  287.                 sscanf (yytext, "%o", &yylval.ival);  /* octal constant */
  288.                 return (ICONST);
  289.                 }
  290. [-]?[1-9][0-9]*            {
  291.                 yylval.ival = atoi (yytext);
  292.                 return (ICONST);
  293.                 }
  294. "="                return (ASGN);
  295. ","                return (COMMA);
  296. "{"                return (LBRACE);
  297. "}"                return (RBRACE);
  298. "("                return (LPAREN);
  299. ")"                return (RPAREN);
  300. ";"                return (SEMI);
  301. "$"                return (DOLLAR);
  302. ":"                return (COLON);
  303. "*"                return (STAR);
  304. "/*"                {
  305.                 /* eat C comments */
  306.                 INch = input ();
  307.                 while ((INch != '*') || 
  308.                       ((INch = input ()) != '/')) {
  309.                     if (INch == LEXnewline)
  310.                         Lcount++;
  311.                     else
  312.                         if (INch == LEXeof) {
  313.                             ErrorReport ("End of file in comment.\n");
  314.                             break;
  315.                         }
  316.                     if (INch != '*')
  317.                         INch = input ();
  318.                 }
  319.                 }
  320. "/"                return (SLASH);
  321. [\\]?.                {
  322.                 if (RMatch) {    /* in rulesets, return literal character */
  323.                     yylval.ival = (yytext[0] == '\\') ? yytext[1] : yytext[0];
  324.                     return (SEPCHAR);
  325.                 } else {
  326.                     PrintError ("Illegal delimiter character: (octal code) \\%03o", *yytext);
  327.                 }
  328.                 }
  329. %%
  330.  
  331. /*
  332.  * fixquotes --- inside a "quoted string", turn `\"' into just `"'
  333.  *
  334.  * this is most useful inside the Argv strings for mailers,
  335.  * particularly when debugging.
  336.  */
  337.  
  338. fixquotes ()
  339. {
  340.     register char *cp1, *cp2;
  341.  
  342.     cp1 = cp2 = yytext;
  343.     while (*cp2) {
  344.         /*
  345.          * if we really wanted to get fancy,
  346.          * at this point we'd handle C escapes,
  347.          * but I don't think it's necessary.
  348.          */
  349.         if (*cp2 == '\\' && cp2[1] == '"')
  350.             cp2++;
  351.         *cp1++ = *cp2++;
  352.     }
  353.     *cp1++ = *cp2++;    /* final '\0' */
  354. }
  355.