home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d160 / m4.lha / M4 / Src / eval.c next >
C/C++ Source or Header  |  1988-10-02  |  6KB  |  337 lines

  1. /*
  2.  * eval.c
  3.  * Facility: m4 macro processor
  4.  * by: oz
  5.  */
  6.  
  7. #include "mdef.h"
  8. #include "extr.h"
  9.  
  10. extern ndptr lookup();
  11. extern char *strsave();
  12. extern char *mktemp();
  13.  
  14. /*
  15.  * eval - evaluate built-in macros.
  16.  *      argc - number of elements in argv.
  17.  *      argv - element vector :
  18.  *            argv[0] = definition of a user
  19.  *                  macro or nil if built-in.
  20.  *            argv[1] = name of the macro or
  21.  *                  built-in.
  22.  *            argv[2] = parameters to user-defined
  23.  *               .      macro or built-in.
  24.  *               .
  25.  *
  26.  * Note that the minimum value for argc is 3. A call in the form
  27.  * of macro-or-builtin() will result in:
  28.  *            argv[0] = nullstr
  29.  *            argv[1] = macro-or-builtin
  30.  *            argv[2] = nullstr
  31.  *
  32.  */
  33.  
  34. int eval (argv, argc, td)
  35. register char *argv[];
  36. register int argc;
  37. register int  td;
  38. {
  39.     register int c, n;
  40.     static int sysval;
  41.  
  42. #ifdef DEBUG
  43.     printf("argc = %d\n", argc);
  44.     for (n = 0; n < argc; n++)
  45.         printf("argv[%d] = %s\n", n, argv[n]);
  46. #endif
  47.     /*
  48.      * if argc == 3 and argv[2] is null,
  49.      * then we have macro-or-builtin() type call.
  50.      * We adjust argc to avoid further checking..
  51.      *
  52.      */
  53.     if (argc == 3 && !*(argv[2]))
  54.         argc--;
  55.  
  56.     switch (td & ~STATIC) {
  57.  
  58.     case DEFITYPE:
  59.         if (argc > 2)
  60.             dodefine(argv[2], (argc > 3) ? argv[3] : null);
  61.         break;
  62.  
  63.     case PUSDTYPE:
  64.         if (argc > 2)
  65.             dopushdef(argv[2], (argc > 3) ? argv[3] : null);
  66.         break;
  67.  
  68.     case DUMPTYPE:
  69.         dodump(argv, argc);
  70.         break;
  71.  
  72.     case EXPRTYPE:
  73.         /*
  74.          * doexpr - evaluate arithmetic expression
  75.          *
  76.          */
  77.         if (argc > 2)
  78.             pbnum(expr(argv[2]));
  79.         break;
  80.  
  81.     case IFELTYPE:
  82.         if (argc > 4)
  83.             doifelse(argv, argc);
  84.         break;
  85.  
  86.     case IFDFTYPE:
  87.         /*
  88.          * doifdef - select one of two alternatives based
  89.          *         on the existence of another definition
  90.          */
  91.         if (argc > 3) {
  92.             if (lookup(argv[2]) != nil)
  93.                 pbstr(argv[3]);
  94.             else if (argc > 4)
  95.                 pbstr(argv[4]);
  96.         }
  97.         break;
  98.  
  99.     case LENGTYPE:
  100.         /*
  101.          * dolen - find the length of the argument
  102.          *
  103.          */
  104.         if (argc > 2)
  105.             pbnum((argc > 2) ? strlen(argv[2]) : 0);
  106.         break;
  107.  
  108.     case INCRTYPE:
  109.         /*
  110.          * doincr - increment the value of the argument
  111.          *
  112.          */
  113.         if (argc > 2)
  114.             pbnum(atoi(argv[2]) + 1);
  115.         break;
  116.  
  117.     case DECRTYPE:
  118.         /*
  119.          * dodecr - decrement the value of the argument
  120.          *
  121.          */
  122.         if (argc > 2)
  123.             pbnum(atoi(argv[2]) - 1);
  124.         break;
  125.  
  126. #if unix || vms
  127.  
  128.     case SYSCTYPE:
  129.         /*
  130.          * dosys - execute system command
  131.          *
  132.          */
  133.         if (argc > 2)
  134.             sysval = system(argv[2]);
  135.         break;
  136.  
  137.     case SYSVTYPE:
  138.         /*
  139.          * dosysval - return value of the last system call.
  140.          *
  141.          */
  142.         pbnum(sysval);
  143.         break;
  144. #endif
  145.  
  146.     case INCLTYPE:
  147.         if (argc > 2)
  148.             if (!doincl(argv[2])) {
  149.                 fprintf(stderr,"m4: %s: ",argv[2]);
  150.                 error("cannot open for read.");
  151.             }
  152.         break;
  153.  
  154.     case SINCTYPE:
  155.         if (argc > 2)
  156.             (void) doincl(argv[2]);
  157.         break;
  158. #ifdef EXTENDED
  159.     case PASTTYPE:
  160.         if (argc > 2)
  161.             if (!dopaste(argv[2])) {
  162.                 fprintf(stderr,"m4: %s: ",argv[2]);
  163.                 error("cannot open for read.");
  164.             }
  165.         break;
  166.  
  167.     case SPASTYPE:
  168.         if (argc > 2)
  169.             (void) dopaste(argv[2]);
  170.         break;
  171. #endif
  172.     case CHNQTYPE:
  173.         dochq(argv, argc);
  174.         break;
  175.  
  176.     case CHNCTYPE:
  177.         dochc(argv, argc);
  178.         break;
  179.  
  180.     case SUBSTYPE:
  181.         /*
  182.          * dosub - select substring
  183.          *
  184.          */
  185.         if (argc > 3)
  186.             dosub(argv,argc);
  187.         break;
  188.  
  189.     case SHIFTYPE:
  190.         /*
  191.          * doshift - push back all arguments except the
  192.          *         first one (i.e. skip argv[2])
  193.          */
  194.         if (argc > 3) {
  195.             for (n = argc-1; n > 3; n--) {
  196.                 putback(rquote);
  197.                 pbstr(argv[n]);
  198.                 putback(lquote);
  199.                 putback(',');
  200.             }
  201.             putback(rquote);
  202.             pbstr(argv[3]);
  203.             putback(lquote);
  204.         }
  205.         break;
  206.  
  207.     case DIVRTYPE:
  208.         if (argc > 2 && (n = atoi(argv[2])) != 0)
  209.             dodiv(n);
  210.         else {
  211.             active = stdout;
  212.             oindex = 0;
  213.         }
  214.         break;
  215.  
  216.     case UNDVTYPE:
  217.         doundiv(argv, argc);
  218.         break;
  219.  
  220.     case DIVNTYPE:
  221.         /*
  222.          * dodivnum - return the number of current
  223.          * output diversion
  224.          *
  225.          */
  226.         pbnum(oindex);
  227.         break;
  228.  
  229.     case UNDFTYPE:
  230.         /*
  231.          * doundefine - undefine a previously defined
  232.          *        macro(s) or m4 keyword(s).
  233.          */
  234.         if (argc > 2)
  235.             for (n = 2; n < argc; n++)
  236.                 remhash(argv[n], ALL);
  237.         break;
  238.  
  239.     case POPDTYPE:
  240.         /*
  241.          * dopopdef - remove the topmost definitions of
  242.          *          macro(s) or m4 keyword(s).
  243.          */
  244.         if (argc > 2)
  245.             for (n = 2; n < argc; n++)
  246.                 remhash(argv[n], TOP);
  247.         break;
  248.  
  249.     case MKTMTYPE:
  250.         /*
  251.          * dotemp - create a temporary file
  252.          *
  253.          */
  254.         if (argc > 2)
  255.              pbstr(mktemp(argv[2])); 
  256.  
  257.         break;
  258.  
  259.     case TRNLTYPE:
  260.         /*
  261.          * dotranslit - replace all characters in the
  262.          *        source string that appears in
  263.          *        the "from" string with the corresponding
  264.          *        characters in the "to" string.
  265.          *
  266.          */
  267.         if (argc > 3) {
  268.             char temp[MAXTOK];
  269.             if (argc > 4)
  270.                 map(temp, argv[2], argv[3], argv[4]);
  271.             else
  272.                 map(temp, argv[2], argv[3], null);
  273.             pbstr(temp);
  274.         }
  275.         else
  276.             if (argc > 2)
  277.             pbstr(argv[2]);
  278.         break;
  279.  
  280.     case INDXTYPE:
  281.         /*
  282.          * doindex - find the index of the second argument
  283.          *         string in the first argument string.
  284.          *         -1 if not present.
  285.          */
  286.         pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
  287.         break;
  288.  
  289.     case ERRPTYPE:
  290.         /*
  291.          * doerrp - print the arguments to stderr file
  292.          *
  293.          */
  294.         if (argc > 2) {
  295.             for (n = 2; n < argc; n++)
  296.                 fprintf(stderr,"%s ", argv[n]);
  297.             fprintf(stderr, "\n");
  298.         }
  299.         break;
  300.  
  301.     case DNLNTYPE:
  302.         /*
  303.          * dodnl - eat-up-to and including newline
  304.          *
  305.          */
  306.         while ((c = gpbc()) != '\n' && c != EOF)
  307.             ;
  308.         break;
  309.  
  310.     case M4WRTYPE:
  311.         /*
  312.          * dom4wrap - set up for wrap-up/wind-down activity
  313.          *
  314.          */
  315.         m4wraps = (argc > 2) ? strsave(argv[2]) : null;
  316.         break;
  317.  
  318.     case EXITTYPE:
  319.         /*
  320.          * doexit - immediate exit from m4.
  321.          *
  322.          */
  323.         exit((argc > 2) ? atoi(argv[2]) : 0);
  324.         break;
  325.  
  326.     case DEFNTYPE:
  327.         if (argc > 2)
  328.             for (n = 2; n < argc; n++)
  329.                 dodefn(argv[n]);
  330.         break;
  331.  
  332.     default:
  333.         error("m4: major botch in eval.");
  334.         break;
  335.     }
  336. }
  337.