home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume9 / teco / part01 / te_exec0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-03-11  |  5.3 KB  |  228 lines

  1. /* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  2. /* This program and its components belong to GenRad Inc, Concord MA 01742    */
  3. /* They may be copied if this copyright notice is included                    */
  4.  
  5. /* te_exec0.c   execute command string   11/31/86 */
  6. #include "te_defs.h"
  7. #include <sys/time.h>
  8.  
  9. exec_cmdstr()
  10.     {
  11.     char c;
  12.     int digit_sw;
  13.     struct tm *timeptr;
  14.     char *timestring, *asctime();
  15.     struct timeval timevalue, tzvalue;
  16.  
  17.     exitflag = 0;                    /* set flag to "executing" */
  18.     cmdstr.p = cbuf.f;                /* cmdstr to start of command string */
  19.     cmdstr.z = cbuf.z;
  20.     cmdstr.flag = cmdstr.dot = cmdstr.c = 0;    /* clear char ptr and iteration flag */
  21.     msp = &cmdstr;                    /* initialize macro stack pointer */
  22.     esp = &estack[0];                /* initialize expression stack pointer */
  23.     qsp = &qstack[-1];                /* initialize q-reg stack pointer */
  24.     atflag = colonflag = 0;            /* clear flags */
  25.     esp->flag2 = esp->flag1 = 0;    /* initialize expression reader */
  26.     esp->op = OP_START;
  27.     trace_sw = 0;                    /* start out with trace off */
  28.     digit_sw = 0;                    /* and no digits read */
  29.  
  30.     while (!exitflag)                /* until end of command string */
  31.         {
  32.         if (getcmdc0(trace_sw) == '^')        /* interpret next char as corresp. control char */
  33.             cmdc = getcmdc(trace_sw) & 0x1f;
  34.  
  35.         if (isdigit(cmdc))        /* process number */
  36.             {                    /* this works lousy for hex but so does TECO-11 */
  37.             if (cmdc - '0' >= ctrl_r) ERROR(E_ILN);                /* invalid digit */
  38.             if (!(digit_sw++)) esp->val1 = cmdc - '0';            /* first digit */
  39.             else esp->val1 = esp->val1 * ctrl_r + cmdc - '0';    /* other digits */
  40.             esp->flag1++;        /* indicate a value read in */
  41.             }
  42.  
  43.     /* not a digit: dispatch on character */
  44.  
  45.         else
  46.             {
  47.             digit_sw = 0;
  48.             switch (mapch_l[cmdc])
  49.                 {
  50.  
  51. /* characters ignored */
  52.  
  53.                 case CR:
  54.                 case LF:
  55.                 case VT:
  56.                 case FF:
  57.                 case ' ':
  58.                     break;
  59. /* ESC: one absorbs argument, two terminate current level */
  60.  
  61.                 case ESC:
  62.                     if (peekcmdc(ESC))    /* if next char is an ESC */
  63.                         {
  64.                         if (msp <= &mstack[0]) exitflag = 1;    /* pop stack; if empty, terminate */
  65.                         else --msp;
  66.                         }
  67.                     else
  68.                         {
  69.                         esp->flag1 = 0;        /* else consume argument */
  70.                         esp->op = OP_START;
  71.                         }
  72.                     break;
  73.  
  74. /* skip comments */
  75.  
  76.                 case '!':
  77.                     while (getcmdc(trace_sw) != '!');
  78.                     break;
  79.  
  80. /* modifiers */
  81.  
  82.                 case '@':
  83.                     atflag++;
  84.                     break;
  85.  
  86.                 case ':':
  87.                     if (peekcmdc(':'))        /* is it "::" ? */
  88.                         {
  89.                         getcmdc(trace_sw);    /* yes, skip 2nd : */
  90.                         colonflag = 2;        /* and set flag to show 2 */
  91.                         }
  92.                     else colonflag = 1;        /* otherwise just 1 colon */
  93.                     break;
  94.  
  95. /* trace control */
  96.  
  97.                 case '?':
  98.                     trace_sw = !(trace_sw);
  99.                     break;
  100.  
  101. /* values */
  102.  
  103.                 case '.':
  104.                     esp->val1 = dot;
  105.                     esp->flag1 = 1;
  106.                     break;
  107.  
  108.                 case 'z':
  109.                     esp->val1 = z;
  110.                     esp->flag1 = 1;
  111.                     break;
  112.  
  113.                 case 'b':
  114.                     esp->val1 = 0;
  115.                     esp->flag1 = 1;
  116.                     break;
  117.             case 'h':
  118.                     esp->val1 = z;
  119.                     esp->val2 = 0;
  120.                     esp->flag2 = esp->flag1 = 1;
  121.                     esp->op = OP_START;
  122.                     break;
  123.  
  124.                 case CTL (S):        /* -length of last insert, etc. */
  125.                     esp->val1 = ctrl_s;
  126.                     esp->flag1 = 1;
  127.                     break;
  128.  
  129.                 case CTL (Y):        /* .-^S, . */
  130.                     esp->val1 = dot + ctrl_s;
  131.                     esp->val2 = dot;
  132.                     esp->flag1 = esp->flag2 = 1;
  133.                     esp->op = OP_START;
  134.                     break;
  135.  
  136.                 case '(':
  137.                     if (++esp > &estack[ESTACKSIZE-1]) ERROR(E_PDO);
  138.                     esp->flag2 = esp->flag1 = 0;
  139.                     esp->op = OP_START;
  140.                     break;
  141.  
  142.                 case CTL (E):                /* form feed flag */
  143.                     esp->val1 = ctrl_e;
  144.                     esp->flag1 = 1;
  145.                     break;
  146.  
  147.                 case CTL (N):                /* eof flag */
  148.                     esp->val1 = infile->eofsw;
  149.                     esp->flag1 = 1;
  150.                     break;
  151.  
  152.                 case CTL (^):                /* value of next char */
  153.                     esp->val1 = getcmdc(trace_sw);
  154.                     esp->flag1 = 1;
  155.                     break;
  156.  
  157. /* date, time */
  158.  
  159.                 case CTL (B):
  160.                 case CTL (H):
  161.                     gettimeofday(&timevalue, &tzvalue);
  162.                     timeptr = localtime(&timevalue.tv_sec);
  163.                     esp->val1 = (cmdc == CTL (B)) ?
  164.                             timeptr->tm_year * 512   + timeptr->tm_mon * 32  + timeptr->tm_mday :
  165.                             timeptr->tm_hour * 1800  + timeptr->tm_min * 30  + timeptr->tm_sec/2;
  166.                     esp->flag1 = 1;
  167.                     make_buffer(&timbuf);        /* make a time buffer */
  168.                     timestring = asctime(timeptr);
  169.                     for (timbuf.z = 0; timbuf.z < 24; timbuf.z++)        /* copy character string */
  170.                         timbuf.f->ch[timbuf.z] = *(timestring + timbuf.z);
  171.                     break;
  172. /* number of characters to matching ( ) { } [ ] */
  173.  
  174.                 case CTL (P):
  175.                     do_ctlp();
  176.                     break;
  177.  
  178. /* none of the above: incorporate the last value into the expression */
  179.  
  180.                 default:
  181.                     if (esp->flag1)                /* if a value entered */
  182.                         {
  183.                         switch (esp->op)
  184.                             {
  185.                             case OP_START:
  186.                                 break;
  187.  
  188.                             case OP_ADD:
  189.                                 esp->val1 += esp->exp;
  190.                                 esp->op = OP_START;
  191.                                 break;
  192.  
  193.                             case OP_SUB:
  194.                                 esp->val1 = esp->exp - esp->val1;
  195.                                 esp->op = OP_START;
  196.                                 break;
  197.  
  198.                             case OP_MULT:
  199.                                 esp->val1 *= esp->exp;
  200.                                 esp->op = OP_START;
  201.                                 break;
  202.  
  203.                             case OP_DIV:
  204.                                 esp->val1 = (esp->val1) ? esp->exp / esp->val1 : 0;
  205.                                 esp->op = OP_START;
  206.                                 break;
  207.  
  208.                             case OP_AND:
  209.                                 esp->val1 &= esp->exp;
  210.                                 esp->op = OP_START;
  211.                                 break;
  212.  
  213.                             case OP_OR:
  214.                                 esp->val1 |= esp->exp;
  215.                                 esp->op = OP_START;
  216.                                 break;
  217.                             }
  218.                     }                /* end of "if a new value" */
  219.  
  220.                 exec_cmds1();    /* go do the command */
  221.                 }        /* end of command dispatch */
  222.             }        /* end of "not a digit" */
  223.         }        /* end of "while" command loop */
  224.     return;
  225.     }            /* end of exec_cmdstr */
  226.  
  227.  
  228.