home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / cpm68k / kmince.lbr / SUPPORT.CQ / SUPPORT.C
Text File  |  1986-08-29  |  15KB  |  695 lines

  1. /* -*-c,save-*- */
  2. /* SUPPORT.C - supporting functions for Mince
  3.  
  4. The seller of this software hereby disclaim any and all
  5. guarantees and warranties, both express and implied.  No
  6. liability of any form shall be assumed by the seller, nor shall
  7. direct, consequential, or other damages be assumed by the seller.
  8. Any user of this software uses it at his or her own risk.
  9.  
  10. Due to the ill-defined nature of "fitness for purpose" or similar
  11. types of guarantees for this type of product, no fitness for any
  12. purpose whatsoever is claimed or implied.
  13.  
  14. The physical medium upon which the software is supplied is
  15. guaranteed for one year against any physical defect.  If it
  16. should fail, return it to the seller, and a new physical medium
  17. with a copy of the purchased software shall be sent.
  18.  
  19. The seller reserve the right to make changes, additions, and
  20. improvements to the software at any time; no guarantee is made
  21. that future versions of the software will be compatible with any
  22. other version.
  23.  
  24. The parts of this disclaimer are severable and fault found in any
  25. one part does not invalidate any other parts.
  26.  
  27.     Copyright (c) 1981 by Mark of the Unicorn
  28.     Created for version two  9/16/80  JTL
  29.     Updated to version three  1/7/80  JTL
  30.  
  31.     This file contains several useful subroutines that can be
  32. generally used. */
  33.  
  34. #include "mince.gbl"
  35.  
  36. ArgEcho(targ)        /* internal routine to display current argument */
  37.     int targ;
  38. {
  39.     int trow, tcol;
  40.  
  41. #ifdef SUSER
  42.     if (targ==4)
  43.         for (cnt=terminal.delaycnt*terminal.mhz; cnt>0; --cnt)
  44.             if (TKbRdy()) return(FALSE);
  45. #endif
  46.     trow=TGetRow();
  47.     tcol=TGetCol();
  48.     Echo("Arg: ");
  49.     itot(targ);
  50.     TCLEOL();
  51.     TSetPoint(trow,tcol);
  52.     TForce();
  53.     return(TRUE);
  54.     }
  55.  
  56. Ask(mesg)                /* Ask a yes/no question in the echo line */
  57.     char *mesg;        /* Space or y or Y mean yes, anything else is no */
  58. {
  59.     char tchar;
  60.     int yes;
  61.  
  62.     Echo(mesg);
  63.     while (TRUE) {
  64.         if (yes = ((KbWait(),tchar=TGetKb())==' ' || toupper(tchar)=='Y'))
  65.             break;
  66.         if (tchar == BELL || tchar == DEL || tchar == BS ||
  67.             toupper(tchar)=='N') break;
  68.         TBell();
  69.         }
  70.     ClrEcho();
  71.     return (yes);
  72.     }
  73.  
  74. BlockMove(from,to)        /* move a block of characters between Point and
  75.                        From to before To.  Assume Point is before From */
  76.     int from, to;
  77. {
  78.     int i;
  79.  
  80.     while (BIsBefore(from)) {
  81.         i=Buff();
  82.         BSwapPnt(to);
  83.         BInsert(i);
  84.         BSwapPnt(to);
  85.         BDelete(1);
  86.         }
  87.     }
  88.  
  89. change(old,new)        /* change old string into new */
  90.     char *old, *new;
  91. {
  92.     BMove(-strlen(old));
  93.     BDelete(strlen(old));
  94.     while (*new) BInsert(*new++);
  95.     }
  96.  
  97. CheckMode(tmname)        /* see if there is a mode of this name */
  98.     char *tmname;
  99. {
  100.     LowCase(tmname);
  101. #ifdef LARGE
  102.     if (!strcmp(tmname,"c")) return('c');
  103.     if (!strcmp(tmname,"save")) return('s');
  104. #ifdef LISPMODE
  105.     if (!strcmp(tmname,"lisp")) return('l');
  106. #endif
  107. #endif
  108.     if (!strcmp(tmname,"fill")) return('f');
  109.     if (!strcmp(tmname,"page")) return('p');
  110.     return(FALSE);
  111.     }
  112.  
  113. ClrEcho()                /* Clear the echo line */
  114. {
  115.     int trow, tcol;
  116.  
  117.     trow=TGetRow();
  118.     tcol=TGetCol();
  119.     TSetPoint(TMaxRow()-1,0);
  120.     TCLEOL();
  121.     TSetPoint(trow,tcol);
  122.     TForce();
  123.     }
  124.  
  125. CopyToMrk(tmpmark,forwdp)    /* copy point to mark to delete buffer */
  126.     int tmpmark, forwdp;
  127. {
  128.     int ltmark;
  129.  
  130.     BSwitchTo(del_buff);
  131.     if (!DelCmnd(lfunct)) {
  132.         BToEnd();
  133.         ltmark=BCreMrk();
  134.         BToStart();
  135.         BDelToMrk(ltmark);
  136.         BKillMrk(ltmark);
  137.         }
  138.     if (forwdp) BToEnd();
  139.     else BToStart();
  140.     BSwitchTo(buffs[cbuff].bbuff);
  141.     BCopyRgn(tmpmark,del_buff);
  142.     }
  143.  
  144. Debug(message,value)    /* useful for debugging commands */
  145.     char *message;
  146.     int value;
  147. {
  148.     char tchar;
  149.  
  150.     Echo(message);
  151.     itot(value);
  152.     IncrDsp();
  153.     return((tchar=TGetKb())==DEL || tchar==BS);
  154.     }
  155.  
  156. DelayPrompt(mesg)        /* echo mesg if no char is typed within interval */
  157.     char *mesg;        /* return true if mesg printed, else false */
  158. {
  159.     int trow, tcol;
  160.  
  161. #ifdef SUSER
  162.     for (cnt=terminal.delaycnt*terminal.mhz; cnt; --cnt)
  163.         if (TKbRdy()) return (FALSE);
  164. #endif
  165.     trow=TGetRow();
  166.     tcol=TGetCol();
  167.     Echo(mesg);
  168.     TSetPoint(trow,tcol);
  169.     TForce();
  170.     return(TRUE);
  171.     }
  172.  
  173. DelCmnd(pfunct)        /* tell if previous command is a delete command */
  174.     int (*pfunct)();
  175. {
  176.     int MDelLin(), MDelWord(), MRDelWord(), MMakeDel();
  177.     int MDelRgn(), MCopyRgn(), MDelELin(), MDelSent();
  178. #ifdef KEYPAD
  179.     int MRDelLin();
  180. #endif
  181.  
  182.     return(pfunct==MDelLin || pfunct==MDelWord ||
  183.         pfunct==MRDelWord || pfunct==MMakeDel ||
  184.         pfunct==MDelRgn || pfunct==MDelELin ||
  185. #ifdef KEYPAD
  186.         pfunct==MRDelLin ||
  187. #endif
  188.         pfunct==MDelSent || pfunct==MCopyRgn);
  189.     }
  190.  
  191. DoReplace(query)        /* do query replace and replace string */
  192.     int query;
  193. {
  194.     char tchar;
  195.     int exit;
  196.     char old[STRMAX], new[STRMAX];
  197.  
  198.     arg=0;
  199.     *old = *new = '\0';
  200.     do if (!GetArg(query ? "Query Replace <ESC>: " : "Replace <ESC>: ",ESC,
  201.             old,STRMAX)) return;
  202.         while (*old=='\0');
  203.     if (!GetArg("with <ESC>: ",ESC,new,STRMAX)) return;
  204.     tmark=BCreMrk();
  205.     if (query) tchar=',';
  206.     else tchar=' ';
  207.     exit=FALSE;
  208.  
  209.     while (!exit && StrSrch(old,FORWARD)) {
  210.         if (query) {
  211.             if (tchar==',') {
  212.                 Echo("Replacing '");
  213.                 NLPrnt(old);
  214.                 TPrntStr("' with '");
  215.                 NLPrnt(new);
  216.                 TPrntChar('\'');
  217.                 }
  218.             IncrDsp();
  219.             KbWait();
  220.             tchar=TGetKb();
  221.             switch (tchar) {
  222.             case BELL: 
  223.                 ClrEcho();
  224.                 BKillMrk(tmark);
  225.                 return;
  226.             case ' ':
  227.             case ',':            /* comma's turn comes later... */
  228.             case 'Y':
  229.             case 'y':
  230.                 break;
  231.             case '!':
  232.                 query=FALSE;
  233.                 break;
  234.             case '.':
  235.                 exit=TRUE;
  236.                 continue;
  237.             default:
  238.                 continue;
  239.                 }
  240.             }
  241.         change(old,new);
  242.         if (tchar==',') {
  243.             IncrDsp();
  244.             if (!Ask("Confirm Replace?")) change(new,old);
  245.             }
  246.         }
  247.     ClrEcho();
  248.     BPntToMrk(tmark);
  249.     BKillMrk(tmark);
  250.     }
  251.  
  252. Echo(mesg)            /* Say something useful in the echo line */
  253.     char *mesg;
  254. {
  255.     TSetPoint(TMaxRow()-1,0);
  256.     TCLEOL();                    /* clear whatever was there */
  257.     TPrntStr(mesg);            /* display the message */
  258.     TForce();
  259.     }
  260.  
  261. Error(mesg)            /* Display an error message */
  262.     char *mesg;
  263. {
  264.     int trow, tcol;
  265.  
  266.     trow=TGetRow();
  267.     tcol=TGetCol();
  268.     TDisStr(TMaxRow()-1,TMaxCol()-25,mesg);    /* Display the message */
  269.     TBell();                            /* Ring the terminal bell */
  270.     TForce();
  271.     KbWait();
  272.     TSetPoint(TMaxRow()-1,TMaxCol()-25);
  273.     TCLEOL();
  274.     TSetPoint(trow,tcol);
  275.     TForce();
  276.     if (KBexecuting) {abort = TRUE; GAbort = TRUE;}
  277.     }
  278.  
  279. ForceCol(col,forwardp)        /* force the column to be col */
  280.     int col, forwardp;
  281. {
  282.     BMakeCol(col);
  283.     if (col<=0) return;
  284.     if (BGetCol()>col && (BMove(-1), Buff()!=TAB)) BMove(1);
  285.     SIndent(col-BGetCol());
  286.     if (BGetCol()>col && !forwardp) BMove(-1);
  287.     }
  288.  
  289. GetArg(mesg,term,str,len)    /* input a string argument */
  290.     char *mesg, term, *str;
  291.     int len;
  292. {
  293.     char stemp[80], inpt, *nstr, tcol;
  294.     char *RubOut();
  295.  
  296.     TDisStr(TMaxRow()-1,0,mesg);
  297.     TCLEOL();
  298.     tcol=TGetCol();
  299.     TForce();
  300.     nstr=stemp;
  301.     while ((KbWait(),inpt=TGetKb())!=term) {
  302.         if (inpt==BELL) {
  303.             ClrEcho();
  304.             return(FALSE);
  305.             }
  306.         if (nstr-stemp>=len-1 && inpt!=DEL && inpt!=BS) {
  307.             nstr=RubOut(stemp,nstr,tcol);
  308.             TBell();
  309.             }
  310.         switch (inpt) {
  311.             case CR:
  312.                 TPrntStr("<NL>");
  313.                 *nstr++=NL;
  314.                 break;
  315.             case BS:
  316.             case DEL:
  317.                 if (nstr>stemp) nstr=RubOut(stemp,nstr,tcol);
  318.                 break;
  319.             case '\21':            /* ^Q */
  320.                 KbWait();
  321.                 inpt=TGetKb();
  322.             default:
  323.                 TPrntChar(inpt);
  324.                 *nstr++=inpt;
  325.                 break;
  326.             }
  327.         TForce();
  328.         }
  329.     if (nstr!=stemp) {
  330.         *nstr='\0';
  331.         strcpy(str,stemp);
  332.         }
  333.     else NLPrnt(str);
  334.     TSetPoint(TMaxRow()-1,0);
  335.     TForce();
  336.     return(TRUE);
  337.     }
  338.  
  339. GetModeId(msg)            /* read in and check a mode id */
  340.     char *msg;
  341. {
  342.     char *tmname[STRMAX];
  343.     int id;
  344.  
  345.     *tmname='\0';
  346.     if (!GetArg(msg,CR,tmname,STRMAX)) return(FALSE);
  347.     if (id=CheckMode(tmname)) return(id);
  348.     Error("Unknown Mode");
  349.     return(FALSE);
  350.     }
  351.  
  352. SIndent(targ)            /* put in the right number of spaces */
  353.     int targ;
  354. {
  355. #ifndef CPM
  356.     register int cnt;
  357. #endif
  358.  
  359.     for (cnt=targ; cnt>0; --cnt) {
  360.         BInsert(' ');
  361.         TKbChk();
  362.         }
  363.     }
  364.  
  365. index(tstr,tchar)            /* locate character in string */
  366.     char *tstr, tchar;
  367. {
  368.     int cntr;
  369.  
  370.     for (cntr=0; *tstr; ++cntr) if (*tstr++==tchar) return(cntr);
  371.     return(-1);
  372.     }
  373.  
  374.  
  375. int IsClose()                /* do we have a closing character */
  376. {
  377.     return(Buff()==')' || Buff()==']' || Buff()=='}' ||
  378.         Buff()=='"' || Buff()=='\'');
  379.     }
  380.  
  381. int IsGray()                /* tell if current char is white space */
  382. {
  383.     return(IsWhite() || (Buff()&255)==NL);
  384.     }
  385.  
  386. IsNL()                /* check for Newline */
  387. {
  388.     return((Buff()&255)==NL);
  389.     }
  390.  
  391. IsNLPunct()            /* check for Newline or punctuation */
  392. {
  393.     return(IsNL() || Buff()=='.' || Buff()=='?' || Buff()=='!');
  394.     }
  395.  
  396.  
  397. IsParaEnd()            /* check for end of paragraph*/
  398. {
  399.     return(BIsEnd() || Buff()==TAB || IsNL() || Buff()=='@' ||
  400.         Buff()=='.');
  401.     }
  402.  
  403. IsSentEnd()            /* check for end of sentence.  you begin
  404.             at, for example, a '.'.  it skips over as many of
  405.             ')}]"' or "'" as it finds, and tells you whether you
  406.             wind up at a whitespace character */
  407. {
  408.  
  409.     extern int IsClose();
  410.  
  411.     BMove(1);
  412.     MovePast(IsClose,FORWARD);
  413.     return(BIsEnd() || IsGray());
  414.     }        
  415.  
  416. IsToken()                /* tell if current char is part of a token */
  417. {
  418.     return(isalpha(Buff()) || isdigit(Buff()));
  419.     }
  420.  
  421. IsWhite()            /* tell if current char is limited white space */
  422. {
  423.     return(Buff()==' ' || Buff()==TAB);
  424.     }
  425.  
  426. itot(n)                    /* print a number on the terminal */
  427.     unsigned n;
  428. {
  429.     if (n>9) itot(n/10);
  430.     TPrntChar(n%10+'0');
  431.     }
  432.  
  433. KbWait()                /* wait for a character to be typed */
  434. {
  435. #ifdef SUSER
  436.     unsigned cntr;
  437.  
  438.     for (cntr=15*terminal.delaycnt*terminal.mhz; cntr>0; --cntr)
  439.         if (TKbRdy()) return;
  440.     while (!TKbRdy()) BFlush();
  441. #else
  442.     TKbWait();
  443. #endif
  444.     }
  445.  
  446. KillToMrk(tmpmark,forwdp)    /* delete region directioned */
  447.     int tmpmark, forwdp;
  448. {
  449.     CopyToMrk(tmpmark,forwdp);
  450.     BDelToMrk(tmpmark);
  451.     }
  452.  
  453. LowCase(str)                /* convert a string to all lower case */
  454.     char *str;
  455. {
  456.     while (*str=tolower(*str)) ++str;
  457.     }
  458.  
  459. #ifndef CPM
  460. ltot(n)                /* print a number on the terminal */
  461.     long n;
  462. {
  463.     if (n>9) ltot(n/10);
  464.     TPrntChar((char)(n%10)+'0');
  465.     }
  466. #endif
  467.  
  468. ModeFlags()            /* Display the mode flags */
  469. {
  470. #ifdef CPM
  471.     unsigned loc, len;
  472. #else
  473.     long loc, len;
  474. #endif
  475.  
  476.     if (TKbRdy()) return;
  477.     TDisStr(TMaxRow()-2,stat_col," -");
  478.     loc=BLocation();
  479.     len=BLength(buffs[cbuff].bbuff);
  480.     if (len==0) len=1;
  481. #ifdef CPM
  482.     if (loc<655) itot((loc*100)/len);
  483.     else if (loc<6550) itot((loc*10)/(len/10+1));
  484.     else itot(loc/(len/100+1));
  485. #else
  486.     itot((int)((loc*100)/len));
  487. #endif
  488.     TPrntStr("%- ");
  489.     if (TKbRdy()) return;
  490.     TPrntChar(BModp(buffs[cbuff].bbuff) ? '*' : ' ');
  491.     TPrntChar(DelCmnd(lfunct) ? '+' : ' ');
  492.     TCLEOL();
  493.     }
  494.  
  495. MovePast(pred,forwdp)    /* go forward or back past a thingy */
  496.     int (*pred)(), forwdp;
  497. {
  498.     if (!forwdp) BMove(-1);
  499.     while (!(forwdp?BIsEnd():BIsStart()) && (*pred)()) {
  500.         BMove(forwdp?1:-1);
  501.         TKbChk();
  502.         }
  503.     if (!forwdp && !BIsStart()) BMove(1);
  504.     }
  505.  
  506. MoveTo(pred,forwdp)        /* go forward or back to a thingy */
  507.     int (*pred)(), forwdp;
  508. {
  509.     if (!forwdp) BMove(-1);
  510.     while (!(forwdp?BIsEnd():BIsStart()) && !(*pred)()) {
  511.         BMove(forwdp?1:-1);
  512.         TKbChk();
  513.         }
  514.     if (!forwdp && !BIsStart()) BMove(1);
  515.     }
  516.  
  517. NLPrnt(str)            /* print a string with "<NL>"'s */
  518.     char *str;
  519. {
  520.     while (*str)
  521.         if (((*str)&255)!=NL) TPrntChar(*str++);
  522.         else {
  523.             TPrntStr("<NL>");
  524.             ++str;
  525.             }
  526.     TForce();
  527.     }
  528.  
  529. NLSrch()                /* Search for the next new line combination */
  530. {
  531.     return(BCSearch(NL));
  532.     }
  533.  
  534. Rebind(from,to)        /* change all references to From to To */
  535.     int (*from)(), (*to)();
  536. {
  537. #ifdef UNIX
  538.     register int icnt;
  539. #else
  540.     int icnt;
  541. #endif
  542.     for (icnt=383; icnt>=0; --icnt) {
  543.         if (functs[icnt]==from) functs[icnt]=to;
  544.         TKbChk();
  545.         }
  546.     }
  547.  
  548. RNLSrch()                /* Reverse search for the next new line */
  549. {
  550.     return(BCRSearch(NL));
  551.     }
  552.  
  553. char *RubOut(ostr,str,tcol)    /* delete a character for getarg */
  554.     char *str, *ostr, tcol;
  555. {
  556.     *--str='\0';
  557.     TSetPoint(TGetRow(),tcol);
  558.     NLPrnt(ostr);
  559.     TCLEOL();
  560.     TForce();
  561.     return(str);
  562.     }
  563.  
  564. strip(to,from)            /* get main part of file name */
  565.     char *to, *from;
  566. {
  567.     int left, right;
  568.     char *tptr;
  569.  
  570. #ifdef UNIX
  571.     left=0;
  572.     while (index(from+left,'/')>=0) left += index(from+left,'/')+1;
  573.     right=index(from+left,'.');
  574.     if (right<0) right=strlen(from);
  575.     else right += left;
  576. #else
  577.     left=index(from,':')+1;
  578.     right=index(from,'.');
  579.     if (right<0) right=strlen(from);
  580.     TKbChk();
  581.     if (left>=right) {
  582.         left=0;
  583.         right=strlen(from);
  584.         }
  585. #endif
  586.     if (right-left>8) right=left+8;
  587.     for (tptr=from+left; tptr<from+right; ++tptr) *to++ = *tptr;
  588.     *to='\0';
  589.     }
  590.  
  591. StrSrch(str,forwardp)    /* directioned string search */
  592.     char *str;
  593.     int forwardp;
  594. {
  595.     cnt=0;
  596.     while (str[cnt]!='\0') {
  597.         if (!(forwardp ? BCSearch(*str) : BCRSearch(*str))) break;
  598.         if (!forwardp) BMove(1);
  599.         for (cnt=1; !BIsEnd() && str[cnt]; ++cnt) {
  600.             if (Buff()!=str[cnt] && tolower(Buff())!=str[cnt]) break;
  601.             BMove(1);
  602.             TKbChk();
  603.             }
  604.         if (!forwardp || str[cnt]!='\0') BMove((forwardp?1:0)-cnt);
  605.         TKbChk();
  606.         }
  607.     return (str[cnt]=='\0');
  608.     }
  609.  
  610. ToBegLine()            /* move to the beginning of the line */
  611. {
  612.     if (BCRSearch(NL)) BMove(1);
  613.     }
  614.  
  615. ToEndLine()            /* move to the end of the line */
  616. {
  617.     if (BCSearch(NL)) BMove(-1);
  618.     }
  619.  
  620. TIndent(targ)            /* put in the right number of tabs and spaces */
  621.     int targ;
  622. {
  623.     for (cnt=targ; cnt>=tabincr; cnt-=tabincr) {
  624.         BInsert(TAB);
  625.         TKbChk();
  626.         }
  627.     SIndent(cnt);
  628.     }
  629.  
  630. ToNotWhite(forwardp)    /* move to non whitespace */
  631.     int forwardp;
  632. {
  633.     extern int IsGray();
  634.  
  635.     MovePast(IsGray,forwardp);
  636.     }
  637.  
  638. ToSentEnd(forwardp)        /* move to a sentence end */
  639.     int forwardp;
  640. {
  641.     extern int IsNLPunct();
  642.  
  643.     while (TRUE) {
  644.         MoveTo(IsNLPunct,forwardp);
  645.         if (!forwardp) BMove(-1);
  646.         if (BIsEnd() || BIsStart()) return;
  647.         if (IsNL()) {
  648.             BMove(1);
  649.             tmp=IsParaEnd();
  650.             if (forwardp) BMove(-1);
  651.             }
  652.         else {
  653.             tmark=BCreMrk();
  654.             tmp=IsSentEnd();
  655.             BPntToMrk(tmark);
  656.             BKillMrk(tmark);
  657.             }
  658.         if (tmp) return;
  659.         BMove(forwardp ? 1:-1);
  660.         }
  661.     }
  662.  
  663. ToWhite(forwardp)        /* Move to whitespace */
  664.     int forwardp;
  665. {
  666.     extern int IsGray();
  667.  
  668.     MoveTo(IsGray,forwardp);
  669.     }
  670.  
  671. ToWord()                /* move to the beginning of a word */
  672. {
  673.     extern int IsToken();
  674.  
  675.     MoveTo(IsToken,FORWARD);
  676.     }
  677.  
  678. #ifdef CPM
  679. UpCase(str)                /* convert a string to all upper case */
  680.     char *str;
  681. {
  682.     while (*str=toupper(*str)) ++str;
  683.     }
  684. #endif
  685.  
  686. VMovCmnd(pfunct)        /* tell if previous command was a vertical move */
  687.     int (*pfunct)();
  688. {
  689.     int MNextLin(), MPrevLin();
  690.     return(pfunct==MNextLin || pfunct==MPrevLin);
  691.     }
  692.  
  693. /* END OF SUPPORT.C - supporting routines for Mince */
  694. (), MPrevLin();
  695.     return(pfunct==MNextLin