home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 138.lha / M4 / Sources / eval.c next >
C/C++ Source or Header  |  1986-11-20  |  10KB  |  298 lines

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