home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 157_01 / qed < prev    next >
Text File  |  1987-10-12  |  14KB  |  628 lines

  1. /*  VERSION 0021  (DATE: 28/04/87)  (TIME: 16:59)  */
  2. /*
  3.     e (qed) screen editor
  4.  
  5.     (C) G. Nigel Gilbert, MICROLOGY, 1981
  6.     licensed for private non-profitmaking use 1983
  7.     
  8.     August-December 1981
  9.  
  10.     Modified: Aug-Dec     1984:  BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
  11.               March        1985:  BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
  12.  
  13.     FILE: qed
  14.  
  15.     FUNCTIONS: main, initialise, edit, finish, seldisk
  16.  
  17.     PURPOSE: initialise; process commands;
  18.  
  19. */
  20.  
  21. #include "qed.h"
  22. #define VERNO 0x30        /* get MSDOS version number */
  23.  
  24. main(argc,argv)
  25. int argc;
  26. char **argv;
  27. {
  28.     int argn;
  29.     int i;
  30.     char *dig;
  31.  
  32. /**************************Default option settings***************************/
  33.  
  34.     initjmp=1;            /*jmp to line 1*/
  35.     autoin=YES;            /*auto indent  [YES/NO]*/
  36.     backup=YES;            /*make ".BAK" file [YES/NO]*/
  37.     readall=YES;        /*read as much text as possible up to memory*/
  38.     trail=NO;            /*don't strip trailing blanks [YES/NO]*/
  39.     helpon=NO;            /*start with help menu on [YES/NO]*/
  40.     expert=YES;            /*brief prompts [YES/NO]*/
  41.     tabwidth=4;            /*tab stops every n cols [number]*/
  42.     displaypos=YES;        /*display line:column at top of screen*/
  43.     blockscroll=NO;        /*don't scroll whole page, just current line*/
  44.     pagingdisk=0;        /*create buffer file on this disk -
  45.                             set to either 0 (for currently logged-in disk)
  46.                             or to desired disk letter  (eg 'B') */
  47.     wboot=YES;            /*do a warm boot at end of edit [YES/NO]*/
  48.     defext[0]='\0';        /* default extension */
  49. #if WWRAP
  50.     rtmarg=LLIM;        /* right margin*/
  51. #endif
  52. #if VRSNNUM
  53.     version=YES;        /* change version num on save*/
  54.     *date='\0';
  55.     *time='\0';
  56. #endif
  57.  
  58. /***********************End of default option settings***********************/
  59.  
  60.  
  61.     inbufp=0;
  62.     if((_os(VERNO,0) & 0x00ff) < 2) {
  63.         puts("Must use MSDOS vers 2.x with 'qed'");
  64.         exit(0);
  65.         }
  66.     filename[0]=name[0]='\0';
  67.  
  68.     argn=0;    
  69.     while (++argn < argc)
  70.         if (*argv[argn] == '-') {
  71.             dig=argv[argn]+1;
  72.             switch(toupper(*dig)) {
  73.             case 'J' :
  74.                 initjmp = atoi((argv[argn]+2));
  75.                 break;
  76.             case 'A' :
  77.                 autoin=!autoin; 
  78.                 break;
  79.             case 'B' : 
  80.                 backup=!backup; 
  81.                 break;
  82.             case 'L' :
  83.                 displaypos=!displaypos;
  84.                 break;
  85.             case 'H' :
  86.                 blockscroll=!blockscroll;
  87.                 break;
  88.             case 'R' :
  89.                 readall=!readall;
  90.                 break;
  91. #if WWRAP
  92.             case 'M' :
  93.                 rtmarg=0;
  94.                 rtmarg=atoi((argv[argn]+2));
  95.                 if (rtmarg < LLIM) {
  96.                     trail=YES;
  97.                     autoin=NO;
  98.                 }
  99.                 break;
  100. #endif
  101.             case 'T' : 
  102.                 tabwidth=0;
  103.                 while (*++dig) tabwidth=tabwidth*10+*dig-'0';
  104.                 break;
  105.             case 'S' :
  106.                 trail=!trail; 
  107.                 break;
  108. #if VRSNNUM
  109.             case 'U' :
  110.                 version = !version;
  111.                 break;
  112. #endif
  113.             case 'V' : 
  114.                 helpon=!helpon; 
  115.                 break;
  116.             case 'E' :
  117.                 expert=!expert;
  118.                 break;
  119.             case 'X' : 
  120.                 wboot=!wboot; 
  121.                 break;
  122.             case 'D' : 
  123.                 pagingdisk=toupper(*(dig+1));
  124.                 if (pagingdisk >= 'A' && pagingdisk <= 'P') break;
  125.             default  : 
  126.                 putstr("Illegal option: "); 
  127.                 putstr(argv[argn]);
  128.                 exit();
  129.                 }
  130.             }
  131.         else strcpy(filename[0] ? name : filename,argv[argn]);
  132.  
  133.     ans[0]=patt[0]=changeto[0]=opts[0]='\0';
  134.     
  135.     keytranslate();
  136.     do {
  137.         initialise();
  138.         edit();
  139.         } 
  140.     while (YES);
  141. }
  142.  
  143. initialise()
  144. {
  145.     int i,warn;
  146.  
  147.     cursorx=charn=offset=lastoff=from=to=0;
  148.     cursory=topline=lastread=lastl=findir=jmpto=1;
  149.     changed=isdim=replace=repeat=blocking=warn=blankedmess=NO;
  150.     pfirst=-100;
  151.     goteof=YES;
  152.     errmess=NULL;
  153.     
  154.     curdsk=_os(CURDSK);
  155.     bakpath[0]='B';
  156.     bakpath[1]=':';
  157.     bakpath[2]='\\';
  158.     bakpath[3]='\0';
  159.  
  160.     initvm();
  161.  
  162.     text[0]='\0';
  163.     cline=1;
  164.     altered=YES;
  165.     puttext();
  166.  
  167.     setstatusname();
  168.     if (filename[0]) {
  169.         putclr();
  170.         gotoxy(8,11);
  171.         putstr("qed  screen editor  version "); 
  172.         putstr(VERSION);
  173.         gotoxy(12,12);
  174.         putstr("MICROLOGY 1983 and JWH 1985");
  175.         gotoxy(12,13);
  176.         terminal();
  177.         while (opentext(filename) == FAIL) {
  178.             if (opentext(strcat(filename,defext)) == FAIL) {
  179.                 askforfile();
  180.                 if (!filename[0]) goto newfile;
  181.                 }
  182.             }
  183.         lastl=UNKNOWN;
  184.         lastread=0;
  185.         goteof=NO;
  186.         if (name[0]) {
  187.             strcpy(filename,name); 
  188.             name[0]='\0';
  189.             }
  190.         }
  191. newfile: errmess=NULL;
  192.     format(filename);
  193.         /*read as much text to fill memory or end of file*/
  194.     if (readall)
  195.         for (i=1;(!(usage[slotsinmem-1]) && (!(goteof)));i+=100)
  196.             readtext(i);
  197.     setstatusname();
  198.     gettext(1);
  199.     putclr();
  200.     if (helpon) dohelp();
  201.     if (initjmp>2) {                 /* (2-1) is a bad jump from line 1 */
  202.         jumpline(initjmp-cline);    /* not possible to do init jump to 2*/
  203.         initjmp=0;
  204.         putstatusline(cline);
  205.         }
  206.     else
  207.         putpage();
  208. }
  209.  
  210. edit()        /*command processor*/
  211. {
  212.     char c;
  213.     char oldcrx,inc;
  214.     int to;
  215.  
  216.     setjmp(0);
  217.  
  218.     while (YES) {
  219.         goodline=cline;
  220.         if ((expert) && (!blankedmess)) xmessoff();
  221.         else if (!blankedmess) unmess();
  222.         putlineno(cline);
  223.         resetcursor();
  224.         c=getkey();
  225.         if (errmess != NULL) {
  226.             errmess=NULL;
  227.             putstatusline(cline);
  228.             }
  229.         switch(c) {
  230.         case DOWNKEY    : 
  231.             moveline(1); 
  232.             break;
  233.         case UPKEY    : 
  234.             moveline(-1); 
  235.             break;
  236.         case LEFTKEY    : 
  237.             movechar(-1); 
  238.             break;
  239.         case RIGHTKEY    : 
  240.             movechar(1); 
  241.             break;
  242.         case LEFTWKEY    : 
  243.             moveword(-1); 
  244.             break;
  245.         case RIGHTWKEY    : 
  246.             moveword(1);  
  247.             break;
  248.         case BOLKEY    : 
  249.             sync(0); 
  250.             break;
  251.         case EOLKEY    : 
  252.             sync(strlen(text)); 
  253.             break;
  254.         case UPPAGE    : 
  255.             movepage(-1); 
  256.             break;
  257.         case DOWNPAGE    : 
  258.             movepage(0); 
  259.             break;
  260.         case HOMEKEY    : 
  261.             if (jumpline(lastl-cline)) sync(strlen(text));
  262.             break;
  263.         case BOFKEY    : 
  264.             if (jumpline(1-cline)) sync(0);
  265.             break;
  266.         case DELLEFT    :
  267.             changed=YES;
  268.             deletechar(-1); 
  269.             break;
  270.         case DELRIGHT    : 
  271.             deletechar(0);
  272.             changed=YES;
  273.             break;
  274.         case DELLNKEY    :
  275.             changed=YES;
  276.             strcpy(textb,text);        /*save for undelete line*/
  277.             text[0]='\0';
  278.             crdelete((cline == lastl ? -1 : 0)); 
  279.             break;
  280.         case DELWDKEY    :
  281.             changed=YES;
  282.             deleteword(); 
  283.             break;
  284.         case JUMPKEY    :
  285.             if (expert) xprtmess("J ? ");
  286.             else putmess("Jump ([+/-]n,RET=crnt) ? ");
  287.             scans(ans,8);
  288.             if (!*ans) jmpto = cline;
  289.             else
  290.                 calcjmp();
  291.             if (expert) xmessoff();
  292.             break;
  293.         case TOPSCRKEY    :
  294.             moveline((topline-cursory));
  295.             break;
  296.         case BOTSCRKEY    :
  297.             moveline((SHEIGHT-cursory));
  298.             break;
  299.          case REPKEY    :
  300.             repeat=YES; 
  301.             dofindrep(1,1);
  302.             repeat=NO; 
  303.             break;
  304.         case BLOCKKEY    : 
  305.             switch (to=blockops()) {
  306.             case YES :    return;
  307.                         break;
  308.             case 'x' :
  309.             case 'q' :  if (finish(to)==YES) return;
  310.                         break;
  311.             case 'r' :
  312.                 if (expert) xprtmess("Read file? ");
  313.                 else putmess("File to read? ");
  314.                 scans(name,FILELEN);
  315.                 if (*(name))  {
  316.                     readfile(name);
  317.                     putpage();
  318.                     changed=YES;
  319.                     }
  320.                 break;
  321.             }
  322.             break;
  323.         case SCRLDNKEY    :
  324.             /* original: slow but sure
  325.             oldcrx = cursorx;
  326.             to = plast-cline;
  327.             moveline(to);
  328.             inc=( (moveline(1)==YES) ? 1 : 0);
  329.             cursorx = oldcrx;
  330.             moveline(((cline-to)<=pfirst) ? (topline-cursory) : (-to - inc));
  331.             */
  332.               /* new: 29.viii.86*/
  333.             if(cursory==topline) puttext();
  334.             if (plast>=(pfirst+2)) {
  335.                 linedelete(topline);
  336.                 inc = plast-pfirst;
  337.                 if (plast<lastl) {
  338.                     getline(++plast);
  339.                     putline(plast,
  340.                         (inc<(SHEIGHT-topline)) ? (inc) : SHEIGHT);
  341.                 }
  342.                 pfirst++;
  343.                 if (cursory==topline) gettext(pfirst);
  344.                 cursorx=adjustc(cursorx);
  345.                 gotoxy(cursorx, (cursory -= cursory>topline ? 1 : 0));
  346.             }
  347.             break;
  348.         case UNDELINE :
  349.             /*  helpon via kontext key
  350.             if (helpon) {
  351.                 helpon=NO;
  352.                 unmess();
  353.                 }
  354.             else {
  355.                 helpon=YES; 
  356.                 dohelp();
  357.                 } 
  358.             */
  359.             puttext();
  360.             cline=inject(cline,textb);
  361.             if (cursory>=SHEIGHT) {
  362.                 linedelete(topline);
  363.                 gotoxy(0,cursory);
  364.                 gettext(cline);
  365.                 putline(cline,cursory);
  366.                 plast++;
  367.                 pfirst++;
  368.             }
  369.             else {
  370.                 gotoxy(0,++cursory);
  371.                 insertline();
  372.                 gettext(cline);
  373.                 putline(cline,cursory);
  374.                 if ((plast-pfirst) < SHEIGHT-topline) plast++;
  375.             }
  376.             break;
  377.         case CR        :
  378.             changed=YES;
  379.             crinsert(0); 
  380.             break;
  381.         case CRSTILL    :
  382.             changed=YES;
  383.             crinsert(-1); 
  384.             break;
  385.         case SCRLUPKEY   :
  386.             /* original: save current cursorx
  387.             oldcrx = cursorx;
  388.             to = topline-cursory;
  389.             moveline(to);
  390.             inc=( (moveline(-1)==YES) ? 1 : 0);
  391.             cursorx = oldcrx;
  392.             moveline(((cline-to)>=plast) ? (SHEIGHT-cursory) : (-to + inc));
  393.             */
  394.               /* new:  29.viii.86 */
  395.             if(cursory==SHEIGHT)puttext();
  396.             if (pfirst>1) {
  397.                 gotoxy(0,topline);
  398.                 insertline();
  399.                 inc=plast-pfirst;
  400.                 putline((--pfirst),topline);
  401.                 if (inc >= (SHEIGHT-topline)) plast--;
  402.                 if (cursory==SHEIGHT) gettext(plast);
  403.                 cursorx=adjustc(cursorx);
  404.                 gotoxy(cursorx, (cursory += ((cursory<SHEIGHT) ? 1 : 0)));
  405.             }
  406.             break;
  407.         case QWIKKEY    :
  408.             info();
  409.             break;
  410.         case OOPSKEY    :
  411.             oops();
  412.             break;
  413.         case TAB:
  414.             changed=YES;
  415.             insertchar('\t');
  416.             break;
  417.         case ESCKEY    :
  418.             resetcursor(); 
  419.             while (!(c=inkey()));
  420.             if (c < ' ') ;                        /*c already CTRL*/
  421.             else
  422.                 if (c < '@') break;                /*c not CTRL char*/
  423.                 else
  424.                     c -= ((c < '`') ? 64 : 96);    /*c either upper or lower*/
  425.         default        :
  426.             changed=YES;
  427.             insertchar(c); 
  428.             break;
  429.             }
  430.         }
  431. }
  432.  
  433. finish(o)  int o;    /*return YES to edit another file;
  434.                       NO to return to current file
  435.                       or don't return, but exit if finished altogther */
  436. {
  437.     int abandon;
  438.     char c, tempname[FILELEN], namebak[FILELEN], *strcpy();
  439.  
  440.     if (o != 'x') {
  441.     if (expert) xprtmess("W/A/R ? ");
  442.     else
  443.      putmess("W|rite edited text to file, |A|bandon all edits, or |R|eturn? ");
  444.     while ( (c=getlow()) != 'w' && c != 'a' && c != 'r'); 
  445.     putch(c);
  446.     if (c == 'r') return NO;
  447.     abandon= c == 'a';
  448.     }
  449.     if ((c == 'w') || (o == 'x'))  {
  450.         if (!filename[0]) {
  451.             if (expert) xprtmess("Write file ?");
  452.             else putmess("File to write to? ");
  453.             scans(filename,FILELEN);
  454.             format(filename);
  455.             if (filename[0] <= ' ' || (!backup && !exists(filename)))
  456.             {
  457.                 filename[0]='\0';
  458.                 return NO;
  459.                 }
  460.             }
  461.         if (backup) {    /*delete old bak file*/
  462.             retag(strcpy(namebak,filename),"BAK");
  463.             if (checkexists(namebak))
  464.                 if (funlink(namebak) == FAIL) return NO;
  465.             }
  466. #if VRSNNUM
  467.         if (version) putvrsn();        /*update version num and date/time*/
  468. #endif
  469.         strcpy(tempname,filename); /*keep old name in 'filename'*/
  470.         retag(tempname,"$$$"); /*new file called'.$$$'*/
  471.         if (writefile(1,lastl,tempname,filename,YES) == FAIL) return NO;
  472.         /*check original file still exists - may have been deleted or
  473.            renamed by user */
  474.         if (checkexists(filename)) {
  475.             if (backup) {
  476.                 /*orig. file becomes '.bak' */
  477.                 if (frename(filename,namebak) == FAIL) goto failed;
  478.                 }
  479.             else {
  480.                 /*delete orig file*/
  481.                 if (funlink(filename) == FAIL) {
  482.     failed:             /*if can't delete/rename old file, change
  483.                         new name to '.$$$'*/
  484.                     strcpy(filename,tempname);
  485.                     goto nowrite;
  486.                     }
  487.                 }
  488.             }
  489.         frename(tempname,filename); /*new file goes from '$$$' to orig name*/
  490.         changed=NO;        /*file now not changed*/
  491.         }
  492.     if (o == 'x') {
  493.         /*
  494.         if (pagefd != NOFILE) {
  495.             close(pagefd);
  496.             funlink(pagingfile);
  497.             }
  498.         */
  499.         xit();
  500.         };
  501. nowrite:
  502.     if (expert) xprtmess("E/R/A ? ");
  503.     else
  504.      putmess("E|xit to DOS,  |R|eturn to this file, or edit |A|nother file? ");
  505.     while ( (c=getlow()) != 'e' && c!='a' && c!='r');
  506.     putch(c);
  507.     switch(c) {
  508.     case 'e' :
  509.         if (changed)
  510.             if (!dispose()) return NO;
  511.         fclose(textbuf);
  512.         /*
  513.         if (pagefd != NOFILE) {
  514.             close(pagefd);
  515.             funlink(pagingfile);
  516.             }
  517.         */
  518.         xit();
  519.     case 'a' :
  520.         if (changed)
  521.             if (!dispose()) return NO;
  522.         fclose(textbuf);
  523.         if (pagefd != NOFILE) {
  524.             close(pagefd);
  525.             funlink(pagingfile);
  526.             }
  527.         askforfile();
  528.         return YES;
  529.         
  530.     case 'r' : 
  531.         if (!abandon) {
  532.             if (pagefd != NOFILE) {
  533.                 close(pagefd);
  534.                 funlink(pagingfile);
  535.                 }
  536.             gotoxy(WAITPOS,0);
  537.             opentext(filename);
  538.             lastl=UNKNOWN; 
  539.             lastread=0; 
  540.             goteof=NO;
  541.             initvm();
  542.             gettext(cline);
  543.             errmess=NULL;
  544.             putstatusline(cline);
  545.             }
  546.         if (expert) xmessoff();
  547.         return NO;
  548.         }
  549. }
  550.  
  551. dispose()        /*check to dispose of modified file*/
  552. {
  553.     char ans;
  554.     
  555.     if (expert) xprtmess("Abandon mods ? ");
  556.     else putmess("Abandon modified file? (y/n) ");
  557.     ans=getlow();
  558.     /*if (getlow() == 'y') return YES;*/
  559.     if (expert) xmessoff();
  560.     if (ans=='y') return YES;
  561.     return NO;
  562. }
  563.  
  564. xit()        /*leave the editor, either by returning to CCP or by
  565.         warm booting, according to X option*/
  566. {
  567.     /* simple no error exit for now */
  568.     if (pagefd != NOFILE) {
  569.         close(pagefd);
  570.         funlink(pagingfile);
  571.     }
  572.     deleteline(0,23);
  573.     gotoxy(0,22);
  574.     exit(0);
  575. }
  576.  
  577. askforfile()    /*get another file to edit into 'filename' */
  578. {
  579.     int drive;
  580.  
  581.     while(YES) {
  582.         putclr();
  583. dirdone:
  584.         if (errmess != NULL)  {
  585.             gotoxy(EMPOS,0);
  586.             putstr(errmess);
  587.             }
  588.         gotoxy(0,0);
  589.         putstr("File to edit\n |([return] to create a new file");
  590.         putstr("   >| to view directory|\n");
  591.         putstr(" |A:-P: to change default disk, [escape] to exit)| ? ");
  592.         if (scans(filename,FILELEN) == ESCKEY) xit();
  593.         /*if (filename[0]=='\0') justfile[0]='\0';*/
  594.         deleteline(EMPOS,0);
  595.         errmess = NULL;
  596.         if (filename[0] == '>')  {
  597.             filename[0] = '\0';
  598.             deleteline(1,3);
  599.             putstr("Enter [drv:]mask| (RET for all) ");
  600.             dirmsk();
  601.             goto dirdone;
  602.             }
  603.         if (strlen(filename) == 2 &&
  604.                 filename[1] == ':') {
  605.             if ( (drive=toupper(filename[0])-'A') >= 0 && drive < 16) {
  606.                 {if (seldisk(drive)) continue;}
  607.                     /*    bdos(RESETDRV,1 << drive);    */
  608.                 curdsk=drive;
  609.                 }
  610.             }
  611.         else {
  612.             name[0]='\0';
  613.             /*if (filename[0]=='\0') justfile[0]=='\0';*/
  614.             return YES;
  615.             }
  616.         }
  617. }
  618.  
  619. seldisk(drive)
  620. int drive;
  621. {
  622. /*
  623.     if (dskcheck(setjmp(dskerr))) return FAIL;
  624. */
  625.     _os(SELDSK,drive);
  626.     return 0;
  627. }
  628.