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

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