home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 199_01 / ged.c < prev    next >
Text File  |  1987-12-17  |  19KB  |  754 lines

  1. /*
  2. Header:           CUG199;
  3. Title:            Module 0 of ged editor;
  4. Last Updated:     12/06/87;
  5.  
  6. Description:     "PURPOSE: initialise; process commands";
  7.  
  8. Keywords:         e, editor, qed, ged, DeSmet, MSDOS;
  9. Filename:         ged.c;
  10. Warnings:        "O file must be present during link of ged";
  11.  
  12. Authors:          G. Nigel Gilbert, James W. Haefner, and Mel Tearle;
  13. Compilers:        DeSmet 3.0;
  14.  
  15. References:
  16. Endref;
  17. */
  18.  
  19. /*
  20. e/qed/ged screen editor
  21.  
  22. (C) G. Nigel Gilbert, MICROLOGY, 1981 -  August-December 1981
  23.  
  24. Modified:   Aug-Dec   1984:  BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
  25.             March     1985:  BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
  26.  
  27.             May       1986:  qed converted to ged         (Mel Tearle)
  28.             August    1987:  ged converted to MSC 4.0     (Mel Tearle)
  29.  
  30. File:       ged.c
  31.  
  32. Functions:  main, initialise, edit, finish, dispose, xit,
  33.             askforfile, seldisk
  34. */
  35.  
  36. #include "ged.h"
  37.  
  38. #ifdef MSC
  39. jmp_buf  mark;
  40. #endif
  41.  
  42. void main(argc,argv)
  43. char **argv;
  44. int argc;
  45. {
  46. int argn;
  47. int i;
  48. char *dig;
  49.  
  50. /* --------------------- Default option settings ---------------------*/
  51.  
  52. initjmp =    1;     /* jmp to line 1 */
  53. autoin  =  YES;     /* auto indent  [YES/NO] */
  54. backup  =  YES;     /* make ".BAK" file [YES/NO] */
  55.  
  56.  
  57. /***********************************************************************/
  58. /*** DON'T CHANGE *** DON'T CHANGE *** DON'T CHANGE *** DON'T CHANGE ***/
  59. /***********************************************************************/
  60.  
  61.    readall =  YES;     /* read as much text as possible up to memory */
  62.  
  63. /***********************************************************************/
  64. /*** DON'T CHANGE *** DON'T CHANGE *** DON'T CHANGE *** DON'T CHANGE ***/
  65. /***********************************************************************/
  66.  
  67.  
  68. trail   =   NO;     /* don't strip trailing blanks [YES/NO] */
  69.  
  70. tabwidth    =   4;  /* tab stops every n cols [number] */
  71. blockscroll = YES;  /* don't horizontal scroll whole page, just current line */
  72. pagingdisk  =   0;  /* create buffer file on this disk -
  73.                        set to either 0 (for currently logged-in disk)
  74.                        or to desired disk letter  (eg 'B') */
  75.  
  76. rtmarg    =  REFORM;   /* default for reformat only - no wordwrap */
  77. defext[0] =    '\0';   /* default extension */
  78.  
  79. window = WINDOW;
  80.  
  81. /* ------------------ End of default option settings -------------------- */
  82.  
  83.  
  84. if ( ( _os( VERNO, 0 ) & 0x00ff ) < 2 )  {
  85.        putstr( "Ged Error: Must use MSDOS vers 2.x with 'ged'" );
  86.        exit(0);
  87. }
  88.  
  89.  
  90. inbufp = 0;
  91. filename[0] = name[0] = '\0';
  92.  
  93. argn = 0;
  94. while ( ++argn < argc )
  95.   if ( *argv[argn] == '-' )  {
  96.         dig = argv[argn]+1;
  97.         switch( toupper(*dig) )  {
  98.            case 'A' :
  99.                 autoin = ( char ) !autoin;
  100.                 break;
  101.            case 'B' :
  102.                 backup = ( char ) !backup;
  103.                 break;
  104.            case 'Q' :
  105.                 readall = ( char ) !readall;
  106.                 break;
  107.            case 'H' :
  108.                 blockscroll = ( char ) !blockscroll;
  109.                 break;
  110.            case 'T' :
  111.                 tabwidth = 0;
  112.                 while (*++dig) tabwidth = tabwidth*10+*dig-'0';
  113.                 break;
  114.            case 'S' :
  115.                 trail = ( char ) !trail;
  116.                 break;
  117.            case 'D' :
  118.                 pagingdisk = toupper(*(dig+1));
  119.                 if ( pagingdisk >= 'A' && pagingdisk <= 'P' )
  120.                      break;
  121.            default  :
  122.                 if ( isdigit( *dig ) )  {
  123.                      initjmp = atoi( (argv[argn]+1 ) );
  124.                      break;
  125.                 }
  126.                 putstr( "Ged Error: Illegal option: " );
  127.                 putstr( argv[argn] );
  128.                 exit(1);
  129.                 }
  130.   }
  131.   else strcpy( filename[0] ? name : filename, argv[argn] );
  132.  
  133. ans[0] = patt[0] = changeto[0] = opts[0] = '\0';
  134.  
  135.  
  136. /* ----------------------  start here  -------------------- */
  137.  
  138. keytranslate();
  139.  
  140. do  {
  141.   initialise();
  142.   edit();
  143. }
  144. while (YES);
  145. }
  146.  
  147. /* -----------------------  end main   ------------------- */
  148.  
  149.  
  150. void initialise()
  151. {
  152. int i;
  153.  
  154. cursorx  = charn   = offset = lastoff = from = 0;
  155. histptr  = histcnt = ncommand = to = 0;
  156.  
  157. cursory  = cline = topline  = lastread = lastl = findir = jmpto = 1;
  158.  
  159. changed  = blocking = isdim = repeat = NO;
  160. replace  = blankedmess = NO;
  161. screen   = NO;
  162.  
  163. if ( overtype )  ;  else  NO;
  164.  
  165. altered   = goteof = YES;
  166. errmess   = '\0';
  167. lastgraph = NULL;
  168.  
  169. pfirst   = -100;    text[0]  = '\0';
  170.  
  171.  
  172. curdsk = _os( CURDSK, 0 );
  173.  
  174.  
  175. initvm();
  176. scr_setup();
  177. scr_cursoff();
  178.  
  179. if ( filename[0] )  {
  180.      scr_clr();
  181.  
  182. scr_putstr( 11, 10,
  183.    "╔═════════════════════════════════════════════════════════╗", RSFW );
  184. scr_putstr( 11, 11,
  185.    "║   qed editor version 4.6b  MICROLOGY 1983 - JWH 1985    ║", RSFW );
  186. scr_putstr( 11, 12,
  187.    "║        m/ged version 2.00  Mel Tearle 1987              ║", RSFW );
  188. scr_putstr( 11, 13,
  189.    "║                    » ged - 12/06/87 «                   ║", RSFW );
  190. scr_putstr( 11, 14,
  191.    "╚═════════════════════════════════════════════════════════╝", RSFW );
  192. scr_delete( 0,24 );
  193.  
  194.  
  195.      /* open a file, if it fails then try again to
  196.       * open it using filename plus default extension
  197.       */
  198.      while ( opentext( filename ) == FAIL )  {
  199.              askforfile();
  200.              if ( !filename[0] )  goto  newfile;
  201.      }
  202.      lastl = UNKNOWN;  lastread = 0;  goteof = NO;
  203.  
  204.      if ( name[0] )  {
  205.           strcpy( filename, name );
  206.           name[0] = '\0';
  207.      }
  208. }       /* end - if filename */
  209.  
  210. newfile:
  211.   errmess = NULL;
  212.  
  213.   format( filename );
  214.  
  215.  
  216.  /* read as much text to fill memory or end of file
  217.   */
  218.  if ( readall )
  219.       for ( i = 1; (! ( usage[slotsinmem-1] ) && ( !( goteof ) ) ); i += 100 )
  220.             readtext(i);
  221.  
  222.  gettext(1);
  223.  scr_clr();
  224.  
  225.  if ( initjmp > 2)  {              /* (2-1) is a bad jump from line 1 */
  226.       jumpline( initjmp-cline );   /* not possible to do init jump to 2*/
  227.       initjmp = 0;
  228.  }
  229.  else
  230.      putpage();
  231.  
  232. setstatusname();
  233. putstatusline( cline );
  234.  
  235. show_fkeys();
  236. }                  /* end - initialise  */
  237.  
  238.  
  239. /* command processor
  240.  */
  241. void edit()
  242. {
  243. unsigned char c;
  244.  
  245. int  inc, i, to, oldcrx;
  246.  
  247. #ifdef  MSC
  248.   setjmp( mark );
  249. #else
  250.   setjmp(0);
  251. #endif
  252.  
  253. while ( YES )  {
  254.   goodline = cline;     /* restore environment */
  255.   storehist = YES;      /* makesure we're saving history */
  256.   unmess();             /* check if topline has changed */
  257.  
  258.   if ( blankedmess )  {
  259.        putstatusline( cline );
  260.        blankedmess = NO;
  261.   }
  262.   else
  263.        putlineno( cline );
  264.  
  265.   resetcursor();
  266.   scr_curson();
  267.   c = getkey();
  268.  
  269.   if ( ( ncommand++ % 32 ) == 0 )   show_time();
  270.  
  271.   if ( errmess != NULL )  errmess =  NULL;
  272.     switch(c)  {
  273.       case UPPAGE :
  274.            movepage(-1);
  275.            break;
  276.       case DOWNPAGE :
  277.            movepage(0);
  278.            break;
  279.       case DOWNKEY :
  280.            moveline(1);
  281.            break;
  282.       case UPKEY :
  283.            moveline(-1);
  284.            break;
  285.       case SCRLDNKEY :
  286.            oldcrx = cursorx;
  287.            to = plast - cline;
  288.            moveline(to);
  289.            inc = ( ( moveline(1) == YES ) ? 1 : 0 );
  290.            cursorx = oldcrx;
  291.            moveline( ( ( cline - to ) <= pfirst )
  292.                      ? ( topline - cursory ) : ( -to - inc ) );
  293.            break;
  294.       case SCRLUPKEY :
  295.            oldcrx = cursorx;   /* save current cursorx */
  296.            to = topline - cursory;
  297.            moveline(to);
  298.            inc = ( ( moveline(-1) == YES ) ? 1 : 0 );
  299.            cursorx = oldcrx;
  300.            moveline( ( ( cline - to ) >= plast )
  301.                      ? ( SHEIGHT - cursory ) : ( -to + inc ) );
  302.            break;
  303.       case DELLNKEY :
  304.            changed = YES;
  305.            text[0] = '\0';
  306.            crdelete( ( cline == lastl ? -1 : 0 ) );
  307.            break;
  308.       case BLOCKKEY :
  309.         switch ( to = blockops() )  {
  310.           case YES :  return;
  311.                  /*   break;  */
  312.           case 'x' :
  313.           case 'q' :  if ( finish(to) == YES )  return;
  314.                       break;
  315.           case 'r' :
  316.                       putmess( "F|ile to read? " );
  317.                       if ( ( scans( name, FILELEN ) ) == ESCKEY )  break;
  318.                       if ( *(name) )  {
  319.                            readfile( name );
  320.                            changed = YES;
  321.                            putpage();
  322.                       }
  323.                       break;
  324.         }
  325.         break;
  326.       case QWIKKEY :    /* all ^Q functions */
  327.            lastgraph = NULL;
  328.            info();
  329.            break;
  330.       case BOLKEY :
  331.            sync(0);
  332.            break;
  333.       case EOLKEY :
  334.            sync( strlen( text ) );
  335.            break;
  336.       case HOMEKEY :    /* last line of file */
  337.            if ( jumpline( lastl - cline ) )  {
  338.                 sync( strlen( text ) );
  339.            }
  340.            break;
  341.       case BOFKEY :     /* first line of file */
  342.            if ( jumpline( 1 - cline ) )  sync( 0 );
  343.            break;
  344.       case LEFTKEY :
  345.            movechar(-1);
  346.            break;
  347.       case RIGHTKEY :
  348.            movechar(1);
  349.            break;
  350.       case LEFTWKEY :
  351.            moveword(-1);
  352.            break;
  353.       case RIGHTWKEY :
  354.            moveword(1);
  355.            break;
  356.       case DELLEFT :
  357.            changed = YES;
  358.            deletechar(-1);
  359.            break;
  360.       case DELRIGHT :
  361.            deletechar(0);
  362.            changed = YES;
  363.            break;
  364.       case DELWDKEY :
  365.            changed = YES;
  366.            deleteword();
  367.            break;
  368.       case JUMPKEY :
  369.            makedim();
  370.            putmess( "J|ump ([+/-]n,|RET|=crnt) ? " );
  371.            scans(ans,6);
  372.            makebright();
  373.            if ( !*ans )  jmpto = cline;
  374.               else
  375.                 calcjmp();
  376.            break;
  377.       case TOPSCRKEY :
  378.            moveline( ( topline-cursory ) );
  379.            break;
  380.       case BOTSCRKEY :
  381.            moveline( ( SHEIGHT-cursory ) );
  382.            break;
  383.       case REPKEY :
  384.            if ( lastgraph )  {
  385.                 changed = YES;
  386.                 insertchar( lastgraph );
  387.            }
  388.            else  {
  389.                 repeat = YES;
  390.                 dofindrep(1);
  391.                 repeat = NO;
  392.            }
  393.            break;
  394.       case HELPKEY :
  395.       case F1KEY :             /* help menu */
  396.          switch ( screen )  {
  397.            case HELP :
  398.              screen = NO;
  399.              break;
  400.            default :
  401.              show_table( HELP );
  402.            }
  403.            break;
  404.       case CR :
  405.            changed = YES;
  406.            crinsert(0);
  407.            break;
  408.       case CRSTILL :
  409.            changed = YES;
  410.            crinsert(-1);
  411.            break;
  412.       case OOPSKEY :
  413.            undo();
  414.            break;
  415.       case TAB :
  416.            changed = YES;
  417.            insertchar('\t');
  418.            break;
  419.       case ESCKEY :
  420.            if ( screen )  {
  421.                 screen = NO;
  422.                 lastgraph = NULL;
  423.                 puttext();
  424.            }
  425.            else {
  426.              resetcursor();
  427.              while ( !( c = inkey() ) );
  428.                if ( c < ' ' ) ;                   /* c already CTRL */
  429.                   else
  430.                     if ( c < '@' ) break;         /* c not CTRL char */
  431.                         else                      /* c either upper or lower */
  432.                         c -= ( ( char ) ( ( c < '`' ) ? 64 : 96 ) );
  433.            }
  434.            break;
  435.       case ALTKEY :
  436.            if ( screen )  {
  437.                 lastgraph = get_graphic();
  438.                 changed = YES;
  439.                 insertchar( lastgraph );
  440.            }
  441.            else
  442.                 get_graphic();
  443.            break;
  444.       case INSKEY :
  445.            if ( overtype  )  {
  446.                 overtype = NO;
  447.                 scr_aputs( OVERT, 0, "          ", HIGH );
  448.            }
  449.            else {
  450.                 overtype = YES;
  451.                 scr_aputs( OVERT, 0, " Overtype ", REVS );
  452.            }
  453.            break;
  454.       case CAPSLKON :
  455.            scr_aputs( CAPLK, 0, " Caps ", REVS );
  456.            break;
  457.       case CAPSLKOFF :
  458.            scr_aputs( CAPLK, 0, "      ", HIGH );
  459.            break;
  460.       case F2KEY :                     /* update time */
  461.            show_time();
  462.            break;
  463.       case GREYMINUS :
  464.       case F3KEY :                     /* move cursor word left */
  465.            moveword(-1);
  466.            break;
  467.       case GREYPLUS :
  468.       case F4KEY :                     /* move cursor word right */
  469.            moveword(1);
  470.            break;
  471.       case F5KEY :
  472.            to = 'k';
  473.            finish(to);
  474.            break;
  475.       case F6KEY :
  476.            #ifdef DS
  477.              getenv( "LS", envstr );
  478.            #else
  479.              envstr = getenv( "LS" );
  480.            #endif
  481.  
  482.            run( "ls ", envstr, 1 );
  483.            break;
  484.       case F7KEY :
  485.            #ifdef DS
  486.              getenv( "MORE", envstr );
  487.            #else
  488.              envstr = getenv( "MORE" );
  489.            #endif
  490.  
  491.            run( "more ", envstr, 1 );
  492.            break;
  493.       case F8KEY :
  494.            #ifdef DS
  495.              getenv( "GREP", envstr );
  496.            #else
  497.              envstr = getenv( "GREP" );
  498.            #endif
  499.  
  500.            run( "grep ", envstr, 1 );
  501.            break;
  502.       case F9KEY :
  503.          switch ( screen )  {
  504.            case  TABLE1 :
  505.              show_table( TABLE2 );
  506.              break;
  507.             default :
  508.              show_table( TABLE1 );
  509.            }
  510.            break;
  511.       case F10KEY :
  512.            envir();
  513.            show_fkeys();
  514.            break;
  515.       default :
  516.            changed = YES;
  517.            insertchar(c);
  518.            break;
  519.       }
  520.   }
  521. }
  522.  
  523.  
  524. /* No to return to current file or don't return,
  525.  * but exit if finished altogther
  526.  * return Yes to edit another file
  527.  */
  528. int finish(o)
  529. int o;
  530. {
  531. int abandon;
  532. char c, tempname[FILELEN], namebak[FILELEN];
  533.  
  534. if ( o != 'x' &&  o != 'k' )  {
  535.    putmess
  536.      ( "W|rite edited text to file, |A|bandon all edits, |Esc|ape to return " );
  537.    while ( ( c = getlow() ) != 'w' && c != 'a' && c != ESCKEY );
  538.    if ( c == ESCKEY )
  539.         return  NO;
  540.    abandon = c == 'a';
  541. }
  542.  
  543. if ( o == 'k' )  c = 'w';
  544.  
  545. if ( ( c == 'w' ) || ( o == 'x' )  )  {
  546.    if ( ( !filename[0] ) )  {
  547.       putmess( "F|ile to write to? " );
  548.       if ( ( scans( filename, FILELEN ) ) == ESCKEY )
  549.              return NO;
  550.  
  551.       format( filename );
  552.  
  553.       if ( filename[0] <= ' '  ||  ( !backup && !exists( filename ) ) )  {
  554.            filename[0] = '\0';
  555.            return  NO;
  556.       }
  557.    }
  558.    if ( backup )  {   /* delete old bak file */
  559.         strcpy( namebak, filename );
  560.         retag(  namebak, "BAK" );
  561.         if ( checkexists( namebak ) )
  562.         if ( funlink( namebak ) == FAIL )  return  NO;
  563.    }
  564.    /* keep old name in 'filename'
  565.     */
  566.    strcpy( tempname, filename );
  567.    /* new file called 'filename.@@@ ' - or whatever you like
  568.     */
  569.    retag( tempname, "@@@" );
  570.    if ( writefile( 1, lastl, tempname, filename, YES ) == FAIL )
  571.         return  NO;
  572.    /* check original file still exists -
  573.     * may have been deleted or renamed by user
  574.     */
  575.    if ( checkexists( filename ) )  {
  576.       if ( backup )  {
  577.        /* orig. file becomes '.bak'
  578.         */
  579.       if ( frename( filename, namebak ) == FAIL )
  580.            goto failed;
  581.    }
  582.    else  {
  583.       /* delete orig file
  584.        */
  585.        if ( funlink(filename) == FAIL )  {
  586.   failed:    /* if can't delete/rename old file, change
  587.               * new name to '.@@@'
  588.               */
  589.            strcpy( filename, tempname );
  590.            goto nowrite;
  591.            }
  592.         }
  593.       }
  594.      /* new file goes from '@@@' to orig name
  595.       */
  596.       frename( tempname, filename );
  597.       changed = NO;     /* file now not changed */
  598.       }
  599.     if ( o == 'x' )  {
  600.         if ( pagefd != NOFILE )  {
  601.              close( pagefd );
  602.              funlink( pagingfile );
  603.         }
  604.         xit();
  605.     };
  606.  
  607. nowrite:
  608.  
  609. if ( o != 'k' )  {
  610.     putmess( "|e|X|it to DOS, |A|nother file, |Esc|ape to return " );
  611.     while ( ( c = getlow() ) != 'x' && c != ESCKEY && c != 'a' );
  612. }
  613. else
  614.    c = ESCKEY;
  615.  
  616.   switch(c)  {
  617.  
  618.     case 'x' :
  619.       if ( changed )
  620.          if ( !dispose() )  return  NO;
  621.       ffclose( ( struct iobuffer * ) textbuf );
  622.       if ( pagefd != NOFILE )  {
  623.            close( pagefd );
  624.            funlink( pagingfile );
  625.       }
  626.       xit();
  627.  
  628.     case 'a' :
  629.       if ( changed )
  630.          if ( !dispose() )  return  NO;
  631.       ffclose( ( struct iobuffer * ) textbuf );
  632.       if ( pagefd != NOFILE )  {
  633.            close( pagefd );
  634.            funlink( pagingfile );
  635.       }
  636.       askforfile();
  637.       return  YES;
  638.  
  639.     case ESCKEY :
  640.       if ( !abandon )  {
  641.           scr_xy( WAITPOS, 0 );
  642.           opentext( filename );
  643.           lastl    = UNKNOWN;
  644.           lastread = 0;
  645.           goteof   = NO;
  646.           initvm();
  647.           gettext( cline );
  648.           errmess  = NULL;
  649.           putstatusline( cline );
  650.       }
  651.   }
  652. return  NO;
  653. }
  654.  
  655.  
  656. /* check to dispose of modified file
  657.  */
  658. int dispose()
  659. {
  660. putmess( "A|bandon modified file?| (y/n) ");
  661.  
  662. if ( getlow() == 'y' )  return  YES;
  663. return  NO;
  664. }
  665.  
  666.  
  667. /* quit editor and leave cursor at bottom of screen
  668.  */
  669. void xit()
  670. {
  671. scr_delete( 0, 24 );
  672. scr_xy( 0, 23 );
  673. exit( 0 );
  674. }
  675.  
  676.  
  677. /* get another file to edit into 'filename'
  678.  */
  679. int askforfile()
  680. {
  681. int drive;
  682.  
  683. while( YES )  {
  684.   scr_clr();
  685.   dirdone:
  686.     if ( errmess != NULL )  {
  687.          scr_xy( EMPOS, 0 );
  688.          putstr( errmess );
  689.     }
  690.   scr_putstr( 0, 0,"File to edit: ", HIGH );
  691.  
  692.   scr_putstr( 0, 24,
  693. "   ESC to exit  '>' for directory  <CR> new file  A:-P: change default disk     ",
  694. REVS );
  695.   scr_curson();
  696.   scr_xy( 14, 0 );
  697.  
  698.   if ( scans( filename, FILELEN ) == ESCKEY )  xit();
  699.  
  700.   scr_delete( EMPOS, 0 );  errmess = NULL;
  701.  
  702.   if ( filename[0] == '>' )  {
  703.        #ifdef DS
  704.          getenv( "LS", envstr );
  705.        #else
  706.          envstr = getenv( "LS" );
  707.        #endif
  708.  
  709.        run( "ls ", envstr, 1 );
  710.        scr_delete( 0, 0 );
  711.        goto  dirdone;
  712.   }
  713.  
  714.   if ( strlen(filename) == 2 &&  filename[1] == ':' )  {
  715.      if ( ( drive = toupper( filename[0]) - 'A' ) >= 0 && drive < 16 )  {
  716.                                     {
  717.           if ( seldisk( drive ) )  continue;
  718.                 }
  719.                 curdsk = drive;
  720.          }
  721.      }
  722.      else  {
  723.        name[0] = '\0';
  724.        return  YES;
  725.      }
  726.   }
  727. }
  728.  
  729.  
  730. int seldisk(drive)
  731. int drive;
  732. {
  733.  
  734. _os( SELDSK, drive );
  735.  
  736. return 0;
  737. }
  738.  
  739.  
  740. /* displays message, returns to a known good screen
  741.  */
  742. void fatalerror(message)
  743. char  *message;
  744. {
  745. error( message );
  746. moveline( goodline-cline );
  747.  
  748. #ifdef  MSC
  749.   longjmp( mark, 1 );
  750. #else
  751.   longjmp( 0, 1 );
  752. #endif
  753. }
  754.