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

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