From decwrl!sdd.hp.com!cs.utexas.edu!uunet!allbery Mon May 7 07:37:32 PDT 1990 Article 1501 of comp.sources.misc: Path: decwrl!sdd.hp.com!cs.utexas.edu!uunet!allbery From: istewart@datlog.co.uk Newsgroups: comp.sources.misc Subject: v12i022: MS_SH 1.6 Upgrade Kit - Part 04 of 08 Message-ID: <87524@uunet.UU.NET> Date: 5 May 90 17:06:39 GMT Sender: allbery@uunet.UU.NET Lines: 1671 Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Posting-number: Volume 12, Issue 22 Submitted-by: istewart@datlog.co.uk Archive-name: ms_sh-1.6/part04 #!/bin/sh # this is part 4 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file Patch1.6 continued # CurArch=4 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file Patch1.6" sed 's/^X//' << 'SHAR_EOF' >> Patch1.6 X! /* Always leave room for NL */ X! char *ep = &e.linep[LINE_MAX - 3]; X X! while ((ip = t->words[n++]) != (char *)NULL) X { X if ((n == 2) && (strcmp (ip, "-n") == 0)) X { X no_eol++; X--- 311,339 ---- X static int doecho (t) X register C_Op *t; X { X! int n = 1; /* Argument number */ X int no_eol = 0; /* No EOL */ X char *ip; /* Input pointer */ X int c_val; /* Current character */ X char c; X bool end_s; X! Out_Buf *bp; X X! /* Get some memory for the buffer */ X! X! if ((bp = Open_buffer (1, FALSE)) == (Out_Buf *)NULL) X { X+ print_error ("echo: %s\n", strerror (ENOMEM)); X+ return 1; X+ } X+ X+ /* Process the arguments */ X+ X+ while ((ip = t->words[n++]) != (char *)NULL) X+ { X+ X+ /* Check for -n switch */ X+ X if ((n == 2) && (strcmp (ip, "-n") == 0)) X { X no_eol++; X*************** X*** 305,332 **** X X /* Output the character */ X X! if (cp < ep) X! *(cp++) = c; X X- else X- { X- v1_putsn (e.linep, (int)(cp - e.linep)); X- cp = e.linep; X- } X- X } while (!end_s); X } X X /* Is EOL required ? */ X X if (!no_eol) X! *(cp++) = NL; X X /* Flush buffer */ X X! if ((n = (int)(cp - e.linep))) X! v1_putsn (e.linep, n); X! X return 0; X } X X--- 375,393 ---- X X /* Output the character */ X X! Add_buffer (c, bp); X X } while (!end_s); X } X X /* Is EOL required ? */ X X if (!no_eol) X! Add_buffer (NL, bp); X X /* Flush buffer */ X X! Close_buffer (bp); X return 0; X } X X*************** X*** 375,382 **** X X /* Check for an octal string */ X X! if ((c_val >= 0) && (c_val < 8)) X { X while ((IS_OCTAL (**cp))) X c_val = (c_val * 8) + *((*cp)++) - '0'; X X--- 436,445 ---- X X /* Check for an octal string */ X X! if (IS_OCTAL (c_val)) X { X+ c_val -= '0'; X+ X while ((IS_OCTAL (**cp))) X c_val = (c_val * 8) + *((*cp)++) - '0'; X X*************** X*** 393,400 **** X static int dover (t) X C_Op *t; X { X! v1printf (Copy_Right1, _osmajor, _osminor); X! v1a_puts (Copy_Right2); X return 0; X } X X--- 456,462 ---- X static int dover (t) X C_Op *t; X { X! Print_Version (1); X return 0; X } X X*************** X*** 896,904 **** X static int dochdir (t) X register C_Op *t; X { X! char *p; X! char *nd; X! register char *cp; X int first = 0; X unsigned int dummy; X unsigned int cdrive; X--- 958,967 ---- X static int dochdir (t) X register C_Op *t; X { X! char *p; /* Original new directory */ X! char *nd; /* New directory */ X! register char *cp; /* In CDPATH Pointer */ X! char *directory; X int first = 0; X unsigned int dummy; X unsigned int cdrive; X*************** X*** 917,942 **** X return 1; X } X X! /* Save the current drive */ X X _dos_getdrive (&cdrive); X X /* Scan for the directory. If there is not a / or : at start, use the X * CDPATH variable X */ X X! cp = (*p == '/') ? null : lookup ("CDPATH", FALSE)->value; X! cp = (*(p + 1) == ':') ? null : cp; X X do X { X! cp = path_append (cp, p, e.linep); X X /* Check for new disk drive */ X X! nd = e.linep; X X! if (*(nd+ 1) == ':') X { X _dos_setdrive (tolower (*nd) - 'a' + 1, &dummy); X nd += 2; X--- 980,1011 ---- X return 1; X } X X! if ((directory = getcell (FFNAME_MAX)) == (char *)NULL) X! { X! print_error ("cd: %s\n", strerror (ENOMEM)); X! return 1; X! } X X+ /* Save the current drive */ X+ X _dos_getdrive (&cdrive); X X /* Scan for the directory. If there is not a / or : at start, use the X * CDPATH variable X */ X X! cp = ((*p == '/') || (*(p + 1) == ':')) ? null X! : lookup ("CDPATH", FALSE)->value; X X do X { X! cp = path_append (cp, p, directory); X X /* Check for new disk drive */ X X! nd = directory; X X! if (*(nd + 1) == ':') X { X _dos_setdrive (tolower (*nd) - 'a' + 1, &dummy); X nd += 2; X*************** X*** 976,1004 **** X * Extract the next path from a string and build a new path from the X * extracted path and a file name X */ X! char *path_append (s1, s2, si) X! register char *s1; /* Path string */ X! register char *s2; /* File name string */ X! char *si; /* Output path */ X { X! register char *s; X X! s = si; X X! while (*s1 && *s1 != ';') X! *s++ = *s1++; X! X! if ((si != s) && (*(s - 1) != '/')) X *s++ = '/'; X X *s = '\0'; X X! if (s2 != (char *)NULL) X! strcpy (s, s2); X X! return (*s1 ? ++s1 : (char *)NULL); X! } X X /* X * Execute a shift command: shift X */ X--- 1045,1074 ---- X * Extract the next path from a string and build a new path from the X * extracted path and a file name X */ X! char *path_append (path_s, file_s, output_s) X! register char *path_s; /* Path string */ X! register char *file_s; /* File name string */ X! char *output_s; /* Output path */ X { X! register char *s = output_s; X! int fsize = 0; X X! while (*path_s && (*path_s != ';') && (fsize++ < FFNAME_MAX)) X! *s++ = *path_s++; X X! if ((output_s != s) && (*(s - 1) != '/') && (fsize++ < FFNAME_MAX)) X *s++ = '/'; X X *s = '\0'; X X! if (file_s != (char *)NULL) X! strncpy (s, file_s, FFNAME_MAX - fsize); X X! output_s[FFNAME_MAX - 1] = 0; X X+ return (*path_s ? ++path_s : (char *)NULL); X+ } X+ X /* X * Execute a shift command: shift X */ X*************** X*** 1062,1086 **** X register int i; X jmp_buf ex; X int *ofail; X X- t->ioact = (IO_Actions **)NULL; X- X for (i = 0; (t->words[i] = t->words[i + 1]) != (char *)NULL; i++) X ; X X! if (i == 0) X! return 0; X X execflg = 1; X ofail = failpt; X X /* Set execute function recursive level to zero */ X X Execute_stack_depth = 0; X X if (setjmp (failpt = ex) == 0) X execute (t, NOPIPE, NOPIPE, FEXEC); X X failpt = ofail; X execflg = 0; X return 1; X--- 1132,1162 ---- X register int i; X jmp_buf ex; X int *ofail; X+ IO_Actions **ios = t->ioact; X X for (i = 0; (t->words[i] = t->words[i + 1]) != (char *)NULL; i++) X ; X X! /* Left the I/O as it is */ X X+ if (i == 0) X+ return restore_std (0, FALSE); X+ X execflg = 1; X ofail = failpt; X X /* Set execute function recursive level to zero */ X X Execute_stack_depth = 0; X+ t->ioact = (IO_Actions **)NULL; X X if (setjmp (failpt = ex) == 0) X execute (t, NOPIPE, NOPIPE, FEXEC); X X+ /* Clear the extended file if an interrupt happened */ X+ X+ Clear_Extended_File (); X+ t->ioact = ios; X failpt = ofail; X execflg = 0; X return 1; X*************** X*** 1096,1119 **** X register int i; X register char *sp; X char *cp; X X if ((cp = t->words[1]) == (char *)NULL) X return 0; X X! sp = any ('/', cp) ? null : path->value; X X! do X { X! sp = path_append (sp, cp, e.linep); X X! if ((i = O_for_execute (e.linep)) >= 0) X! { X! exstat = 0; X! next (remap (i)); X! return exstat; X! } X! } while (sp != (char *)NULL); X X print_error ("%s: not found\n", cp); X return 1; X } X--- 1172,1203 ---- X register int i; X register char *sp; X char *cp; X+ char *l_path; X X if ((cp = t->words[1]) == (char *)NULL) X return 0; X X! /* Get some space */ X X! if ((l_path = getcell (FFNAME_MAX)) == (char *)NULL) X { X! print_error (".: %s\n", strerror (ENOMEM)); X! return 1; X! } X X! /* Save the current drive */ X X+ sp = (any ('/', cp) || (*(cp + 1) == ':')) ? null : path->value; X+ X+ do X+ { X+ sp = path_append (sp, cp, l_path); X+ X+ if ((i = O_for_execute (l_path, (char **)NULL, (int *)NULL)) >= 0) X+ return RUN (afile, remap (i), filechar, FALSE); X+ X+ } while (sp != (char *)NULL); X+ X print_error ("%s: not found\n", cp); X return 1; X } X*************** X*** 1125,1147 **** X static int doread (t) X C_Op *t; X { X! register char *cp, **wp; X register int nb; X X if (t->words[1] == (char *)NULL) X { X print_error ("Usage: read name ...\n"); X return 1; X } X X! for (wp = t->words + 1; *wp != (char *)NULL; wp++) X { X! for (cp = e.linep; cp < e.eline - 1; cp++) X { X if (((nb = read (STDIN_FILENO, cp, 1)) != 1) || (*cp == NL) || X ((wp[1] != (char *)NULL) && any (*cp, ifs->value))) X X! break; X } X X *cp = 0; X--- 1209,1256 ---- X static int doread (t) X C_Op *t; X { X! register char *cp; X! register char **wp; X register int nb; X+ bool nl_detected = FALSE; X+ char *buffer; X+ char *ep; X X+ /* Check usage */ X+ X if (t->words[1] == (char *)NULL) X { X print_error ("Usage: read name ...\n"); X return 1; X } X X! /* Get some memory */ X! X! if ((buffer = getcell (LINE_MAX)) == (char *)NULL) X { X! print_error ("read: %s\n", strerror (ENOMEM)); X! return 1; X! } X! X! ep = &buffer[LINE_MAX - 2]; X! X! /* Save the current drive */ X! X! for (wp = t->words + 1; *wp != (char *)NULL; wp++) X! { X! X! /* Read in until end of line, file or a field separator is detected */ X! X! for (cp = buffer; !nl_detected && (cp < ep); cp++) X { X if (((nb = read (STDIN_FILENO, cp, 1)) != 1) || (*cp == NL) || X ((wp[1] != (char *)NULL) && any (*cp, ifs->value))) X+ { X+ if ((nb != 1) || (*cp == NL)) X+ nl_detected = TRUE; X X! break; X! } X } X X *cp = 0; X*************** X*** 1149,1155 **** X if (nb <= 0) X break; X X! setval (lookup (*wp, TRUE), e.linep); X } X X return (nb <= 0); X--- 1258,1264 ---- X if (nb <= 0) X break; X X! setval (lookup (*wp, TRUE), buffer); X } X X return (nb <= 0); X*************** X*** 1162,1168 **** X static int doeval (t) X register C_Op *t; X { X! return RUN (awordlist, t->words + 1, wdchar); X } X X /* X--- 1271,1277 ---- X static int doeval (t) X register C_Op *t; X { X! return RUN (awordlist, t->words + 1, wdchar, TRUE); X } X X /* X*************** X*** 1177,1183 **** X char tval[10]; X char *cp; X X- X if (t->words[1] == (char *)NULL) X { X X--- 1286,1291 ---- X*************** X*** 1472,1478 **** X if ((vp->status & key) && isalpha (*vp->name)) X { X v1_puts (tstring); X! v1_putsn (vp->name, (int)(findeq (vp->name) - vp->name)); X v1_putc (NL); X } X } X--- 1580,1587 ---- X if ((vp->status & key) && isalpha (*vp->name)) X { X v1_puts (tstring); X! write (STDOUT_FILENO, vp->name, X! (int)(findeq (vp->name) - vp->name)); X v1_putc (NL); X } X } X*************** X*** 1617,1622 **** X--- 1726,1732 ---- X * History functions - display, initialise, enable, disable X */ X X+ #ifndef NO_HISTORY X static int dohistory (t) X C_Op *t; X { X*************** X*** 1639,1651 **** X X return 0; X } X X /* X * Type fucntion: For each name, indicate how it would be interpreted X */ X X static char *type_ext[] = { X! "", ".exe", ".com", ".sh" X }; X X static int dotype (t) X--- 1749,1762 ---- X X return 0; X } X+ #endif X X /* X * Type fucntion: For each name, indicate how it would be interpreted X */ X X static char *type_ext[] = { X! "", ".exe", ".com", ".sh", ".bat" X }; X X static int dotype (t) X*************** X*** 1659,1690 **** X int n = 1; /* Argument count */ X int i, fp; X bool found; /* Found flag */ X X! while ((cp = t->words[n++]) != (char *)NULL) X! { X! sp = any ('/', cp) ? null : path->value; X! found = FALSE; X X do X { X! sp = path_append (sp, cp, e.linep); X! ep = &e.linep[strlen (e.linep)]; X X /* Get start of file name */ X X! if ((xp1 = strrchr (e.linep, '/')) == (char *)NULL) X! xp1 = e.linep; X X else X ++xp1; X X! /* Look up all 4 types */ X X! for (i = 0; (i < 4) && !found; i++) X { X strcpy (ep, type_ext[i]); X X! if (access (e.linep, F_OK) == 0) X { X X /* If no extension or .sh extension, check for shell script */ X--- 1770,1826 ---- X int n = 1; /* Argument count */ X int i, fp; X bool found; /* Found flag */ X+ char *l_path; X+ Fun_Ops *fops; X X! /* Get some memory for the buffer */ X X+ if ((l_path = getcell (FFNAME_MAX + 4)) == (char *)NULL) X+ { X+ print_error ("type: %s\n", strerror (ENOMEM)); X+ return 1; X+ } X+ X+ /* Process each parameter */ X+ X+ while ((cp = t->words[n++]) != (char *)NULL) X+ { X+ X+ /* Check for a function */ X+ X+ if ((fops = Fun_Search (cp)) != (Fun_Ops *)NULL) X+ { X+ v1_puts (cp); X+ v1a_puts (" is a function"); X+ Print_ExTree (fops->tree); X+ continue; X+ } X+ X+ /* Scan the path for an executable */ X+ X+ sp = (any ('/', cp) || (*(cp + 1) == ':')) ? null : path->value; X+ found = FALSE; X+ X do X { X! sp = path_append (sp, cp, l_path); X! ep = &l_path[strlen (l_path)]; X X /* Get start of file name */ X X! if ((xp1 = strrchr (l_path, '/')) == (char *)NULL) X! xp1 = l_path; X X else X ++xp1; X X! /* Look up all 5 types */ X X! for (i = 0; (i < 5) && !found; i++) X { X strcpy (ep, type_ext[i]); X X! if (access (l_path, F_OK) == 0) X { X X /* If no extension or .sh extension, check for shell script */ X*************** X*** 1692,1708 **** X if (((xp = strchr (xp1, '.')) == (char *)NULL) || X (stricmp (xp, ".sh") == 0)) X { X! if ((fp = Check_Script (e.linep)) < 0) X continue; X X S_close (fp, TRUE); X } X X else if ((stricmp (xp, ".exe") != 0) && X! (stricmp (xp, ".com") != 0)) X continue; X X! print_error ("%s is %s\n", cp, e.linep); X found = TRUE; X } X } X--- 1828,1846 ---- X if (((xp = strchr (xp1, '.')) == (char *)NULL) || X (stricmp (xp, ".sh") == 0)) X { X! if ((fp = Check_Script (l_path, (char **)NULL, X! (int *)NULL)) < 0) X continue; X X S_close (fp, TRUE); X } X X else if ((stricmp (xp, ".exe") != 0) && X! (stricmp (xp, ".com") != 0) && X! (stricmp (xp, ".bat") != 0)) X continue; X X! print_error ("%s is %s\n", cp, l_path); X found = TRUE; X } X } X*************** X*** 1730,1736 **** X--- 1868,1876 ---- X "exit", doexit, X "export", doexport, X "getopt", dogetopt, X+ #ifndef NO_HISTORY X "history", dohistory, X+ #endif X "msdos", domsdos, X "pwd", dopwd, X "read", doread, X*************** X*** 1766,1772 **** X return bp->fn; X } X X! return NULL; X } X X /* Write to stdout functions - printf, fputs, fputc, and a special */ X--- 1906,1912 ---- X return bp->fn; X } X X! return (int (*)())NULL; X } X X /* Write to stdout functions - printf, fputs, fputc, and a special */ X*************** X*** 1811,1832 **** X } X X /* X- * Write n characters to STDOUT X- */ X- X- static void v1_putsn (s, n) X- char *s; X- int n; X- { X- write (STDOUT_FILENO, s, n); X- } X- X- /* X * Write 1 character to STDOUT X */ X X void v1_putc (c) X char c; X { X! write (STDOUT_FILENO, &c, 1); X } X--- 1951,1962 ---- X } X X /* X * Write 1 character to STDOUT X */ X X void v1_putc (c) X char c; X { X! if ((c != 0x07) || Ring_Bell ()) X! write (STDOUT_FILENO, &c, 1); X } XIndex: shell/sh9.c XPrereq: 1.2 X*** ../sh15/shell/sh9.c Mon Feb 19 15:49:13 1990 X--- shell/sh9.c Tue May 1 19:49:58 1990 X*************** X*** 12,20 **** X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * X! * $Header: sh9.c 1.2 90/02/19 15:42:39 MS_user Exp $ X * X * $Log: sh9.c $ X * Revision 1.2 90/02/19 15:42:39 MS_user X * Remove dependency on ANSI.SYS X * X--- 12,55 ---- X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * X! * $Header: sh9.c 1.11 90/03/27 20:22:07 MS_user Exp $ X * X * $Log: sh9.c $ X+ * Revision 1.11 90/03/27 20:22:07 MS_user X+ * Fix problem with paging down history file - the last item was incorrect X+ * X+ * Revision 1.10 90/03/26 04:10:53 MS_user X+ * Scan_History uses the Match length and not the string length for matching X+ * X+ * Revision 1.9 90/03/21 14:05:26 MS_user X+ * History search sometimes includes the optionals in the search string. X+ * X+ * Revision 1.8 90/03/14 13:23:48 MS_user X+ * Change names of configuration fields to reflect function X+ * X+ * Revision 1.7 90/03/13 18:36:07 MS_user X+ * Add initialisation file processing X+ * X+ * Revision 1.6 90/03/09 16:07:40 MS_user X+ * Add SH_ALT_KEYS processing X+ * Fix bottom line processing so that cursor doesn't disappear X+ * Fix EGA detection so we get the correct screen size X+ * X+ * Revision 1.5 90/03/06 16:50:57 MS_user X+ * Add disable history option X+ * X+ * Revision 1.4 90/03/06 15:14:40 MS_user X+ * Complete changes for file name completion X+ * Add find Max Lines function X+ * X+ * Revision 1.3 90/03/05 13:54:28 MS_user X+ * Fix get previous command request X+ * Add filename completion X+ * Add Max Columns from BIOS X+ * Add cursor position check function X+ * Add !! option X+ * Change erase to end of line processing to remove ANSI.SYS dependency X+ * X * Revision 1.2 90/02/19 15:42:39 MS_user X * Remove dependency on ANSI.SYS X * X*************** X*** 38,45 **** X--- 73,108 ---- X #include X #include X #include X+ #include X #include "sh.h" X X+ /* Keyboard functions */ X+ X+ #define KF_LENGTH (sizeof (KF_List) / sizeof (KF_List[0])) X+ #define KF_SCANBACKWARD 0x00 /* Scan backwards in history */ X+ #define KF_SCANFOREWARD 0x01 /* Scan forewards in history */ X+ #define KF_PREVIOUS 0x02 /* Previous command */ X+ #define KF_NEXT 0x03 /* Next command */ X+ #define KF_LEFT 0x04 /* Left one character */ X+ #define KF_RIGHT 0x05 /* Right one character */ X+ #define KF_WORDRIGHT 0x06 /* Right one word */ X+ #define KF_WORDLEFT 0x07 /* Left one word */ X+ #define KF_START 0x08 /* Move to start of line */ X+ #define KF_CLEAR 0x09 /* Clear input line */ X+ #define KF_FLUSH 0x0a /* Flush to end of line */ X+ #define KF_END 0x0b /* End of line */ X+ #define KF_INSERT 0x0c /* Insert mode switch */ X+ #define KF_DELETERIGHT 0x0d /* Delete right character */ X+ #define KF_DELETELEFT 0x0e /* Delete left character */ X+ #define KF_COMPLETE 0x0f /* Complete file name */ X+ #define KF_DIRECTORY 0x10 /* Complete directory function */ X+ #define KF_END_FKEYS 0x11 /* End of function keys */ X+ #define KF_RINGBELL 0x11 /* Ring bell */ X+ #define KF_HALFHEIGTH 0x12 /* Half height cursor */ X+ X+ /* Function Declarations */ X+ X+ #ifndef NO_HISTORY X static bool alpha_numeric (int); X static bool function (int); X static bool Process_History (int); X*************** X*** 50,68 **** X static bool UpDate_CLine (char *); X static bool Re_start (char *); X static void memrcpy (char *, char *, int); X- static void read_cursor_position (void); X static void set_cursor_position (int); X static void gen_cursor_position (void); X static void erase_to_end_of_line (void); X X static bool insert_mode = FALSE; X static char *c_buffer_pos; /* Position in command line */ X static char *end_buffer; /* End of command line */ X- static int s_cursor; /* Start cursor position */ X static int m_line = 0; /* Max write line number */ X static int c_history = -1; /* Current entry */ X static int l_history = 0; /* End of history array */ X static int M_length = -1; /* Match length */ X static char l_buffer[LINE_MAX + 1]; X static char *No_prehistory = "history: No previous commands"; X static char *No_MatchHistory = "history: No history match found"; X--- 113,140 ---- X static bool UpDate_CLine (char *); X static bool Re_start (char *); X static void memrcpy (char *, char *, int); X static void set_cursor_position (int); X static void gen_cursor_position (void); X static void erase_to_end_of_line (void); X+ static void set_cursor_shape (bool); X+ static bool Complete_file (char *, bool); X+ static void Init_Input (bool); X+ #endif X+ static void read_cursor_position (void); X+ static void Get_Screen_Params (void); X X+ static int s_cursor; /* Start cursor position */ X+ static int Max_Cols = 80; /* Max columns */ X+ static int Max_Lines = 25; /* Max Lines */ X+ #ifndef NO_HISTORY X static bool insert_mode = FALSE; X static char *c_buffer_pos; /* Position in command line */ X static char *end_buffer; /* End of command line */ X static int m_line = 0; /* Max write line number */ X static int c_history = -1; /* Current entry */ X static int l_history = 0; /* End of history array */ X static int M_length = -1; /* Match length */ X+ static int Max_Length = 0; /* Max line length */ X static char l_buffer[LINE_MAX + 1]; X static char *No_prehistory = "history: No previous commands"; X static char *No_MatchHistory = "history: No history match found"; X*************** X*** 70,77 **** X static char *History_2long = "history: History line too long"; X static char *H_TooLongI = "History file line too long - ignored (%d)\n"; X X! /* Arrary of history Items */ X X static struct cmd_history { X int number; X char *command; X--- 142,181 ---- X static char *History_2long = "history: History line too long"; X static char *H_TooLongI = "History file line too long - ignored (%d)\n"; X X! /* Function Key table */ X X+ static struct Key_Fun_List { X+ char *kf_name; X+ char akey; X+ char fkey; X+ char fcode; X+ } KF_List[] = { X+ { "ScanBackward", 0, 'I', KF_SCANBACKWARD }, X+ { "ScanForeward", 0, 'Q', KF_SCANFOREWARD }, X+ { "Previous", 0, 'H', KF_PREVIOUS }, X+ { "Next", 0, 'P', KF_NEXT }, X+ { "Left", 0, 'K', KF_LEFT }, X+ { "Right", 0, 'M', KF_RIGHT }, X+ { "WordRight", 0, 't', KF_WORDRIGHT }, X+ { "WordLeft", 0, 's', KF_WORDLEFT }, X+ { "Start", 0, 'G', KF_START }, X+ { "Clear", 0, 'v', KF_CLEAR }, X+ { "Flush", 0, 'u', KF_FLUSH }, X+ { "End", 0, 'O', KF_END }, X+ { "Insert", 0, 'R', KF_INSERT }, X+ { "DeleteRight", 0, 'S', KF_DELETERIGHT }, X+ { "DeleteLeft", 0x08, 0, KF_DELETELEFT }, X+ { "Complete", 0, 'w', KF_COMPLETE }, X+ { "Directory", 0, 0x0f, KF_DIRECTORY }, X+ X+ /* End of function keys - flags */ X+ X+ { "Bell", 1, 0, KF_RINGBELL }, X+ { "HalfHeight", 0, 0, KF_HALFHEIGTH } X+ }; X+ X+ /* Arrary of history Items */ X+ X static struct cmd_history { X int number; X char *command; X*************** X*** 119,149 **** X X static void Process_Stdin () X { X int i; X- char *control = "^x"; X X /* Set to last history item */ X X! c_history = l_history - 1; X X /* Process the input */ X X while (TRUE) X { X! c_buffer_pos = l_buffer; /* Initialise */ X! end_buffer = l_buffer; X! insert_mode = FALSE; X! M_length = -1; X! read_cursor_position (); X X! while (((i = getch ()) != 0x1a) && (i != NL) && (i != '\r')) X { X X! /* Re-position the line? */ X X! if (((i) ? alpha_numeric (i) : function (getch ()))) X! Redisplay_Line (); X X /* Reposition the cursor */ X X gen_cursor_position (); X--- 223,270 ---- X X static void Process_Stdin () X { X+ char a_key, f_key; X int i; X X /* Set to last history item */ X X! c_history = l_history; X X /* Process the input */ X X while (TRUE) X { X! Init_Input (FALSE); /* Initialise */ X X! while (((a_key = (char)getch ()) != 0x1a) && (a_key != NL) && X! (a_key != '\r')) X { X X! /* If function key, get the fkey value */ X! X! if (!a_key) X! f_key = (char)getch (); X X! /* Look up the keystroke to see if it is one of our functions */ X X+ for (i = 0; (i < KF_END_FKEYS); ++i) X+ { X+ if (KF_List[i].akey != a_key) X+ continue; X+ X+ if ((a_key != 0) || (KF_List[i].fkey == f_key)) X+ break; X+ } X+ X+ /* If this is a function key and is not ours, ignore it */ X+ X+ if ((i == KF_END_FKEYS) && (!a_key)) X+ continue; X+ X+ if (((i == KF_END_FKEYS) ? alpha_numeric (a_key) X+ : function (KF_List[i].fcode))) X+ Redisplay_Line (); X+ X /* Reposition the cursor */ X X gen_cursor_position (); X*************** X*** 153,158 **** X--- 274,280 ---- X X *end_buffer = 0; X v1_putc (NL); X+ s_cursor = -1; X X /* Line input - check for history */ X X*************** X*** 164,176 **** X X else if (*l_buffer != '!') X break; X- X- /* Output prompt and try again */ X- X- Re_start ((char *)NULL); X } X X! *end_buffer = (char)((i == '\r') ? NL : i); X } X X /* Handler Alpha_numeric characters */ X--- 286,295 ---- X X else if (*l_buffer != '!') X break; X } X X! set_cursor_shape (FALSE); X! *end_buffer = (char)((a_key == '\r') ? NL : a_key); X } X X /* Handler Alpha_numeric characters */ X*************** X*** 180,206 **** X { X bool redisplay = FALSE; X X- /* Backspace processing */ X- X- if (c == 0x08) X- { X- if (c_buffer_pos == l_buffer) X- { X- v1_putc (0x07); /* Ring bell */ X- return FALSE; X- } X- X- /* Decrement current position */ X- X- if ((c_buffer_pos--) == end_buffer) X- --end_buffer; X- X- else X- *c_buffer_pos = ' '; X- X- return TRUE; X- } X- X /* Normal character processing */ X X if ((c_buffer_pos - l_buffer) == LINE_MAX) X--- 299,304 ---- X*************** X*** 254,278 **** X static bool function (fn) X int fn; X { X switch (fn) X { X! case 'I': /* Scan back command line */ X! case 'Q': /* Scan up command line */ X! if (M_length == -1) X! break; X X! Page_History ((fn == 'I') ? -1 : 1); X return TRUE; X X! case 'H': /* Previous command line */ X Process_History (-1); X return TRUE; X X! case 'P': /* Next command line */ X Process_History (1); X return TRUE; X X! case 'K': /* Cursor left */ X if (c_buffer_pos != l_buffer) X --c_buffer_pos; X X--- 352,381 ---- X static bool function (fn) X int fn; X { X+ bool fn_search = FALSE; X+ X switch (fn) X { X! case KF_SCANBACKWARD: /* Scan backwards in history */ X! case KF_SCANFOREWARD: /* Scan forewards in history */ X! *end_buffer = 0; X X! if (M_length == -1) X! M_length = strlen (l_buffer); X! X! Page_History ((fn == KF_SCANBACKWARD) ? -1 : 1); X return TRUE; X X! case KF_PREVIOUS: /* Previous command */ X! *end_buffer = 0; X Process_History (-1); X return TRUE; X X! case KF_NEXT: /* Next command line */ X Process_History (1); X return TRUE; X X! case KF_LEFT: /* Cursor left */ X if (c_buffer_pos != l_buffer) X --c_buffer_pos; X X*************** X*** 281,287 **** X X return FALSE; X X! case 'M': /* Cursor right */ X if (c_buffer_pos != end_buffer) X ++c_buffer_pos; X X--- 384,390 ---- X X return FALSE; X X! case KF_RIGHT: /* Cursor right */ X if (c_buffer_pos != end_buffer) X ++c_buffer_pos; X X*************** X*** 290,296 **** X X return FALSE; X X! case 's': /* Cursor left a word */ X if (c_buffer_pos != l_buffer) X { X --c_buffer_pos; /* Reposition on previous char */ X--- 393,399 ---- X X return FALSE; X X! case KF_WORDLEFT: /* Cursor left a word */ X if (c_buffer_pos != l_buffer) X { X --c_buffer_pos; /* Reposition on previous char */ X*************** X*** 310,316 **** X X return FALSE; X X! case 't': /* Cursor right a word */ X if (c_buffer_pos != end_buffer) X { X X--- 413,419 ---- X X return FALSE; X X! case KF_WORDRIGHT: /* Cursor right a word */ X if (c_buffer_pos != end_buffer) X { X X*************** X*** 330,345 **** X X return FALSE; X X! case 'G': /* Cursor home */ X c_buffer_pos = l_buffer; X return FALSE; X X! case 'u': /* Flush to end */ X memset (c_buffer_pos, ' ', end_buffer - c_buffer_pos); X end_buffer = c_buffer_pos; X return TRUE; X X! case 'O': /* Cursor end of command */ X if (*l_buffer == '!') X { X *end_buffer = 0; X--- 433,451 ---- X X return FALSE; X X! case KF_START: /* Cursor home */ X c_buffer_pos = l_buffer; X return FALSE; X X! case KF_CLEAR: /* Erase buffer */ X! c_buffer_pos = l_buffer; X! X! case KF_FLUSH: /* Flush to end */ X memset (c_buffer_pos, ' ', end_buffer - c_buffer_pos); X end_buffer = c_buffer_pos; X return TRUE; X X! case KF_END: /* Cursor end of command */ X if (*l_buffer == '!') X { X *end_buffer = 0; X*************** X*** 350,364 **** X c_buffer_pos = end_buffer; X return FALSE; X X! case 'R': /* Switch insert mode */ X insert_mode = (insert_mode) ? FALSE : TRUE; X return FALSE; X X! case 'S': /* Delete character */ X! if (c_buffer_pos != end_buffer) X! memcpy (c_buffer_pos, c_buffer_pos + 1, X! end_buffer - c_buffer_pos); X X if (end_buffer == l_buffer) X { X v1_putc (0x07); X--- 456,472 ---- X c_buffer_pos = end_buffer; X return FALSE; X X! case KF_INSERT: /* Switch insert mode */ X insert_mode = (insert_mode) ? FALSE : TRUE; X+ set_cursor_shape (insert_mode); X return FALSE; X X! case KF_DELETERIGHT: /* Delete right character */ X! if (c_buffer_pos == end_buffer) X! return FALSE; X X+ memcpy (c_buffer_pos, c_buffer_pos + 1, end_buffer - c_buffer_pos); X+ X if (end_buffer == l_buffer) X { X v1_putc (0x07); X*************** X*** 369,380 **** X --c_buffer_pos; X X return TRUE; X- } X X! v1_putc (0x07); X! return FALSE; X! } X X /* Read Cursor position */ X X static void read_cursor_position () X--- 477,539 ---- X --c_buffer_pos; X X return TRUE; X X! case KF_DIRECTORY: /* File name directory */ X! fn_search = TRUE; X X+ case KF_COMPLETE: /* File name completion */ X+ { X+ char *fn_start = c_buffer_pos; X+ X+ *end_buffer = 0; X+ X+ if (isspace (*fn_start)) X+ --fn_start; X+ X+ if (isspace (*fn_start) || (fn_start < l_buffer)) X+ break; X+ X+ return Complete_file (fn_start, fn_search); X+ } X+ X+ case KF_DELETELEFT: /* Delete left character */ X+ if (c_buffer_pos == l_buffer) X+ { X+ v1_putc (0x07); /* Ring bell */ X+ return FALSE; X+ } X+ X+ /* Decrement current position */ X+ X+ --c_buffer_pos; X+ memcpy (c_buffer_pos, c_buffer_pos + 1, end_buffer - c_buffer_pos); X+ --end_buffer; X+ return TRUE; X+ } X+ } X+ X+ /* Set cursor shape */ X+ X+ static void set_cursor_shape (mode) X+ bool mode; X+ { X+ union REGS r; X+ X+ /* Get the current cursor position to get the cursor lines */ X+ X+ r.h.ah = 0x03; X+ int86 (0x10, &r, &r); X+ X+ /* Reset the type */ X+ X+ r.h.ah = 0x01; X+ r.h.ch = (unsigned char)(!mode ? r.h.cl - 1 X+ : (KF_List[KF_HALFHEIGTH].akey X+ ? (r.h.cl / 2) + 1 : 1)); X+ int86 (0x10, &r, &r); X+ } X+ #endif X+ X /* Read Cursor position */ X X static void read_cursor_position () X*************** X*** 384,416 **** X r.h.ah = 0x03; /* Read cursor position */ X r.h.bh = 0; /* Page zero */ X int86 (0x10, &r, &r); X! s_cursor = (r.h.dh * 80) + r.h.dl; X! m_line = r.h.dh; X } X X /* Re-position the cursor */ X X static void set_cursor_position (new) X int new; X { X union REGS r; X X r.h.ah = 0x02; /* Set new position */ X r.h.bh = 0; /* Page zero */ X! r.h.dh = (unsigned char)(new / 80); X! r.h.dl = (unsigned char)(new % 80); X X /* Are we at the bottom of the page? */ X X! if (r.h.dh == 25) X { X! r.h.dh = 24; X! s_cursor -= 80; X } X X- if (m_line < r.h.dh) X- m_line = r.h.dh; X- X int86 (0x10, &r, &r); X } X X--- 543,574 ---- X r.h.ah = 0x03; /* Read cursor position */ X r.h.bh = 0; /* Page zero */ X int86 (0x10, &r, &r); X! s_cursor = (r.h.dh * Max_Cols) + r.h.dl; X } X X /* Re-position the cursor */ X X+ #ifndef NO_HISTORY X static void set_cursor_position (new) X int new; X { X+ int diff; X union REGS r; X X r.h.ah = 0x02; /* Set new position */ X r.h.bh = 0; /* Page zero */ X! r.h.dh = (unsigned char)(new / Max_Cols); X! r.h.dl = (unsigned char)(new % Max_Cols); X X /* Are we at the bottom of the page? */ X X! if (r.h.dh >= (unsigned char)Max_Lines) X { X! diff = r.h.dh + 1 - Max_Lines; X! r.h.dh = (unsigned char)(Max_Lines - 1); X! s_cursor -= Max_Cols * diff; X } X X int86 (0x10, &r, &r); X } X X*************** X*** 418,433 **** X X static void erase_to_end_of_line () X { X! union REGS r; X X! r.h.ah = 0x03; X r.h.bh = 0; X int86 (0x10, &r, &r); X X! if ((r.x.cx = 80 - r.h.dl + (m_line - r.h.dh) * 80) > 0) X { X! r.x.ax = 0x0920; X! r.x.bx = 0x0007; X int86 (0x10, &r, &r); X } X } X--- 576,604 ---- X X static void erase_to_end_of_line () X { X! union REGS r; X! unsigned char backg; X X! /* Get the background attribute of the cursor */ X! X! r.h.ah = 0x08; X r.h.bh = 0; X int86 (0x10, &r, &r); X+ backg = r.h.ah & 0x07; X X! r.h.ah = 0x03; X! r.h.bh = 0; X! int86 (0x10, &r, &r); X! X! /* Check that we use the correct m_line */ X! X! if (m_line < r.h.dh) X! m_line = r.h.dh; X! X! if ((r.x.cx = Max_Cols - r.h.dl + (m_line - r.h.dh) * Max_Cols) > 0) X { X! r.x.ax = 0x0a20; X! r.x.bx = backg; X int86 (0x10, &r, &r); X } X } X*************** X*** 498,504 **** X--- 669,679 ---- X ++cp; X } X X+ if ((m_line = ((s_cursor + Max_Length) / Max_Cols) + 1) >= Max_Lines) X+ m_line = Max_Lines - 1; X+ X erase_to_end_of_line (); /* clear to end of line */ X+ Max_Length = end_buffer - l_buffer; X } X X /* Process history command X*************** X*** 523,529 **** X case -1: /* Move up one line */ X if (c_history < 0) X { X! ++c_history; X return Re_start (No_prehistory); X } X X--- 698,704 ---- X case -1: /* Move up one line */ X if (c_history < 0) X { X! c_history = -1; X return Re_start (No_prehistory); X } X X*************** X*** 532,538 **** X case 1: /* Move to next history line */ X if (c_history >= l_history) X { X! --c_history; X return Re_start (No_posthistory); X } X X--- 707,713 ---- X case 1: /* Move to next history line */ X if (c_history >= l_history) X { X! c_history = l_history; X return Re_start (No_posthistory); X } X X*************** X*** 545,569 **** X /* Find the end of the first part */ X X while (!isspace (*optionals) && *optionals) X! ++optionals; X X! /* Terminate the history command */ X X! if (*optionals) X! *(optionals++) = 0; X X! /* Find the end of the space separator part which gives the start of the X! * optionals X! */ X X! while (isspace (*optionals)) X! ++optionals; X X X! /* Copy selected item into line buffer */ X X case 2: X! M_length = strlen (l_buffer) - 1; X if (!Scan_History ()) X return FALSE; X X--- 720,759 ---- X /* Find the end of the first part */ X X while (!isspace (*optionals) && *optionals) X! { X! if (*optionals == '!') X! { X X! /* Terminate at !! */ X X! if (*(optionals + 1) == '!') X! { X! optionals += 2; X! break; X! } X X! /* Terminate at a numeric value */ X X! else if (isdigit (*(optionals + 1)) || X! (*(optionals + 1) == '-')) X! { X! optionals += 2; X! while (isdigit (*optionals)) X! ++optionals; X X+ break; X+ } X+ } X X! ++optionals; X! } X X+ /* Copy selected item into line buffer */ X+ X case 2: X! M_length = (optionals == null) ? strlen (l_buffer) - 1 X! : optionals - l_buffer - 1; X! X if (!Scan_History ()) X return FALSE; X X*************** X*** 588,604 **** X return Re_start (History_2long); X X if (end_buffer > optionals) X! memrcpy (end_buffer + 1 + opt_len, optionals + opt_len, opt_len + 1); X X else X! strcpy (end_buffer + 1, optionals); X X! strcpy (l_buffer, cmd_history[c_history].command); X! X! if (opt_len) X! *end_buffer = ' '; X! X end_buffer = &l_buffer[strlen (l_buffer)]; X return TRUE; X } X X--- 778,791 ---- X return Re_start (History_2long); X X if (end_buffer > optionals) X! memrcpy (end_buffer + opt_len, optionals + opt_len, opt_len + 1); X X else X! strcpy (end_buffer, optionals); X X! strncpy (l_buffer, cmd_history[c_history].command, (end_buffer - l_buffer)); X end_buffer = &l_buffer[strlen (l_buffer)]; X+ c_buffer_pos = end_buffer; X return TRUE; X } X X*************** X*** 606,625 **** X X static bool Scan_History () X { X! char *cp = &l_buffer[1]; X! int c_len = strlen (cp); X char *ep; SHAR_EOF echo "End of part 4" echo "File Patch1.6 is continued in part 5" echo "5" > s2_seq_.tmp exit 0