home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l440 / 2.ddi / CHAP6 / ENVEDT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-27  |  11.6 KB  |  303 lines

  1. /**********************************************************
  2.  *  ENVEDT.C - Editor for Master Environment Variables    *
  3.  *  Jim Kyle, July 8, 1990                                *
  4.  *                                                        *
  5.  *      qcl envedt.c eea.obj envpkg.obj nxtevar.obj       *
  6.  *   or cl envedt.c -MAmx eea.asm envpkg.asm nxtevar.asm  *
  7.  *   or tcc envedt.c eea.asm envpkg.asm nxtevar.asm       *
  8.  *                                                        *
  9.  *   NOTE: THIS FILE CONTAINS CODE THAT WAS ACCIDENTALLY  *
  10.  *   LEFT OUT OF THE VERSION PRINTED IN UNDOCUMENTED DOS  *
  11.  **********************************************************/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <conio.h>
  15. #include <string.h>
  16.  
  17. #ifndef FP_SEG
  18. #define FP_SEG(f) (*((unsigned *)&(f) + 1))
  19. #endif
  20.  
  21. #ifndef FP_OFF
  22. #define FP_OFF(f) (*((unsigned *)&(f)))
  23. #endif
  24.  
  25. #ifndef MK_FP
  26. #define MK_FP(s,o) ((void far *)\
  27.     (((unsigned long)(s) << 16) | (unsigned)(o)))
  28. #endif
  29.  
  30. extern char far * nxtevar( char far * vptr );
  31. extern char far * mstenvp( void );
  32. extern void max_xy( int *x, int *y );
  33. extern int col( void );
  34. extern int row( void );
  35. extern void setrc( int r, int c );
  36. extern int envsiz( char far * envptr);
  37.  
  38. char far * menv;                /* pointer to current var */
  39. char far * rest;                /* pointer to next var    */
  40. char far * lstbyt;              /* adr of last byte used  */
  41. char vname[512], *txtptr;       /* working buffer and ptr */
  42. int  nmlen,  insmode = 0,       /* name len, insert flag  */
  43.      max_x,  max_y,             /* screen limits          */
  44.      i,      c,                 /* scratchpads            */
  45.      begrow, begcol,            /* cursor, start of text  */
  46.      currow, curcol,            /*         current loc    */
  47.      endrow,                    /*         end of text    */
  48.      editing,                   /* loop control flag      */
  49.      i_cur, i_max,              /* cur, max i in txtptr   */
  50.      free_env;                  /* bytes free in env      */
  51.  
  52. void findvar( char * varnam )   /* find var, set txtptr   */
  53. { nmlen = strlen( varnam );
  54.   txtptr = NULL;                /* present not-found flag */
  55.   while ( *menv )
  56.     { rest = nxtevar( menv );   /* "rest" always next one */
  57.       sprintf( vname, "%Fs", menv );
  58.       if( vname[nmlen] == '=')  /* possible match found   */
  59.         { vname[nmlen] = '\0';
  60.           if (stricmp( vname, varnam ) == 0)
  61.             { txtptr = &vname[nmlen+1];
  62.               vname[nmlen] = '=';
  63.               return;           /* found it, get out now  */
  64.             }
  65.         }
  66.       menv = rest;              /* try again with next    */
  67.     }
  68. }
  69.  
  70. void calccrsr( void )           /* calc currow, curcol    */
  71. { begrow = endrow - (i_max / max_x );
  72.   if (( i_max % max_x ) == 0 )
  73.     begrow++;
  74.   begcol = 0;
  75.   currow = begrow + (i_cur / max_x );
  76.   curcol = begcol + (i_cur % max_x );
  77. }
  78.  
  79. void show_var( void )           /* display var content    */
  80. { setrc( begrow, begcol );      /* set to start           */
  81.   printf( txtptr );             /* show the string        */
  82.   endrow = row();               /* update end row if scrl */
  83.   if( ! col() &&                /* adjust for line scroll */
  84.       endrow == (max_y-1) )
  85.     endrow--;
  86.   calccrsr();                   /* establish cursor posn  */
  87. }
  88.  
  89. void do_del( void )
  90. { for (i=i_cur; txtptr[i]; i++ )/* slide over one to left */
  91.     txtptr[i] = txtptr[i+1];
  92.   if ( i_max && i_cur >= --i_max )       /* decr length   */
  93.     i_cur = (i_max - 1);        /* and adjust if needed   */
  94.   free_env++;                   /* account for freed byte */
  95.   setrc( begrow, begcol );      /* re-display the string  */
  96.   printf( txtptr );
  97.   endrow = row();               /* hold ending point      */
  98.   if( ! col() )                 /* adjust for line wrap   */
  99.     endrow--;                   /*   if now in col 0      */
  100.   putchar( ' ' );               /* erase garbage char     */
  101.   calccrsr();                   /* establish cursor posn  */
  102. }
  103.  
  104. void dochar( void )
  105. { if ( free_env < 3 )           /* just beep if no space  */
  106.     { putchar( 7 );
  107.       return;
  108.     }
  109.   if ( insmode )                /* open up a hole for new */
  110.     { if ( --free_env < 3 )     /* decr freespace count   */
  111.         { putchar( 7 );         /*   and if too little is */
  112.           return;               /*   left, beep and quit  */
  113.         }
  114.     for (i = ++i_max; i > i_cur; i--)
  115.       txtptr[i] = txtptr[i-1];
  116.     }
  117.   txtptr[i_cur++] = (char) c;   /* put char down          */
  118.   if ( i_cur >= i_max )         /* check for extending it */
  119.     { txtptr[ ++i_max ] = '\0'; /* set new EOS            */
  120.       if ( --free_env < 3 )     /* decr freespace count   */
  121.         { putchar( 7 );         /*   if too little is     */
  122.           return;               /*   left, beep and quit  */
  123.         }
  124.     }
  125.   show_var();                   /* re-display the string  */
  126. }
  127.  
  128. int edtxt( void )               /* read kbd, do editing   */
  129. { int retval;
  130.   begrow = row();
  131.   begcol = 0;
  132.   i_max = strlen( txtptr );     /* set buffer index limit */
  133.   i_cur = 0;                    /* and current index val  */
  134.   show_var();                   /* display the string     */
  135.   for ( editing=1; editing; )   /* main editing loop here */
  136.     { setrc( 0, 70 );           /* status message loc     */
  137.       printf("MODE: %s ", insmode ? "INS" : "REP" );
  138.       setrc( currow, curcol );  /* keep cursor posn curr  */
  139.       switch( c = getch() )
  140.         { case 0:               /* function key or keypad */
  141.             switch( getch() )
  142.               { case 30:        /* Alt-A, redisplay       */
  143.                   show_var();   /* re-display the string  */
  144.                   break;
  145.                 case 32:        /* Alt-D, delete variable */
  146.                   printf("\nDELETE this variable (Y/N)? ");
  147.                   if(( getch() & 89 ) == 89 ) /* 89 = 'Y' */
  148.                     { vname[0] = '\0';
  149.                       retval = 1;
  150.                       editing = 0;
  151.                     }
  152.                   break;
  153.                 case 71:        /* home, goto first char  */
  154.                   i_cur = 0;
  155.                   calccrsr();   /* establish cursor posn  */
  156.                   break;
  157.                 case 72:        /* up arrow               */
  158.                   if ( (i_cur - max_x ) > 0 )
  159.                     i_cur -= max_x;
  160.                   calccrsr();   /* establish cursor posn  */
  161.                   break;
  162.                 case 75:        /* left arrow             */
  163.                   if ( i_cur > 0 )
  164.                     i_cur--;
  165.                   calccrsr();   /* establish cursor posn  */
  166.                   break;
  167.                 case 77:        /* right arrow            */
  168.                   if ( i_cur < i_max )
  169.                     i_cur++;
  170.                   calccrsr();   /* establish cursor posn  */
  171.                   break;
  172.                 case 79:        /* end, goto last char    */
  173.                   i_cur = i_max;
  174.                   calccrsr();   /* establish cursor posn  */
  175.                   break;
  176.                 case 80:        /* down arrow             */
  177.                   if ( (i_cur + max_x ) < i_max )
  178.                     i_cur += max_x;
  179.                   calccrsr();   /* establish cursor posn  */
  180.                   break;
  181.                 case 82:        /* insert, toggle flag    */
  182.                   insmode = !insmode;
  183.                   break;
  184.                 case 83:        /* delete, remove 1 char  */
  185.                   do_del();
  186.                   break;
  187.               }                 /* end of special codes   */
  188.             break;
  189.           case 8:               /* backspace del to left  */
  190.             if (i_cur)
  191.               { i_cur--;        /* back up one first      */
  192.                 do_del();       /* then do the delete     */
  193.               }
  194.             break;
  195.           case 13:              /* Enter accepts changes  */
  196.             retval = 1;
  197.             editing = 0;
  198.             break;
  199.           case 27:              /* ESC quits without save */
  200.             retval = 0;
  201.             editing = 0;
  202.             break;
  203.           default:
  204.             if (c >= ' ' && c < 127)
  205.               dochar();         /* handle INS or REP      */
  206.             else
  207.               putchar( 7 );     /* beep on any other char */
  208.         }
  209.     }
  210.   setrc( endrow, 0 );
  211.   return (retval);
  212. }
  213.  
  214. void putenvbak( void )          /* copies back to env     */
  215. { char * locptr;
  216.   int save_size;
  217.  
  218.   save_size = FP_OFF( lstbyt ) - FP_OFF( rest ) + 1;
  219.   locptr = (char *)malloc( save_size );
  220.  
  221.   for( i=0; i<save_size; i++ )  /* save trailing data     */
  222.     locptr[i] = rest[i];
  223.   for( i=0; vname[i]; i++ )     /* copy edited string     */
  224.     *menv++ = vname[i];
  225.   if( vname[0] )                /* if not deleting...     */
  226.     *menv++ = '\0';             /* ...add EOS byte to var */
  227.   for( i=0; i<save_size; i++)   /* copy in trailing data  */
  228.     *menv++ = locptr[i];
  229.   free( locptr );               /* release save area      */
  230.  
  231.   printf("\nENVIRONMENT UPDATED." );
  232. }
  233.  
  234. void doedit( char * varnam )    /* find var, edit, save   */
  235. { printf("Editing '%s':\n", varnam );
  236.   menv = mstenvp();             /* set starting point     */
  237.   free_env = envsiz(menv) << 4; /* get the size in bytes  */
  238.   findvar( varnam );            /* look for the variable  */
  239.   for( lstbyt=menv; *lstbyt; )  /* menv set by findvar()  */
  240.     lstbyt=nxtevar(lstbyt);     /* locate end of var area */
  241.   if( lstbyt[1] == 1 && lstbyt[2] == 0 )
  242.     { lstbyt += 3;              /* skip loadfile name     */
  243.       while (*lstbyt)
  244.         lstbyt++;
  245.     }
  246.   lstbyt++;
  247.   free_env -= FP_OFF( lstbyt ); /* what's left is free    */
  248.   if ( txtptr == NULL )         /* didn't find the name   */
  249.     { free_env -= (nmlen+1);    /* take out free space    */
  250.       if ( free_env < 5 )
  251.         { puts("Not found, no room to add.");
  252.           return;
  253.         }
  254.       printf( "Not found; add it (Y/N)? " );
  255.       if(( getch() & 89 ) != 89 )       /* 89 = 'Y'       */
  256.         return;
  257.       for ( i=0; i<nmlen; i++ ) /* force to uppercase     */
  258.         vname[i] = (char) toupper( varnam[i] );
  259.       vname[nmlen] = '=';       /* add the equals sign    */
  260.       vname[nmlen+1] = '\0';    /* make content empty     */
  261.       txtptr = &vname[nmlen+1]; /* set text pointer to it */
  262.       putchar( '\n' );          /* start on fresh line    */
  263.       insmode = 1;              /* and in INS mode        */
  264.     }
  265.   printf("Free environment space = %d bytes.\n", free_env );
  266.   if ( edtxt() )                /* do the editing now     */
  267.     putenvbak();                /* copy to master env     */
  268.   else
  269.     printf("\nENVIRONMENT NOT CHANGED." );
  270.   putchar( '\n' );
  271. }
  272.  
  273. void showvars( void )           /* prints usage message   */
  274. { puts(" USAGE: ENVEDT varname [[name2] ... ]");
  275.   puts("where varname is the name of an env variable");
  276.   puts("  and name2, etc., are optional added names.");
  277.   puts("Current variable names are:" );
  278.   menv = mstenvp();
  279.   for( i=0; i<8; i++ )
  280.     vname[i] = ' ';
  281.   while ( *menv )               /* get and print names    */
  282.     { sprintf(vname+8, "%Fs", menv );
  283.       for( i=8; vname[i] != '='; i++ )
  284.         /* all done by for()        */ ;
  285.       vname[i] = '\0';
  286.       puts( vname );
  287.       menv = nxtevar( menv );
  288.     }
  289.   puts("Re-run with name(s) of variable(s) to be edited.");
  290. }
  291.  
  292. void main ( int argc, char **argv )
  293. { int i;
  294.  
  295.   if (argc < 2)
  296.     showvars();                 /* list all vars to CRT   */
  297.   else
  298.     { max_xy( &max_x, &max_y ); /* set up screen limits   */
  299.       while ( --argc )          /* process all vars named */
  300.         doedit( *++argv );
  301.     }
  302. }
  303.