home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 178_01 / tvx_lex.c < prev    next >
C/C++ Source or Header  |  1986-01-17  |  14KB  |  530 lines

  1. /* -------------------------- tvx_lex.c ----------------------------------- */
  2. #include "tvx_defs.ic"
  3.  
  4. /* -------------------------- GLOBALS GO HERE -------------------------------*/
  5. #define EXTERN
  6.  
  7. #include "tvx_glbl.ic"
  8.  
  9.    char clower(),cupper();
  10.  
  11. /* =============================>>> CHECKOS <<<============================= */
  12.   checkos()
  13.   {
  14.     /* check if ok operating system */
  15. #ifdef MSDOS
  16.     if ((bdos(0x30,0) & 0xff) < 2)        /* !!! cii-86 dependent */
  17.       {
  18.     remark("TVX requires MS-DOS 2.0 or later");
  19.     exit();
  20.       }
  21. #endif
  22.   }
  23.  
  24. /* =============================>>> STARTM <<<============================= */
  25.   startm()
  26.   {
  27.     prompt("TVX - Full Screen Editor ");
  28.     prompt(VERSION); prompt("Terminal: ");
  29.     remark(cversn);
  30.     remark("");
  31.     remark("? for help");
  32.     remark("");
  33.   }
  34.  
  35. /* =============================>>> MEMORY <<<============================= */
  36.   memory()
  37.   { /* memory - print memory left */
  38.  
  39.     SLOW int nxt,chrsavail;
  40.     SLOW unsigned int tmp;
  41.  
  42.     char value[10],msg[85],*cp,stemp[80];
  43.  
  44.     nxt = 0;            /* where message goes */
  45.  
  46.     stcopy(" Chrs left:",0,stemp,&nxt);    /* add ' Chars: ' */
  47.  
  48. #ifdef LASL
  49.     tmp = max(nxtsav - nxtchr - BUFFLIMIT,0);
  50. #else
  51.     tmp = nxtsav - nxtchr;
  52. #endif
  53.  
  54. #ifdef INT16
  55.     if (tmp > 30000)        /* handle "neg" size */
  56.       {
  57.     stemp[nxt++] = '+';
  58.     tmp -= 30000;
  59.       }
  60. #endif
  61.  
  62.     itoa(tmp,value);
  63.     stcopy(value,0,stemp,&nxt);    /* the value */
  64.  
  65.     stcopy(" Last line:",0,stemp,&nxt);    /* add ' Lines: ' */
  66.     itoa(nxtlin-1,value);
  67.     stcopy(value,0,stemp,&nxt);    /* add the count */
  68.  
  69. #ifdef STATCURLINE
  70.     stcopy(" Cur line:",0,stemp,&nxt); /* add ' Cur line: ' */
  71.     itoa(curlin,value);
  72. #endif
  73. #ifdef STATREPEAT
  74.     stcopy(" Rpt:",0,stemp,&nxt); /* add ' Rpt: ' */
  75.     itoa(rptuse+1,value);
  76.     stcopy(value,0,stemp,&nxt);    /* the count */
  77.  
  78.     stcopy("/",0,stemp,&nxt); /* add '/' */
  79.     itoa(REPEATBUFS,value);
  80. #endif
  81.     stcopy(value,0,stemp,&nxt);
  82.     chrsavail=80-strlen(stemp);
  83.     nxt=0;            /* where message goes */
  84.     cp = (*dest_file ? dest_file : orig_file);
  85.     stcopy(cp,max(strlen(cp)-chrsavail,0),msg,&nxt);    /* the file name */
  86.     if (strlen(VERSION) <= chrsavail-nxt)
  87.      {
  88.        stcopy(VERSION,0,msg,&nxt); /* TVX */
  89.          if (strlen(cversn) <= chrsavail-nxt)
  90.            stcopy(cversn,0,msg,&nxt);  /* terminal type */
  91.      }
  92.        stcopy(stemp,0,msg,&nxt);   /* rest of string */
  93.  
  94.     tverr(msg);     /* display line on screen */
  95.  }
  96.  
  97. /* =============================>>> SHOSET  <<<============================= */
  98.   shoset()
  99.   {  /* show repeat buffer, help if available */
  100.  
  101. #ifdef HELP
  102.     static char rp[2];
  103.     FAST int i;
  104.     SLOW char *cp, *msg;
  105.     SLOW int fields, oldtty, hnum;
  106.     SLOW unsigned tmp;
  107.  
  108. #ifdef FULLHELP
  109.     struct help_msg 
  110.       {
  111.     char *hmsg;
  112.     char Vmsg;
  113.       };
  114.  
  115.     static struct help_msg cmddes[] =    /* messages for help */
  116.       {
  117.     {"nApnd to sv buff",    VSAPPEND},
  118.     {" Buffer beg     ",      VTOP},
  119.     {" File beg",         VFBEGIN},
  120.     {"nChange chars   ",    VCHANGE},
  121.     {"nDown line      ",     VDOWNLINE},
  122.     {"nDown column",     VDOWNCOL},
  123.     {" Buffer end     ",    VBOTTOM},
  124.     {"nEdit rpt buffer",     VEDITRPT},
  125.     {"nFind",         VSEARCH},
  126.     {" Find cross-buff",    VNEXT},
  127.     {" Get save buffer",     VGET},
  128.     {" Unkill lastline",     VUNKILL},
  129.     {"nHalf page      ",    VHALFP},
  130.     {"nInsert (to ESC)",     VINSERT},
  131.     {" Jump back",         VJUMP},
  132.     {"nKill character ",    VDELNEXT},
  133.     {"nKill line      ",     VKILLALL},
  134.     {"nLeft",         VLEFT},
  135.     {" Memory status  ",    VMEMORY},
  136.     {"nNote location  ",     VNOTELOC},
  137.     {"nReset loc",         VRETNOTE},
  138.     {"nOpen line      ",    VOPENLINE},
  139.     {" Call Opr system",     VSYSTEM},
  140.     {"nPage",         VFLIP},
  141.     {" Print screen   ",    VPRINTS},
  142.     {"nRight          ",    VRIGHT},
  143.     {" Restore rpt buf",     VSTORERPT},
  144.     {"nSave lines     ",    VSAVE},
  145.     {"nTidy, fill text",     VTIDY},
  146.     {" Abort",         VABORT},
  147.     {"nUp             ",    VUPLINE},
  148.     {"nUp column      ",     VUPCOL},
  149.     {" Verify screen",     VVERIFY},
  150.     {"nWrite buffer   ",    VWPAGE},
  151.     {" Exit, end edit ",     VQUIT},
  152.     {"nYank file",         VYANK},
  153.     {"nDel prev char  ",    VDELLAST},
  154.     {"nFind again     ",     VSAGAIN},
  155.     {" Del last",         VREMOVE},
  156.     {" Change last    ",    VRMVINS},
  157.     {" Del to line beg",     VKILLPREV},
  158.     {" Del to line end",     VKILLREST},
  159.     {" Line begining  ",    VBEGLINE},
  160.     {" Line end       ",     VENDLINE},
  161.     {"nWord right",         VMVWORD},
  162.     {"nWord left      ",    VMVBWORD},
  163.     {"nRepeat again   ",     VXREPEAT},
  164.     {"nk Exec rpt k n times", VEXECRPT},
  165.     {"n p Set param p ",    VSETPARS},
  166.     {" Help           ",     VHELP},
  167.     {" Insert find pat",     VINSPAT},
  168.     {"/",0}            /* last variable entry */
  169.       };
  170. #endif
  171.  
  172.     oldtty = ttymode;
  173.     ttymode = FALSE;
  174.     if (!oldtty)
  175.     tvclr();
  176.  
  177.     prompt("Parameter : cur val (1=y, 0=n)    Prev 16 cmds:");
  178.     for (hnum = 0,i = old_cindex ; hnum < 16 ; ++hnum)
  179.       {
  180.     shocout(old_cmds[i]);
  181.     i = ++i % 16;
  182.       }
  183.  
  184.     remark("");
  185.     prompt("A-Autoindent: "); wtint(autoin);
  186.     prompt("  T-TTY mode: "); wtint(ttymode);
  187.     prompt("  E-Expand tabs: "); wtint(tabspc); remark("");
  188.  
  189.     prompt("F-Find: ignore case: "); 
  190.     if (xcases)
  191.         tvcout('0');
  192.     else
  193.         tvcout('1');
  194.  
  195.     prompt("    M-Match wild cards: "); wtint(use_wild); remark("");
  196.     prompt("U-User wild card set: "); remark(user_set);
  197.  
  198.     prompt("D disp line:"); wtint(dsplin); 
  199.     prompt("  S-Scroll window:"); wtint(scroll);
  200.     prompt("  V-Virtual window:"); wtint(tvlins); 
  201.     prompt("/"); wtint(tvhardlines);
  202.     prompt("  W-Wrap width:"); wtint(wraplm); remark("");
  203.     prompt("O-Output file: "); prompt(dest_file);
  204.     prompt("  (input file is: ");prompt(orig_file); remark(")");
  205.     remark("");
  206.  
  207.     prompt("Find: |");
  208.     for (cp = sbuff ; *cp ; ++cp)
  209.       {
  210.     shocout(*cp);
  211.       }
  212.     remark("|");
  213.     remark("");
  214.     prompt("Max chars: ");
  215.     tmp = mxbuff;
  216. #ifdef INT16
  217.     if (tmp > 30000)        /* handle "neg" size */
  218.       {
  219.     prompt("30000+");
  220.     tmp -= 30000;
  221.       }
  222. #endif
  223.     wtint(tmp); prompt("  Max lines: ");    wtint(mxline);
  224.     prompt("  Cur line: "); wtint(curlin);
  225.     if (usecz)
  226.     prompt("    ^Z for EOF");
  227.     remark("");
  228.     remark("");
  229.  
  230.     prompt("R-Repeat buffer: ");wtint(rptuse+1);
  231.     remark("   All repeat buffers : <contents>:");
  232.     for (i = 0 ; i < REPEATBUFS ; ++ i)
  233.       {
  234.     fields = 5;
  235.     shocout('#') ; shocout(i+'1') ; prompt(": <");
  236.     for (cp = &rptbuf[i][0] ; *cp ; ++cp)
  237.       {
  238.         shocout(*cp);
  239.         ++fields;        /* how many letters */
  240.         if (*cp < ' ')
  241.         ++fields;
  242.         if (fields >= (tvcols - 6))
  243.           {
  244.         prompt("+more+");
  245.         break;
  246.           }
  247.       }
  248.     remark("");
  249.       }
  250.  
  251.     ttymode = oldtty;
  252.     memory();
  253.  
  254. #ifdef FULLHELP
  255.     tvxy(1,22);
  256.  
  257.     ask("Press space to exit, anything else for command list ",rp,1);
  258.  
  259.     if (*rp == ' ')
  260.       {
  261.     ttymode = oldtty;
  262.     verify(1);
  263.     return;
  264.       }
  265.  
  266.     if (!oldtty)
  267.     tvclr();
  268.  
  269.     remark("Commands (n => count allowed):");
  270.     for (hnum = fields = 0  ; ; ++hnum )
  271.       {
  272.     prompt("   ");
  273.     cp = cmddes[hnum].hmsg;
  274.     if (*cp == '/')    /* end of variable list */
  275.         break;
  276.     else
  277.         shocout(*cp);    /* show n or blank */
  278.     msg = ++cp;        /* where message is, skipping 'n' field */
  279.     while (*cp)        /* ship to lex value */
  280.         ++cp;
  281.     i = cmddes[hnum].Vmsg;        /* get the lexical index */
  282.     shocout(cupper(lexsym[i]));    /* show the command */
  283.     if (lexsym[i] >= ' ')
  284.         shocout(' ');    /* skip space for no '^' */
  285.  
  286.     shocout(' ');        /* space to separate */
  287.     prompt(msg);        /* and show the message */
  288.     if (++fields == 3)    /* bump fields, see if need newline */
  289.       {
  290.         fields = 0;
  291.         remark("");
  292.       }
  293.       }
  294.     remark("");
  295.     remark("   n<>$$ Rpt loop        @  Invoke cmd file   $  Escape");
  296.     remark("Wild cards:");
  297. remark("^A-alphanumeric  ^D-digit  ^L-letter  ^O-other,(not-^A)  ^P-punctuation");
  298. remark("^X-any character ^U-user set  -- ^W-word of ^..  ^N-not in word of ^..");
  299.  
  300. #endif
  301.  
  302.     if (!oldtty)
  303.     tvxy(1,24);
  304.     ask("Press any key to resume ",rp,1);
  305.  
  306.     ttymode = oldtty;
  307.  
  308.     verify(1);
  309. #else
  310.     tverr(&rptbuf[rptuse][0]);
  311. #endif
  312.   }
  313.  
  314. /* =============================>>> SHOCOUT <<<============================= */
  315.   shocout(c)
  316.   char c;
  317.   {
  318.  
  319.     if (c < ' ')
  320.       {
  321.     ttwt('^'); ttwt(c + '@');
  322.       }
  323.     else
  324.     ttwt(c);
  325.   }
  326.  
  327. /* =============================>>> LEXGET <<<============================= */
  328.   lexget(chr)
  329.   char *chr;
  330.   {  /* lexget - get a character for lex, possibly from repeat buffer */
  331.  
  332.     SLOW char tmp;
  333. l10:
  334.     if (rptcnt[rptuse] > 0)    /* in a repeat buffer? */
  335.       {
  336.     *chr=rptbuf[rptuse][nxtrpt[rptuse]];    /* pick up from repeat buffer */
  337.     if (*chr == SLOOPEND)     /* at end of rpt buff */
  338.       {
  339.         nxtrpt[rptuse] = 0;    /* start <> loop over */
  340.         if (--rptcnt[rptuse] == 0 && !echof)    /* all done with loop */
  341.           {
  342.         echof = TRUE;    /* turn on echo again */
  343.         newscr();    /* update screen after repeat */
  344.           }
  345.         goto l10;        /* loop again */
  346.       }
  347.     ++nxtrpt[rptuse];    /* bump to next char in loop */
  348.       }
  349.     else            /* not in loop, get from keyboard */
  350.       {
  351.     gkbd(&tmp);    /* picks up one character from the keyboard */
  352.     *chr = old_cmds[old_cindex] = tmp;
  353.     old_cindex = ++old_cindex % 16;
  354.       }
  355.   }
  356.  
  357. /* =============================>>> LEX    <<<============================= */
  358.   lex(lexval,lexcnt,lexchr,parsok)
  359.   int *lexval,*lexcnt,parsok;
  360.   char *lexchr;
  361.   { /* ##  lex - gets command input from terminal, and scans for
  362.        #  its lexical value.  Returns a count if given.  Also handles
  363.        #  repeat loops. */
  364.  
  365.     SLOW int count, lex_default;
  366.     FAST int i;
  367.     SLOW int neg, newln;
  368.  
  369.     static char chr,cmdchr,tchr;
  370.  
  371.  
  372.     lex_default = TRUE;
  373.  
  374.     if (!parsok)        /* abort if error in <> */
  375.       {
  376.     if (rptcnt[rptuse] > 0)    /* in loop? */
  377.       {
  378.         newscr();    /* clear screen, send message */
  379.         tverrb("<> not complete ");
  380.       }
  381.     rptcnt[rptuse]=0;    /* abort loop if going */
  382.     nxtrpt[rptuse]=0;
  383.       }
  384. l10:
  385.     for (;;) 
  386.       {             /* need this loop to support <> */
  387.     count = 1;        /* default count is 1 */
  388.  
  389.     lexget(&chr);        /* fetch a character */
  390.     if (rptcnt[rptuse]>0 && chr==SLOOPBEG)    /* detect nesting */
  391.       {
  392.         nxtrpt[rptuse] = 0 ; rptcnt[rptuse] = 0 ; echof=TRUE;
  393.         newscr();    /* update anything so far */
  394.         tverrb("?No nesting ");
  395.         continue;
  396.       }
  397.  
  398.     if ((chr>='0' && chr<='9') || chr=='-')    /* a number */
  399.       {
  400.         count = 0;  lex_default = FALSE;
  401.         neg = FALSE;    /* handle negative counts */
  402.         if (chr=='-')
  403.         neg=TRUE;
  404.         else 
  405.         count = chr-'0';    /* convert to int value */
  406.         for (;;) 
  407.           {
  408.         if (rptcnt[rptuse] > 0)    /* have to handle rptbuf special */
  409.           {
  410.             chr=rptbuf[rptuse][nxtrpt[rptuse]];
  411.             ++nxtrpt[rptuse];
  412.           }
  413.         else 
  414.             lexget(&chr);
  415.         if (chr>='0' && chr<='9')    /* another number? */
  416.             count = count*10+chr-'0';
  417.         else            /* done with number */
  418.             break;
  419.           }
  420.         if (neg)            /* fix if it was negative */
  421.         count = min(-count ,-1);
  422.       }
  423.     cmdchr = clower(chr);    /* fold to one case */
  424.     if (cmdchr == SLOOPBEG)    /* starting a loop? */
  425.       {
  426.         lex_default = TRUE;            /* don't let lex count be def */
  427.         rptcnt[rptuse] = (count < 0) ? (-count) : count;    /* save count */
  428.         ins_mode = TRUE;            /* so ttymode works */
  429.         tvmsg("repeat[",FALSE);        /* echo 'repeat[k]: n<' */
  430.         wtint(rptuse+1); prompt("]: ");
  431.         wtint(rptcnt[rptuse]);
  432.  
  433.         tvcout(SLOOPBEG);
  434.         nxtrpt[rptuse]=0;    /* begin inserting at beginning */
  435.         newln = FALSE;    /* no new line echo yet */
  436.         do            /* fetch repeat chars until get > */
  437.           {
  438.         gkbd(&chr);    /* fetch a char */
  439.         if (chr==delkey)    /* allow editing */
  440.           {
  441.             if (nxtrpt[rptuse] > 0)    /* don't go past start */
  442.               {
  443.             --nxtrpt[rptuse];    /* wipe out last */
  444.             if ((tchr = rptbuf[rptuse][nxtrpt[rptuse]])==CR)
  445.               {
  446.                 tvcout(CR);    /* going to newline */
  447. #ifdef USELF
  448.                 tvcout(LF);
  449. #endif
  450.                 newln = TRUE;        /* new line now */
  451.               }
  452.             else if (!newln)
  453.               {
  454.                 tvcout(BACKSPACE);    /* back over character */
  455.                 tvcout(' ');
  456.                 tvcout(BACKSPACE);
  457.                 if (tchr < ' ' && tchr != 27)
  458.                   {
  459.                 tvcout(BACKSPACE);    /* back over char */
  460.                 tvcout(' ');
  461.                 tvcout(BACKSPACE);
  462.                   }
  463.               }
  464.             else        /* have passed new line start */
  465.               {
  466.                 ctrlch(rptbuf[rptuse][nxtrpt[rptuse]]);
  467.                 tvcout('\\');
  468.               }
  469.               }
  470.             else
  471.             tvcout(BELL);    /* trying to rubout too much */
  472.             continue;
  473.           }
  474.         else        /* a control character detected */
  475.             ctrlch(chr);    /* echo */
  476.  
  477.         rptbuf[rptuse][nxtrpt[rptuse]]=chr;    /* stuff in current rpt buff. */
  478.         ++nxtrpt[rptuse];    /* bump count */
  479.         if (nxtrpt[rptuse] >= 100)    /* only allow 100 chars! */
  480.           {
  481.             newscr();
  482.             tverrb("100 chars only");
  483.             nxtrpt[rptuse]=0 ; rptcnt[rptuse]=0;
  484.             ins_mode = FALSE;
  485.             goto l10;    /* bail out */
  486.           }
  487.           }
  488.         while (!( chr==ESC && rptbuf[rptuse][nxtrpt[rptuse]-2]==ESC &&
  489.           rptbuf[rptuse][nxtrpt[rptuse]-3]==SLOOPEND));    /* end do loop */
  490.  
  491.         ins_mode = FALSE;        /* get ttymode right */
  492.  
  493.         if (rptcnt[rptuse] > 1 || newln)    /* positive count? */
  494.         echof = FALSE;    /* turn off echoing */
  495.         else        /* 0 count */
  496.           {
  497.         fixend();
  498.         tvhdln();    /* get back where we were */
  499.           }
  500.  
  501.         rptbuf[rptuse][nxtrpt[rptuse]-2]=0;
  502.         lstrpt[rptuse]=nxtrpt[rptuse]-3;    /* bump back to end of buffer */
  503.         nxtrpt[rptuse]=0;    /* back for scan now */
  504.         continue;        /* now execute the loop */
  505.       }
  506. #ifdef VB
  507.     else if (cmdchr == '@')    /*$$$    indirect files! */
  508.       {
  509.         opnatf();
  510.         continue;
  511.       }
  512. #endif
  513.     for (i=0 ; synofr[i]!=0 ; ++i)
  514.       if (synofr[i]==cmdchr)
  515.          cmdchr=synoto[i];        /* allow synonyms */
  516.  
  517.     *lexval = UNKNOWN;    /* assume unknown command */
  518.     for (i = 1 ; i<= LEXVALUES ; ++i)    /* scan all possible cmds */
  519.         if (cmdchr == lexsym[i])    /* found it */
  520.           {
  521.         *lexval = i;
  522.         break;
  523.           }
  524.     *lexcnt = count;        /* return good stuff */
  525.     *lexchr = chr;
  526.     return (lex_default);        /* let know if gave back default */
  527.       }                    /* end of for(;;) */
  528.   }
  529. /* ------------------------ tvx_lex.c --------------------------------- */
  530.