#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'stevie/help.c' <<'END_OF_FILE' X/* $Header: /nw/tony/src/stevie/src/RCS/help.c,v 1.9 89/08/06 09:50:09 tony Exp $ X * X * Routine to display a command summary. X * (Dave Tutelman note: X * I added the ability to page backwards and forwards through help. X * In order to minimize the abuse to the existing code, I used X * "goto"s and labeled each screen. It's not the way I would have X * done help from scratch, but it's not TOO ugly. X * ) X */ X X#include X#include "stevie.h" X#include "ascii.h" X#include "keymap.h" X X/* Macro to show help screen 'n'. X * If C supported label types, it'd be cleaner to do it that way. */ X#define SHOWHELP( n ) switch(n) { \ X case 0: goto Screen0; \ X case 1: goto Screen1; \ X case 2: goto Screen2; \ X case 3: goto Screen3; \ X case 4: goto Screen4; \ X case 5: goto Screen5; \ X case 6: goto Screen6; \ X case 7: goto Screen7; \ X case 8: goto Screen8; \ X default: return (TRUE); } X Xextern char *Version; X Xstatic int helprow; Xstatic int lastscreen = 0; /* return to help in previous screen */ X X#ifdef HELP X Xstatic void longline(); X Xbool_t Xvi_help() X{ X int k; X X SHOWHELP( lastscreen ); /* where did we quit help last ? */ X X/*********************************************************************** X * Zeroth Screen : Index to the help screens. X ***********************************************************************/ X XScreen0: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Index to HELP Screens\n\ X =====================\n\n"); Xlongline("\ X 0 Help index (this screen)\n\ X 1 Positioning within file, adjusting the screen\n\ X 2 Character positioning\n\ X 3 Line positioning, marking & returning, undo & redo\n"); Xlongline("\ X 4 Insert & replace, words, sentences, paragraphs\n\ X 5 Operators, miscellaneous operations, yank & put\n\ X 6 \"Ex\" command line operations\n\ X 7 Set parameters\n\ X 8 System-specific features\n"); X X windgoto(0, 52); X longline(Version); X X SHOWHELP( helpkey (0) ); X X X/*********************************************************************** X * First Screen: Positioning within file, Adjusting the Screen X ***********************************************************************/ X XScreen1: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Positioning within file\n\ X =======================\n\ X ^F Forward screenfull\n\ X ^B Backward screenfull\n"); Xlongline("\ X ^D scroll down half screen\n\ X ^U scroll up half screen\n"); Xlongline("\ X G Goto line (end default)\n\ X ]] next function\n\ X [[ previous function\n\ X /re next occurence of regular expression 're'\n"); Xlongline("\ X ?re prior occurence of regular expression 're'\n\ X n repeat last / or ?\n\ X N reverse last / or ?\n\ X % find matching (, ), {, }, [, or ]\n"); Xlongline("\ X\n\ X Adjusting the screen\n\ X ====================\n\ X ^L Redraw the screen\n\ X ^E scroll window down 1 line\n\ X ^Y scroll window up 1 line\n"); Xlongline("\ X z redraw, current line at top\n\ X z- ... at bottom\n\ X z. ... at center\n"); X X SHOWHELP( helpkey (1) ); X X X/*********************************************************************** X * Second Screen: Character positioning X ***********************************************************************/ X XScreen2: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Character Positioning\n\ X =====================\n\ X ^ first non-white\n\ X 0 beginning of line\n\ X $ end of line\n\ X h backward\n"); Xlongline("\ X l forward\n\ X ^H same as h\n\ X space same as l\n\ X fx find 'x' forward\n"); Xlongline("\ X Fx find 'x' backward\n\ X tx upto 'x' forward\n\ X Tx upto 'x' backward\n\ X ; Repeat last f, F, t, or T\n"); Xlongline("\ X , inverse of ;\n\ X | to specified column\n\ X % find matching (, ), {, }, [, or ]\n"); X X SHOWHELP( helpkey (2) ); X X X/*********************************************************************** X * Third Screen: Line Positioning, Marking and Returning X ***********************************************************************/ X XScreen3: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Line Positioning\n\ X ================\n\ X H home window line\n\ X L last window line\n\ X M middle window line\n"); Xlongline("\ X + next line, at first non-white\n\ X - previous line, at first non-white\n\ X CR return, same as +\n\ X j next line, same column\n\ X k previous line, same column\n"); X Xlongline("\ X\n\ X Marking and Returning\n\ X =====================\n\ X `` previous context\n\ X '' ... at first non-white in line\n"); Xlongline("\ X mx mark position with letter 'x'\n\ X `x to mark 'x'\n\ X 'x ... at first non-white in line\n"); X Xlongline("\n\ X Undo & Redo\n\ X =============\n\ X u undo last change\n\ X U restore current line\n\ X . repeat last change\n"); X X SHOWHELP( helpkey (3) ); X X X/*********************************************************************** X * Fourth Screen: Insert & Replace, X ***********************************************************************/ X XScreen4: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Insert and Replace\n\ X ==================\n\ X a append after cursor\n\ X i insert before cursor\n\ X A append at end of line\n\ X I insert before first non-blank\n"); Xlongline("\ X o open line below\n\ X O open line above\n\ X rx replace single char with 'x'\n\ X R replace characters\n"); Xif (! P(P_TO)) Xlongline("\ X ~ change case (upper/lower) of single char\n"); X Xlongline("\ X\n\ X Words, sentences, paragraphs\n\ X ============================\n\ X w word forward\n\ X b back word\n\ X e end of word\n\ X ) to next sentence\n\ X } to next paragraph\n"); Xlongline("\ X ( back sentence\n\ X { back paragraph\n\ X W blank delimited word\n\ X B back W\n\ X E to end of W\n"); X X SHOWHELP( helpkey (4) ); X X X/*********************************************************************** X * Fifth Screen: Operators, Misc. operations, Yank & Put X ***********************************************************************/ X XScreen5: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Operators (double to affect lines)\n\ X ==================================\n\ X d delete\n\ X c change\n"); Xlongline("\ X < left shift\n\ X > right shift\n\ X y yank to buffer\n\ X ! filter lines (command name follows)\n"); Xif (P(P_TO)) Xlongline("\ X ~ reverse case (upper/lower)\n"); X Xlongline("\n\ X Miscellaneous operations\n\ X ========================\n\ X C change rest of line\n\ X D delete rest of line\n\ X s substitute chars\n"); Xlongline("\ X S substitute lines (not yet)\n\ X J join lines\n\ X x delete characters\n\ X X ... before cursor\n"); X Xlongline("\n\ X Yank and Put\n\ X ============\n\ X p put back text\n\ X P put before\n\ X Y yank lines"); X X SHOWHELP( helpkey (5) ); X X X/*********************************************************************** X * Sixth Screen: Command-line operations X ***********************************************************************/ X XScreen6: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X EX command-line operations\n\ X ==========================\n"); Xlongline("\ X :w write back changes\n\ X :wq write and quit\n\ X :x write if modified, and quit\n\ X :q quit\n\ X :q! quit, discard changes\n\ X :e name edit file 'name'\n\ X :e! reedit, discard changes\n"); Xif (P(P_TG)) Xlongline("\ X :e # edit alternate file\n"); Xelse Xlongline("\ X :e # edit alternate file (also ctrl-^)\n"); Xlongline("\ X :w name write file 'name'\n\ X :n edit next file in arglist\n\ X :N edit prior file in arglist\n\ X :rew rewind arglist\n\ X :f show current file and lines\n"); Xlongline("\ X :f file change current file name\n\ X :g/pat/p|d global command (print or delete only)\n\ X :s/p1/p2/ text substitution (trailing 'g' optional)\n\ X :ta tag to tag file entry 'tag'\n\ X ^] :ta, current word is tag\n"); Xif (P(P_TG)) Xlongline("\ X :untag back to before last ':ta' (also ctrl-^)\n"); Xlongline("\ X :sh run an interactive shell\n\ X :!cmd execute a shell command\n\ X"); X X SHOWHELP( helpkey (6) ); X X X/*********************************************************************** X * Seventh Screen: Set parameters X ***********************************************************************/ X XScreen7: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X Set Parameters\n\ X ==============\n"); Xlongline("\ X :set param-name[=param-value] to set\n\ X :set sm, :set nosm, :set co=23 examples\n\ X :set all display all values\n\ X :set display non-default values\n\n"); Xlongline("Abbrev, name, and current value:\n"); Xhparm(P_AI); hparm(P_SM); longline("\n"); Xhparm(P_BK); hparm(P_CO); longline("\n"); Xhparm(P_TS); hparm(P_MO); longline("\n"); Xhparm(P_IC); hparm(P_ML); longline("\n"); Xhparm(P_TG); hparm(P_TO); longline("\n"); Xhparm(P_EB); hparm(P_VB); longline("\n"); Xhparm(P_LI); hparm(P_NU); longline("\n"); Xhparm(P_SS); longline(" (# of lines for ^D, ^U)\n"); Xhparm(P_LS); longline(" (show tabs, newlines graphically)\n"); Xhparm(P_RP); longline(" (min # of lines to report on oper)\n"); Xhparm(P_WS); longline(" (search wraps around end of file)\n"); Xhparm(P_CR); longline(" (write newline to file as CR-LF)\n"); X X SHOWHELP( helpkey (7) ); X X X/*********************************************************************** X * Eighth Screen: System-Specific Features for DOS and OS/2 X ***********************************************************************/ X XScreen8: X CLS; X windgoto(helprow = 0, 0); X Xlongline("\ X MSDOS & OS/2 Special Keys\n\ X =========================\n"); Xlongline("\ X The cursor keypad does pretty much what you'd expect,\n"); Xlongline("\ X as long as you're not in text entry mode:\n\ X\n\ X Home, End, PgUp, PgDn, and the arrow keys navigate.\n\ X Insert enter text before cursor.\n\ X Delete delete character at the cursor.\n\n"); X Xlongline("\ X Function Keys\n\ X =============\n\ X F1 Help\n\ X F2 Next file (:n) Shift-F2 discard changes (:n!)\n\ X F3 Previous file (:N) Shift-F3 discard changes (:N!)\n"); Xlongline("\ X F4 Alternate file (:e #) Shift-F4 discard changes (:e! #)\n\ X F5 Rewind file list (:rew) Shift-F5 discard changes (:rew!)\n\ X F6 Next function (]]) Shift-F6 Prev. function ([[)\n\ X F8 Global subst. (:1,$s/)\n\ X F10 Save & quit (:x) Shift-F10 discard changes (:q!)"); X X SHOWHELP( helpkey (8) ); X X} X X X/* longline (p) X * Put the string p into the buffer, expanding newlines. X */ Xstatic void Xlongline(p) Xchar *p; X{ X register char *s; X X for ( s = p; *s ;s++ ) { X if ( *s == '\n' ) X windgoto(++helprow, 0); X else X outchar(*s); X } X} X X/* hparm (n) X * Put the help info for param #n into the buffer. X */ Xhparm (p) X int p; X{ X char buf[85]; /* was 25, too small(!), so increased to 85 */ X char *bp; X X sprintf(buf, " %6s %-10s ", X params[p].shortname, params[p].fullname); X bp = buf + strlen (buf); X if (params[p].flags & P_NUM) /* numeric param */ X sprintf(bp, "%-3d", params[p].value); X else { /* Boolean param */ X if (params[p].value) X strcpy (bp, "yes"); X else X strcpy (bp, "no "); X } X longline (buf); X} X X/* Get keystroke and return instructions on what to do next. X * Argument is current help screen. X * Return value is target help screen, or -1 to quit help. X */ X X#ifdef DOS X# define NSCREEN 8 X#else X#ifdef OS2 X# define NSCREEN 8 X#else X# define NSCREEN 7 X#endif X#endif X Xint Xhelpkey (n) X int n; X{ X static int c = '\0'; X int prevkey; X char banner [16]; X X /* Start with instructions on navigating Help */ X strcpy (banner, "PAGE 0 OF HELP"); X banner [5] = (char)n + '0'; X windgoto(helprow = Rows-4, 63); X longline(banner); X windgoto(helprow = Rows-3, 63); X longline("^^^^^^^^^^^^^^"); X windgoto(helprow = Rows-2, 54); X longline(""); X windgoto(helprow = Rows-1, 44); X longline("\n"); X X /* Now get keystrokes till we get a valid one */ X while (1) { X prevkey = c; X c = vgetc(); X switch (c) { X /* cases for Next Screen */ X case ' ': case '\t': X case '\n': case '\r': case '+': X case K_DARROW: X case 'f': case CTRL('F'): X case CTRL('D'): case CTRL('Y'): X case 'n': case 'N': case CTRL('N'): X case 'j': X if (n < NSCREEN) return (n+1); X break; X X /* cases for Previous Screen */ X case BS: case '-': X case K_UARROW: X case 'b': case CTRL('B'): X case CTRL('U'): case CTRL('E'): X case 'p': case 'P': case CTRL('P'): X case 'k': X if (n > 0) return (n-1); X break; X X /* cases for Quit Help */ X case ESC: X case 'Q': X case 'q': X case 'X': X case 'x': X lastscreen = n; /* remember where we quit */ X return (-1); X X /* "G" is presumed to be a "vi-style" go-to-line, X * except that we interpret it as go-to-screen. X */ X case 'G': X /* If previous key was a number, X * we're already there. Otherwise, go to X * last screen. X */ X if (prevkey<(int)'0' || prevkey>NSCREEN+(int)'0') X return (NSCREEN); X break; X X /* Default is screen number or invalid code */ X default: X if (c>=(int)'0' && c<=NSCREEN+(int)'0') X return ( c - (int)'0' ); X break; X } X } X} X X X#else X Xbool_t Xvi_help() X{ X msg("Sorry, help not configured"); X return FALSE; X} X#endif END_OF_FILE if test 14493 -ne `wc -c <'stevie/help.c'`; then echo shar: \"'stevie/help.c'\" unpacked with wrong size! fi # end of 'stevie/help.c' fi if test -f 'stevie/setenv.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stevie/setenv.c'\" else echo shar: Extracting \"'stevie/setenv.c'\" \(14259 characters\) sed "s/^X//" >'stevie/setenv.c' <<'END_OF_FILE' X/***************************************************************************** X * A program for adding or changing environment variable values for MSDOS. X * The "set" command provided by command.com is very limited. It fails to X * provide the ability to use quotation marks and escape characters and X * octal/hex constants in the value definition. Setenv provides these X * abilities. X * X * Usage notes: X * X * setenv = X * X * ::= legal MSDOS environment symbol. Lower case converted X * to uppercase. X * X * ::= environment symbol value in one of three forms: X * X * * No quotation marks. The value is the literal string X * of characters starting IMMEDIATELY after the equal X * sign and extending to the end-of-line. X * X * * Single quotation marks ('). The value is the literal X * string enclosed in quotation marks. X * X * * Double quotation marks ("). The value is the string X * enclosed in double quotation marks. Backslash escape X * constructions are processed -- this includes the usual X * C language constructions such as \n for newline and X * \r for carriage return plus octal and hexadecimal X * constants (\ddd & \0xdd, respectively). X *****************************************************************************/ X X/***************************************************************************** X * Based on a program by Alan J Myrvold (ajmyrvold@violet.waterloo.edu) X * X * WARNING WARNING WARNING - virtually no error checking is done !! X * use at own risk !! X * X * This program by Larry A. Shurr (las@cbema.ATT.COM) X * X * I added checking for env seg overrun, so now it's a little more robust. X *****************************************************************************/ X X/***************************************************************************** X * X * Notes by Alan J Myrgold: X * X * Technical information : A program's PSP contains a pointer at X * offset 44 (decimal) to a COPY of the parent's environment. X * The environment is a set of strings of the form NAME=value, X * each terminated by a NULL byte. X * An additional NULL byte marks the end of the environment. X * The environment area is ALWAYS paragraph aligned X * i.e. on a 16 byte boundary. X * X * Searching backwards from the PSP, I consistently find X * two copies of the envronment area. X * X * The program : finds the two areas X * reads one into memory X * udpates the specified environment variable X * writes updated environment to parent environment X *****************************************************************************/ X X#include X#include X#include X#include X#include X#include X#include X X#define FALSE 0 X#define TRUE 1 X Xstruct mcb { /* MSDOS Memory Control Block */ X unsigned char tag4D; /* Tag field must = 0x4D */ X unsigned int next; /* Segment base for next block */ X unsigned int size; /* Memory block size in paragraphs */ X}; X X Xunsigned env_size = 0; /* Maintain size of environment */ X/***************************************************************************/ Xint env_size_bytes(unsigned env_seg) X/* Determine the length of the environment area in bytes */ X{ X int n; X X n = 0; X while (peekb(env_seg,n) != 0) { X while (peekb(env_seg,n) != 0) n++; X n++; X } X return(n); X} X/***************************************************************************/ Xint env_size_strings(unsigned env_seg) X/* Determine how many strings are in the environment area */ X{ X int k,n; X X k = n = 0; X while (peekb(env_seg,n) != 0) { X k++; X while (peekb(env_seg,n) != 0) n++; X n++; X } X return(k); X} X/***************************************************************************/ Xint peek_cmp(unsigned seg1,unsigned seg2,int nbytes) X/* A trivial compare routine for segement aligned data items */ X{ X int i; X X for (i = 0; (i < nbytes) && (peekb(seg1,i) == peekb(seg2,i)); i++); X return(i == nbytes); X} X/***************************************************************************/ Xvoid find_env(unsigned seg_ray[2]) X{ X unsigned psp_seg,copy_of_seg,env_seg; X int k,n; X X/* Find first copy of environment */ X psp_seg = _psp; X copy_of_seg = peek(psp_seg,44); X X/* Set return value to non-garabage */ X seg_ray[0] = seg_ray[1] = copy_of_seg; X X/* Search back to find 2 copies of environment */ X env_size = n = env_size_bytes(copy_of_seg); X env_seg = copy_of_seg - 1; X for (k = 0; (env_seg != 0) && (k < 2); k++) { X while ((env_seg != 0) && X (peek_cmp(copy_of_seg,env_seg,n) == 0)) { X env_seg--; X } X if (env_seg != 0) { X seg_ray[k] = env_seg; X env_seg--; X } X } X X/* If not found, display error message and abort */ X if (k != 2) { X fprintf(stderr,"Two copies of the environment were not found\n"); X exit(-1); X } X} X/***************************************************************************/ Xvoid read_env(unsigned env_seg,int *k,char ***s,char ***t) X/* Read environment into a malloc'd array of malloc'd strings */ X{ X int i,j,n; X X env_size = env_size_bytes(env_seg); X X *k = env_size_strings(env_seg); X *s = (char **) malloc((*k)*sizeof(char *)); X *t = (char **) malloc((*k)*sizeof(char *)); X X n = 0; X for (i = 0; i < *k; i++) { X for (j = 0; peekb(env_seg,n+j) != '='; j++); X (*s)[i] = (char *) malloc(j+1); X for (j = 0; peekb(env_seg,n+j) != '='; j++) X ((*s)[i])[j] = peekb(env_seg,n+j); X ((*s)[i])[j] = 0; X n += j + 1; X for (j = 0; peekb(env_seg,n+j) != 0; j++); X (*t)[i] = (char *) malloc(j+1); X for (j = 0; peekb(env_seg,n+j) != 0; j++) X ((*t)[i])[j] = peekb(env_seg,n+j); X ((*t)[i])[j] = 0; X n += j + 1; X } X} X/***************************************************************************/ Xvoid write_env(unsigned env_seg, int k, char **s, char **t) X/* Write the environment back out to memory */ X{ X int i,j,n; X X struct mcb far *tmcb = (struct mcb far *)((long)(env_seg-1) << 16); X X if (tmcb->tag4D == 0x4D) { X unsigned env_seg_siz = tmcb->size << 4; X if (env_size < env_seg_siz) { X for (n = i = 0; i < k; i++) { X char *si = s[i]; X char *ti = t[i]; X for (j = 0; si[j] != 0; j++) pokeb(env_seg,n++,si[j]); X pokeb(env_seg,n++,'='); X for (j = 0; ti[j] != 0; j++) pokeb(env_seg,n++,ti[j]); X pokeb(env_seg,n++,0); X } X pokeb(env_seg,n,0); X } else { X fprintf(stderr,"Insufficient space in environment\n"); X exit(-1); X } X } else { X fprintf(stderr,"Environment memory control block trashed\n"); X exit(-1); X } X} X/***************************************************************************/ Xchar *get_env_var(int k,char **s,char **t,char *var) X/* Return the value of the environment variable or NULL if not found */ X{ X char *val; X int i; X X val = NULL; X for (i = 0; i < k; i++) if (stricmp(s[i],var) == 0) val = t[i]; X X return(val); X} X X/***************************************************************************/ Xvoid set_env_var(int *k,char ***s,char ***t,char *var,char *val) X/* Set a new or existing environment variable to a new value */ X{ X int i,done; X X done = 0; X for (i = 0; i < *k; i++) { X if (stricmp((*s)[i],var) == 0) { X /* Existing variable */ X done = 1; X env_size -= strlen((*t)[i]); X free((*t)[i]); X (*t)[i] = (char *) malloc(1+strlen(val)); X strcpy((*t)[i],val); X env_size += strlen((*t)[i]); X } X } X X if (!done) { X /* New environment variable */ X (*k)++; X *s = realloc(*s,(*k)*sizeof(char *)); X *t = realloc(*t,(*k)*sizeof(char *)); X (*s)[*k-1] = (char *) malloc(1+strlen(var)); X strcpy((*s)[*k-1],var); X strupr((*s)[*k-1]); X (*t)[*k-1] = (char *) malloc(1+strlen(val)); X strcpy((*t)[*k-1],val); X /* Length of name + length of '=' + length of value + length of '\0' */ X env_size += (strlen((*s)[*k-1]) + 1 + strlen((*t)[*k-1]) + 1); X } X} X/***************************************************************************/ Xvoid show_env(int k,char **s,char **t) X/* Display the array of environment strings */ X{ X int i; X for (i = 0; i < k; i++) printf("%s=%s\n",s[i],t[i]); X} X/***************************************************************************/ Xvoid get_cmdline(char *cmd) X/* Read raw command line text into string buffer */ X{ X char far *pcmd; X X int idx,odx; X X pcmd = (char far *)((long)_psp << 16) + 128L; X X for (idx = *pcmd++, odx = 0; idx > 0; idx--, odx++) { X cmd[odx] = *pcmd++; X } X X cmd[odx] = '\0'; X} X/***************************************************************************/ Xchar_in(char ch, char *set) X/* Determine if a character is in a set of characters */ X{ X do { X if (ch == *set) return(TRUE); X } while ((int)*(++set)); X return(FALSE); X} X/***************************************************************************/ Xchar get_num(char *cmd, int *pidx) X/* Interpret octal or hexadecimal constant in string */ X{ X int accum = 0; X char ch; X int f_scan = TRUE; X int idx = *pidx; X int limit; X char *nch = cmd+idx; X char *och = nch+1; X int radix; X X#define HEXDIG "0123456789ABCDEFabcdef" X X if (*nch == '0' && char_in(*och,"xX") && char_in(*(och+1),HEXDIG)) { X radix = 16; X limit = 2; X och += 1; X } else { X radix = 8; X limit = 3; X och = nch; X } X X while (limit-- > 0 && f_scan) { X X f_scan = FALSE; X X while ((int)(*nch)) *nch++ = *och++; X X nch = cmd+idx; X och = nch+1; X X switch (ch = *nch) { X case '0' : X case '1' : X case '2' : X case '3' : X case '4' : X case '5' : X case '6' : X case '7' : X case '8' : X case '9' : X if (ch == 9 && radix == 8) break; X accum = accum * radix + (int)(ch - '0'); X f_scan = TRUE; X break; X case 'A' : X case 'B' : X case 'C' : X case 'D' : X case 'E' : X case 'F' : X if (radix == 8) break; X accum = accum * radix + (int)(ch - 'A') + 10; X f_scan = TRUE; X break; X case 'a' : X case 'b' : X case 'c' : X case 'd' : X case 'e' : X case 'f' : X if (radix == 8) break; X accum = accum * radix + (int)(ch - 'a') + 10; X f_scan = TRUE; X break; X default : break; X } X } X X *pidx = idx; X return(accum); X} X/***************************************************************************/ Xget_escape(char *cmd, int *pidx, char quote) X/* Interpret escape'd (i.e., '\' (backslash) character */ X{ X int idx = *pidx; X X if (quote == '"') { X char *nch = cmd+idx; X char *och = nch+1; X char *xch = nch; X while ((int)(*nch)) *nch++ = *och++; X switch (*xch) { X case 'a' : *xch = '\a'; break; X case 'b' : *xch = '\b'; break; X case 'c' : *xch = '\c'; break; X case 'd' : *xch = '\d'; break; X case 'e' : *xch = '\e'; break; X case 'f' : *xch = '\f'; break; X case 'g' : *xch = '\g'; break; X case 'h' : *xch = '\h'; break; X case 'i' : *xch = '\i'; break; X case 'j' : *xch = '\j'; break; X case 'k' : *xch = '\k'; break; X case 'l' : *xch = '\l'; break; X case 'm' : *xch = '\m'; break; X case 'n' : *xch = '\n'; break; X case 'o' : *xch = '\o'; break; X case 'p' : *xch = '\p'; break; X case 'q' : *xch = '\q'; break; X case 'r' : *xch = '\r'; break; X case 's' : *xch = '\s'; break; X case 't' : *xch = '\t'; break; X case 'u' : *xch = '\u'; break; X case 'v' : *xch = '\v'; break; X case 'w' : *xch = '\w'; break; X case 'x' : *xch = '\x'; break; X case 'y' : *xch = '\y'; break; X case 'z' : *xch = '\z'; break; X case '0' : X case '1' : X case '2' : X *xch = get_num(cmd, &idx); X break; X } X } X X *pidx = idx + 1; X} X/***************************************************************************/ Xget_qvalue(char *cmd, int idx, char quote, char **value) X/* Extract a quoted value part from command line */ X{ X char ch; X int f_esc; X X *value = cmd + (++idx); X X do { X while ((int)(ch = cmd[idx]) && ch != '\\' && ch != quote) idx++; X if (!(int)ch) return(-1); X if (ch == '\\') { X f_esc = TRUE; X get_escape(cmd, &idx, quote); X } else f_esc = FALSE; X } while (f_esc); X X cmd[idx] = '\0'; X X for (idx += 1; (int)(ch = cmd[idx]) && ch == ' '; idx++); X X if ((int)ch) return(-1); X X return(0); X} X/***************************************************************************/ Xget_parm(char **name, char **value) X/* Extract environment symbol name and value from command line */ X{ X char ch; X int idx; X int sdx; X X static char cmd[128]; X X get_cmdline(cmd); X X for (idx = 0; (int)(ch = cmd[idx]) && ch == ' '; idx++); X X if (!(int)ch) return(1); X X *name = cmd + idx; X X for (; (int)(ch = cmd[idx]) && ch != '=' && ch != ' '; idx++); X X if (!(int)ch) return(-1); X X if (ch == ' ') { X cmd[idx] = '\0'; X for (idx += 1; (int)(ch = cmd[idx]) && ch != '='; idx++); X } else cmd[idx] = '\0'; X X if (!(int)ch) return(-1); X X for (sdx = (idx += 1); (int)(ch = cmd[idx]) && ch == ' '; idx++); X X /*if (!(int)ch) return(-1);*/ X X switch (ch) { X case '"' : return(get_qvalue(cmd, idx, '"', value)); X case '\'' : return(get_qvalue(cmd, idx, '\'', value)); X default : *value = cmd + sdx; break; X } X X return(0); X} X/***************************************************************************/ Xmain(int argc,char **argv) X{ X unsigned env_seg[2]; X char **s,**t; X int k; X long now; X struct tm *local; X X static char *name = NULL, *value = NULL; X X switch (get_parm(&name,&value)) { X X case -1: X X fprintf(stderr,"Invalid symbol definition syntax\n"); X exit(-1); X X case 0: X X /* Find and read environment */ X X find_env(env_seg); X read_env(env_seg[1],&k,&s,&t); X X /* Set the variable to */ X X set_env_var(&k,&s,&t,name,value); X X /* Update caller's environment */ X X write_env(env_seg[0],k,s,t); X X break; X X case 1: X X fprintf(stderr,"Usage: setenv = \n"); X break; X } X X return(0); X} X/***************************************************************************/ X END_OF_FILE if test 14259 -ne `wc -c <'stevie/setenv.c'`; then echo shar: \"'stevie/setenv.c'\" unpacked with wrong size! fi # end of 'stevie/setenv.c' fi echo shar: End of archive 8 \(of 13\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 13 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0