home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / m4 / eval.c next >
Encoding:
C/C++ Source or Header  |  1991-04-20  |  7.5 KB  |  375 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Ozan Yigit.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char sccsid[] = "@(#)eval.c    5.4 (Berkeley) 2/26/91";
  39. #endif /* not lint */
  40.  
  41. /*
  42.  * eval.c
  43.  * Facility: m4 macro processor
  44.  * by: oz
  45.  */
  46.  
  47. #include <unistd.h>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include "mdef.h"
  52. #include "extr.h"
  53.  
  54. extern ndptr lookup();
  55.  
  56. /*
  57.  * eval - evaluate built-in macros.
  58.  *      argc - number of elements in argv.
  59.  *      argv - element vector :
  60.  *            argv[0] = definition of a user
  61.  *                  macro or nil if built-in.
  62.  *            argv[1] = name of the macro or
  63.  *                  built-in.
  64.  *            argv[2] = parameters to user-defined
  65.  *               .      macro or built-in.
  66.  *               .
  67.  *
  68.  * Note that the minimum value for argc is 3. A call in the form
  69.  * of macro-or-builtin() will result in:
  70.  *            argv[0] = nullstr
  71.  *            argv[1] = macro-or-builtin
  72.  *            argv[2] = nullstr
  73.  *
  74.  */
  75.  
  76. eval (argv, argc, td)
  77. register char *argv[];
  78. register int argc;
  79. register int  td;
  80. {
  81.     register int c, n;
  82.     static int sysval;
  83.  
  84. #ifdef DEBUG
  85.     printf("argc = %d\n", argc);
  86.     for (n = 0; n < argc; n++)
  87.         printf("argv[%d] = %s\n", n, argv[n]);
  88. #endif
  89.     /*
  90.      * if argc == 3 and argv[2] is null,
  91.      * then we have macro-or-builtin() type call.
  92.      * We adjust argc to avoid further checking..
  93.      *
  94.      */
  95.     if (argc == 3 && !*(argv[2]))
  96.         argc--;
  97.  
  98.     switch (td & ~STATIC) {
  99.  
  100.     case DEFITYPE:
  101.         if (argc > 2)
  102.             dodefine(argv[2], (argc > 3) ? argv[3] : null);
  103.         break;
  104.  
  105.     case PUSDTYPE:
  106.         if (argc > 2)
  107.             dopushdef(argv[2], (argc > 3) ? argv[3] : null);
  108.         break;
  109.  
  110.     case DUMPTYPE:
  111.         dodump(argv, argc);
  112.         break;
  113.  
  114.     case EXPRTYPE:
  115.         /*
  116.          * doexpr - evaluate arithmetic expression
  117.          *
  118.          */
  119.         if (argc > 2)
  120.             pbnum(expr(argv[2]));
  121.         break;
  122.  
  123.     case IFELTYPE:
  124.         if (argc > 4)
  125.             doifelse(argv, argc);
  126.         break;
  127.  
  128.     case IFDFTYPE:
  129.         /*
  130.          * doifdef - select one of two alternatives based
  131.          *         on the existence of another definition
  132.          */
  133.         if (argc > 3) {
  134.             if (lookup(argv[2]) != nil)
  135.                 pbstr(argv[3]);
  136.             else if (argc > 4)
  137.                 pbstr(argv[4]);
  138.         }
  139.         break;
  140.  
  141.     case LENGTYPE:
  142.         /*
  143.          * dolen - find the length of the argument
  144.          *
  145.          */
  146.         if (argc > 2)
  147.             pbnum((argc > 2) ? strlen(argv[2]) : 0);
  148.         break;
  149.  
  150.     case INCRTYPE:
  151.         /*
  152.          * doincr - increment the value of the argument
  153.          *
  154.          */
  155.         if (argc > 2)
  156.             pbnum(atoi(argv[2]) + 1);
  157.         break;
  158.  
  159.     case DECRTYPE:
  160.         /*
  161.          * dodecr - decrement the value of the argument
  162.          *
  163.          */
  164.         if (argc > 2)
  165.             pbnum(atoi(argv[2]) - 1);
  166.         break;
  167.  
  168.     case SYSCTYPE:
  169.         /*
  170.          * dosys - execute system command
  171.          *
  172.          */
  173.         if (argc > 2)
  174.             sysval = system(argv[2]);
  175.         break;
  176.  
  177.     case SYSVTYPE:
  178.         /*
  179.          * dosysval - return value of the last system call.
  180.          *
  181.          */
  182.         pbnum(sysval);
  183.         break;
  184.  
  185.     case INCLTYPE:
  186.         if (argc > 2)
  187.             if (!doincl(argv[2])) {
  188.                 fprintf(stderr,"m4: %s: ",argv[2]);
  189.                 error("cannot open for read.");
  190.             }
  191.         break;
  192.  
  193.     case SINCTYPE:
  194.         if (argc > 2)
  195.             (void) doincl(argv[2]);
  196.         break;
  197. #ifdef EXTENDED
  198.     case PASTTYPE:
  199.         if (argc > 2)
  200.             if (!dopaste(argv[2])) {
  201.                 fprintf(stderr,"m4: %s: ",argv[2]);
  202.                 error("cannot open for read.");
  203.             }
  204.         break;
  205.  
  206.     case SPASTYPE:
  207.         if (argc > 2)
  208.             (void) dopaste(argv[2]);
  209.         break;
  210. #endif
  211.     case CHNQTYPE:
  212.         dochq(argv, argc);
  213.         break;
  214.  
  215.     case CHNCTYPE:
  216.         dochc(argv, argc);
  217.         break;
  218.  
  219.     case SUBSTYPE:
  220.         /*
  221.          * dosub - select substring
  222.          *
  223.          */
  224.         if (argc > 3)
  225.             dosub(argv,argc);
  226.         break;
  227.  
  228.     case SHIFTYPE:
  229.         /*
  230.          * doshift - push back all arguments except the
  231.          *         first one (i.e. skip argv[2])
  232.          */
  233.         if (argc > 3) {
  234.             for (n = argc-1; n > 3; n--) {
  235.                 putback(rquote);
  236.                 pbstr(argv[n]);
  237.                 putback(lquote);
  238.                 putback(',');
  239.             }
  240.             putback(rquote);
  241.             pbstr(argv[3]);
  242.             putback(lquote);
  243.         }
  244.         break;
  245.  
  246.     case DIVRTYPE:
  247.         if (argc > 2 && (n = atoi(argv[2])) != 0)
  248.             dodiv(n);
  249.         else {
  250.             active = stdout;
  251.             oindex = 0;
  252.         }
  253.         break;
  254.  
  255.     case UNDVTYPE:
  256.         doundiv(argv, argc);
  257.         break;
  258.  
  259.     case DIVNTYPE:
  260.         /*
  261.          * dodivnum - return the number of current
  262.          * output diversion
  263.          *
  264.          */
  265.         pbnum(oindex);
  266.         break;
  267.  
  268.     case UNDFTYPE:
  269.         /*
  270.          * doundefine - undefine a previously defined
  271.          *        macro(s) or m4 keyword(s).
  272.          */
  273.         if (argc > 2)
  274.             for (n = 2; n < argc; n++)
  275.                 remhash(argv[n], ALL);
  276.         break;
  277.  
  278.     case POPDTYPE:
  279.         /*
  280.          * dopopdef - remove the topmost definitions of
  281.          *          macro(s) or m4 keyword(s).
  282.          */
  283.         if (argc > 2)
  284.             for (n = 2; n < argc; n++)
  285.                 remhash(argv[n], TOP);
  286.         break;
  287.  
  288.     case MKTMTYPE:
  289.         /*
  290.          * dotemp - create a temporary file
  291.          *
  292.          */
  293.         if (argc > 2)
  294.             pbstr(mktemp(argv[2]));
  295.         break;
  296.  
  297.     case TRNLTYPE:
  298.         /*
  299.          * dotranslit - replace all characters in the
  300.          *        source string that appears in
  301.          *        the "from" string with the corresponding
  302.          *        characters in the "to" string.
  303.          *
  304.          */
  305.         if (argc > 3) {
  306.             char temp[MAXTOK];
  307.             if (argc > 4)
  308.                 map(temp, argv[2], argv[3], argv[4]);
  309.             else
  310.                 map(temp, argv[2], argv[3], null);
  311.             pbstr(temp);
  312.         }
  313.         else
  314.             if (argc > 2)
  315.             pbstr(argv[2]);
  316.         break;
  317.  
  318.     case INDXTYPE:
  319.         /*
  320.          * doindex - find the index of the second argument
  321.          *         string in the first argument string.
  322.          *         -1 if not present.
  323.          */
  324.         pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
  325.         break;
  326.  
  327.     case ERRPTYPE:
  328.         /*
  329.          * doerrp - print the arguments to stderr file
  330.          *
  331.          */
  332.         if (argc > 2) {
  333.             for (n = 2; n < argc; n++)
  334.                 fprintf(stderr,"%s ", argv[n]);
  335.             fprintf(stderr, "\n");
  336.         }
  337.         break;
  338.  
  339.     case DNLNTYPE:
  340.         /*
  341.          * dodnl - eat-up-to and including newline
  342.          *
  343.          */
  344.         while ((c = gpbc()) != '\n' && c != EOF)
  345.             ;
  346.         break;
  347.  
  348.     case M4WRTYPE:
  349.         /*
  350.          * dom4wrap - set up for wrap-up/wind-down activity
  351.          *
  352.          */
  353.         m4wraps = (argc > 2) ? strdup(argv[2]) : null;
  354.         break;
  355.  
  356.     case EXITTYPE:
  357.         /*
  358.          * doexit - immediate exit from m4.
  359.          *
  360.          */
  361.         exit((argc > 2) ? atoi(argv[2]) : 0);
  362.         break;
  363.  
  364.     case DEFNTYPE:
  365.         if (argc > 2)
  366.             for (n = 2; n < argc; n++)
  367.                 dodefn(argv[n]);
  368.         break;
  369.  
  370.     default:
  371.         error("m4: major botch in eval.");
  372.         break;
  373.     }
  374. }
  375.