=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/cmdbuf.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.2 diff -c -r1.1.1.1 -r1.1.1.2 *** src/usr.bin/less/cmdbuf.c 1996/09/21 05:39:41 1.1.1.1 --- src/usr.bin/less/cmdbuf.c 2003/04/13 18:21:21 1.1.1.2 *************** *** 1,27 **** /* ! * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman ! * All rights reserved. * ! * Redistribution and use in source and binary forms, with or without ! * modification, are permitted provided that the following conditions ! * are met: ! * 1. Redistributions of source code must retain the above copyright ! * notice, this list of conditions and the following disclaimer. ! * 2. Redistributions in binary form must reproduce the above copyright ! * notice in the documentation and/or other materials provided with ! * the distribution. * ! * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY ! * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ! * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE ! * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ! * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT ! * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ! * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ! * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE ! * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN ! * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ --- 1,11 ---- /* ! * Copyright (C) 1984-2002 Mark Nudelman * ! * You may distribute under the terms of either the GNU General Public ! * License or the Less License, as specified in the README file. * ! * For more information about less, or for information on how to ! * contact the author, see the README file. */ *************** *** 35,44 **** extern int sc_width; ! static char cmdbuf[120]; /* Buffer for holding a multi-char command */ ! static int cmd_col; /* Current column of the multi-char command */ static char *cp; /* Pointer into cmdbuf */ ! static int literal; #if TAB_COMPLETE_FILENAME static int cmd_complete(); --- 19,30 ---- extern int sc_width; ! static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */ ! static int cmd_col; /* Current column of the cursor */ ! static int prompt_col; /* Column of cursor just after prompt */ static char *cp; /* Pointer into cmdbuf */ ! static int cmd_offset; /* Index into cmdbuf of first displayed char */ ! static int literal; /* Next input char should not be interpreted */ #if TAB_COMPLETE_FILENAME static int cmd_complete(); *************** *** 53,58 **** --- 39,52 ---- static struct textlist tk_tlist; #endif + static int cmd_left(); + static int cmd_right(); + + #if SPACES_IN_FILENAMES + public char openquote = '"'; + public char closequote = '"'; + #endif + #if CMD_HISTORY /* * A mlist structure represents a command history. *************** *** 70,91 **** */ struct mlist mlist_search = { &mlist_search, &mlist_search, &mlist_search, NULL }; ! public void *ml_search = (void *) &mlist_search; struct mlist mlist_examine = { &mlist_examine, &mlist_examine, &mlist_examine, NULL }; ! public void *ml_examine = (void *) &mlist_examine; #if SHELL_ESCAPE || PIPEC struct mlist mlist_shell = { &mlist_shell, &mlist_shell, &mlist_shell, NULL }; ! public void *ml_shell = (void *) &mlist_shell; ! #endif /* SHELL_ESCAPE || PIPEC */ /* * History for the current command. */ static struct mlist *curr_mlist = NULL; - #endif /* CMD_HISTORY */ /* * Reset command buffer (to empty). --- 64,98 ---- */ struct mlist mlist_search = { &mlist_search, &mlist_search, &mlist_search, NULL }; ! public void * constant ml_search = (void *) &mlist_search; ! struct mlist mlist_examine = { &mlist_examine, &mlist_examine, &mlist_examine, NULL }; ! public void * constant ml_examine = (void *) &mlist_examine; ! #if SHELL_ESCAPE || PIPEC struct mlist mlist_shell = { &mlist_shell, &mlist_shell, &mlist_shell, NULL }; ! public void * constant ml_shell = (void *) &mlist_shell; ! #endif + #else /* CMD_HISTORY */ + + /* If CMD_HISTORY is off, these are just flags. */ + public void * constant ml_search = (void *)1; + public void * constant ml_examine = (void *)2; + #if SHELL_ESCAPE || PIPEC + public void * constant ml_shell = (void *)3; + #endif + + #endif /* CMD_HISTORY */ + /* * History for the current command. */ static struct mlist *curr_mlist = NULL; + static int curr_cmdflags; /* * Reset command buffer (to empty). *************** *** 96,105 **** --- 103,135 ---- cp = cmdbuf; *cp = '\0'; cmd_col = 0; + cmd_offset = 0; literal = 0; } /* + * Clear command line on display. + */ + public void + clear_cmd() + { + clear_bot(); + cmd_col = prompt_col = 0; + } + + /* + * Display a string, usually as a prompt for input into the command buffer. + */ + public void + cmd_putstr(s) + char *s; + { + putstr(s); + cmd_col += strlen(s); + prompt_col += strlen(s); + } + + /* * How many characters are in the command buffer? */ public int *************** *** 109,114 **** --- 139,326 ---- } /* + * Repaint the line from cp onwards. + * Then position the cursor just after the char old_cp (a pointer into cmdbuf). + */ + static void + cmd_repaint(old_cp) + char *old_cp; + { + char *p; + + /* + * Repaint the line from the current position. + */ + clear_eol(); + for ( ; *cp != '\0'; cp++) + { + p = prchar(*cp); + if (cmd_col + (int)strlen(p) >= sc_width) + break; + putstr(p); + cmd_col += strlen(p); + } + + /* + * Back up the cursor to the correct position. + */ + while (cp > old_cp) + cmd_left(); + } + + /* + * Put the cursor at "home" (just after the prompt), + * and set cp to the corresponding char in cmdbuf. + */ + static void + cmd_home() + { + while (cmd_col > prompt_col) + { + putbs(); + cmd_col--; + } + + cp = &cmdbuf[cmd_offset]; + } + + /* + * Shift the cmdbuf display left a half-screen. + */ + static void + cmd_lshift() + { + char *s; + char *save_cp; + int cols; + + /* + * Start at the first displayed char, count how far to the + * right we'd have to move to reach the center of the screen. + */ + s = cmdbuf + cmd_offset; + cols = 0; + while (cols < (sc_width - prompt_col) / 2 && *s != '\0') + cols += strlen(prchar(*s++)); + + cmd_offset = s - cmdbuf; + save_cp = cp; + cmd_home(); + cmd_repaint(save_cp); + } + + /* + * Shift the cmdbuf display right a half-screen. + */ + static void + cmd_rshift() + { + char *s; + char *p; + char *save_cp; + int cols; + + /* + * Start at the first displayed char, count how far to the + * left we'd have to move to traverse a half-screen width + * of displayed characters. + */ + s = cmdbuf + cmd_offset; + cols = 0; + while (cols < (sc_width - prompt_col) / 2 && s > cmdbuf) + { + p = prchar(*--s); + cols += strlen(p); + } + + cmd_offset = s - cmdbuf; + save_cp = cp; + cmd_home(); + cmd_repaint(save_cp); + } + + /* + * Move cursor right one character. + */ + static int + cmd_right() + { + char *p; + + if (*cp == '\0') + { + /* + * Already at the end of the line. + */ + return (CC_OK); + } + p = prchar(*cp); + if (cmd_col + (int)strlen(p) >= sc_width) + cmd_lshift(); + else if (cmd_col + (int)strlen(p) == sc_width - 1 && cp[1] != '\0') + cmd_lshift(); + cp++; + putstr(p); + cmd_col += strlen(p); + return (CC_OK); + } + + /* + * Move cursor left one character. + */ + static int + cmd_left() + { + char *p; + + if (cp <= cmdbuf) + { + /* Already at the beginning of the line */ + return (CC_OK); + } + p = prchar(cp[-1]); + if (cmd_col < prompt_col + (int)strlen(p)) + cmd_rshift(); + cp--; + cmd_col -= strlen(p); + while (*p++ != '\0') + putbs(); + return (CC_OK); + } + + /* + * Insert a char into the command buffer, at the current position. + */ + static int + cmd_ichar(c) + int c; + { + char *s; + + if (strlen(cmdbuf) >= sizeof(cmdbuf)-2) + { + /* + * No room in the command buffer for another char. + */ + bell(); + return (CC_ERROR); + } + + /* + * Insert the character into the buffer. + */ + for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--) + s[1] = s[0]; + *cp = c; + /* + * Reprint the tail of the line from the inserted char. + */ + cmd_repaint(cp); + cmd_right(); + return (CC_OK); + } + + /* * Backspace in the command buffer. * Delete the char to the left of the cursor. */ *************** *** 116,123 **** cmd_erase() { register char *s; - char *p; - int col; if (cp == cmdbuf) { --- 328,333 ---- *************** *** 128,184 **** return (CC_QUIT); } /* ! * Back up the pointer. */ ! --cp; /* ! * Remember the current cursor column and ! * set it back the width of the char being erased. */ - col = cmd_col; - p = prchar(*cp); - cmd_col -= strlen(p); - /* - * Shift left the buffer after the erased char. - */ for (s = cp; *s != '\0'; s++) s[0] = s[1]; /* ! * Back up the cursor to the position of the erased char, ! * clear the tail of the line, ! * and reprint the line after the erased char. */ ! while (col > cmd_col) ! { ! putbs(); ! col--; ! } ! clear_eol(); ! for (s = cp; *s != '\0'; s++) ! { ! p = prchar(*s); ! putstr(p); ! col += strlen(p); ! } ! /* ! * Back up the cursor again. ! */ ! while (col > cmd_col) ! { ! putbs(); ! col--; ! } /* - * This is rather weird. * We say that erasing the entire command string causes us ! * to abort the current command, BUT ONLY IF there is no history ! * for this type of command. This causes commands like search (/) ! * and edit (:e) to stay active even if we erase the entire string, ! * but commands like and - go away when we erase the string. ! * (See same thing in cmd_kill.) */ ! if (curr_mlist == NULL && cp == cmdbuf && *cp == '\0') return (CC_QUIT); return (CC_OK); } --- 338,361 ---- return (CC_QUIT); } /* ! * Move cursor left (to the char being erased). */ ! cmd_left(); /* ! * Remove the char from the buffer (shift the buffer left). */ for (s = cp; *s != '\0'; s++) s[0] = s[1]; /* ! * Repaint the buffer after the erased char. */ ! cmd_repaint(cp); /* * We say that erasing the entire command string causes us ! * to abort the current command, if CF_QUIT_ON_ERASE is set. */ ! if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0') return (CC_QUIT); return (CC_OK); } *************** *** 189,196 **** static int cmd_delete() { - char *p; - if (*cp == '\0') { /* --- 366,371 ---- *************** *** 201,210 **** /* * Move right, then use cmd_erase. */ ! p = prchar(*cp); ! cp++; ! putstr(p); ! cmd_col += strlen(p); cmd_erase(); return (CC_OK); } --- 376,382 ---- /* * Move right, then use cmd_erase. */ ! cmd_right(); cmd_erase(); return (CC_OK); } *************** *** 262,289 **** } /* - * Move cursor to start of command buffer. - */ - static int - cmd_home() - { - char *p; - - /* - * Back up until we hit start of buffer. - */ - while (cp > cmdbuf) - { - cp--; - p = prchar(*cp); - cmd_col -= strlen(p); - while (*p++ != '\0') - putbs(); - } - return (CC_OK); - } - - /* * Delete all chars in the command buffer. */ static int --- 434,439 ---- *************** *** 296,367 **** */ return (CC_QUIT); } ! (void) cmd_home(); *cp = '\0'; ! clear_eol(); /* ! * Same weirdness as in cmd_erase. ! * If the current command has no history, abort the current command. */ ! if (curr_mlist == NULL) return (CC_QUIT); return (CC_OK); } /* - * Move cursor right one character. - */ - static int - cmd_right() - { - char *p; - - if (*cp == '\0') - { - /* - * Already at the end of the line. - */ - return (CC_OK); - } - p = prchar(*cp); - cp++; - putstr(p); - cmd_col += strlen(p); - return (CC_OK); - } - - /* - * Move cursor left one character. - */ - static int - cmd_left() - { - char *p; - - if (cp <= cmdbuf) - { - /* Already at the beginning of the line */ - return (CC_OK); - } - cp--; - p = prchar(*cp); - cmd_col -= strlen(p); - while (*p++ != '\0') - putbs(); - return (CC_OK); - } - - #if CMD_HISTORY - /* * Select an mlist structure to be the current command history. */ public void ! set_mlist(mlist) void *mlist; { curr_mlist = (struct mlist *) mlist; } /* * Move up or down in the currently selected command history list. */ --- 446,478 ---- */ return (CC_QUIT); } ! cmd_offset = 0; ! cmd_home(); *cp = '\0'; ! cmd_repaint(cp); ! /* ! * We say that erasing the entire command string causes us ! * to abort the current command, if CF_QUIT_ON_ERASE is set. */ ! if (curr_cmdflags & CF_QUIT_ON_ERASE) return (CC_QUIT); return (CC_OK); } /* * Select an mlist structure to be the current command history. */ public void ! set_mlist(mlist, cmdflags) void *mlist; + int cmdflags; { curr_mlist = (struct mlist *) mlist; + curr_cmdflags = cmdflags; } + #if CMD_HISTORY /* * Move up or down in the currently selected command history list. */ *************** *** 369,375 **** cmd_updown(action) int action; { - char *p; char *s; if (curr_mlist == NULL) --- 480,485 ---- *************** *** 395,459 **** s = curr_mlist->curr_mp->string; if (s == NULL) s = ""; ! for (cp = cmdbuf; *s != '\0'; s++, cp++) { *cp = *s; ! p = prchar(*cp); ! cmd_col += strlen(p); ! putstr(p); } *cp = '\0'; return (CC_OK); } /* ! * Accept the command in the command buffer. ! * Add it to the currently selected history list. */ public void ! cmd_accept() { struct mlist *ml; /* - * Nothing to do if there is no currently selected history list. - */ - if (curr_mlist == NULL) - return; - /* * Don't save a trivial command. */ ! if (strlen(cmdbuf) == 0) return; /* ! * Don't save if a duplicate of a command which is already in the history. * But select the one already in the history to be current. */ ! for (ml = curr_mlist->next; ml != curr_mlist; ml = ml->next) { ! if (strcmp(ml->string, cmdbuf) == 0) break; } ! if (ml == curr_mlist) { /* * Did not find command in history. * Save the command and put it at the end of the history list. */ ml = (struct mlist *) ecalloc(1, sizeof(struct mlist)); ! ml->string = save(cmdbuf); ! ml->next = curr_mlist; ! ml->prev = curr_mlist->prev; ! curr_mlist->prev->next = ml; ! curr_mlist->prev = ml; } /* * Point to the cmd just after the just-accepted command. * Thus, an UPARROW will always retrieve the previous command. */ ! curr_mlist->curr_mp = ml->next; } #endif /* * Try to perform a line-edit function on the command buffer, --- 505,583 ---- s = curr_mlist->curr_mp->string; if (s == NULL) s = ""; ! for (cp = cmdbuf; *s != '\0'; s++) { *cp = *s; ! cmd_right(); } *cp = '\0'; return (CC_OK); } + #endif /* ! * Add a string to a history list. */ public void ! cmd_addhist(mlist, cmd) ! struct mlist *mlist; ! char *cmd; { + #if CMD_HISTORY struct mlist *ml; /* * Don't save a trivial command. */ ! if (strlen(cmd) == 0) return; /* ! * Don't save if a duplicate of a command which is already ! * in the history. * But select the one already in the history to be current. */ ! for (ml = mlist->next; ml != mlist; ml = ml->next) { ! if (strcmp(ml->string, cmd) == 0) break; } ! if (ml == mlist) { /* * Did not find command in history. * Save the command and put it at the end of the history list. */ ml = (struct mlist *) ecalloc(1, sizeof(struct mlist)); ! ml->string = save(cmd); ! ml->next = mlist; ! ml->prev = mlist->prev; ! mlist->prev->next = ml; ! mlist->prev = ml; } /* * Point to the cmd just after the just-accepted command. * Thus, an UPARROW will always retrieve the previous command. */ ! mlist->curr_mp = ml->next; ! #endif } + + /* + * Accept the command in the command buffer. + * Add it to the currently selected history list. + */ + public void + cmd_accept() + { + #if CMD_HISTORY + /* + * Nothing to do if there is no currently selected history list. + */ + if (curr_mlist == NULL) + return; + cmd_addhist(curr_mlist, cmdbuf); #endif + } /* * Try to perform a line-edit function on the command buffer, *************** *** 480,495 **** * See if the char is indeed a line-editing command. */ flags = 0; if (curr_mlist == NULL) /* * No current history; don't accept history manipulation cmds. */ flags |= EC_NOHISTORY; ! if (curr_mlist == &mlist_search) /* * In a search command; don't accept file-completion cmds. */ flags |= EC_NOCOMPLETE; action = editchar(c, flags); --- 604,623 ---- * See if the char is indeed a line-editing command. */ flags = 0; + #if CMD_HISTORY if (curr_mlist == NULL) /* * No current history; don't accept history manipulation cmds. */ flags |= EC_NOHISTORY; ! #endif ! #if TAB_COMPLETE_FILENAME ! if (curr_mlist == ml_search) /* * In a search command; don't accept file-completion cmds. */ flags |= EC_NOCOMPLETE; + #endif action = editchar(c, flags); *************** *** 517,523 **** return (CC_OK); case EC_HOME: not_in_completion(); ! return (cmd_home()); case EC_END: not_in_completion(); while (*cp != '\0') --- 645,654 ---- return (CC_OK); case EC_HOME: not_in_completion(); ! cmd_offset = 0; ! cmd_home(); ! cmd_repaint(cp); ! return (CC_OK); case EC_END: not_in_completion(); while (*cp != '\0') *************** *** 556,645 **** case EC_EXPAND: return (cmd_complete(action)); #endif default: not_in_completion(); return (CC_PASS); } } - /* - * Insert a char into the command buffer, at the current position. - */ - static int - cmd_ichar(c) - int c; - { - int col; - char *p; - char *s; - - if (strlen(cmdbuf) >= sizeof(cmdbuf)-2) - { - /* - * No room in the command buffer for another char. - */ - bell(); - return (CC_ERROR); - } - - /* - * Remember the current cursor column and - * move it forward the width of the char being inserted. - */ - col = cmd_col; - p = prchar(c); - cmd_col += strlen(p); - if (cmd_col >= sc_width-1) - { - cmd_col -= strlen(p); - bell(); - return (CC_ERROR); - } - /* - * Insert the character in the string. - * First, make room for the new char. - */ - for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--) - s[1] = s[0]; - *cp++ = c; - /* - * Reprint the tail of the line after the inserted char. - */ - clear_eol(); - for (s = cp-1; *s != '\0'; s++) - { - p = prchar(*s); - col += strlen(p); - if (col >= sc_width-1) - { - /* - * Oops. There is no room on the screen - * for the new char. Back up the cursor to - * just after the inserted char and erase it. - */ - col -= strlen(p); - while (col > cmd_col) - { - putbs(); - col--; - } - (void) cmd_erase(); - bell(); - return (CC_ERROR); - } - putstr(p); - } - /* - * Back up the cursor to just after the inserted char. - */ - while (col > cmd_col) - { - putbs(); - col--; - } - return (CC_OK); - } - #if TAB_COMPLETE_FILENAME /* * Insert a string into the command buffer, at the current position. --- 687,700 ---- case EC_EXPAND: return (cmd_complete(action)); #endif + case EC_NOACTION: + return (CC_OK); default: not_in_completion(); return (CC_PASS); } } #if TAB_COMPLETE_FILENAME /* * Insert a string into the command buffer, at the current position. *************** *** 673,678 **** --- 728,740 ---- delimit_word() { char *word; + #if SPACES_IN_FILENAMES + char *p; + int delim_quoted = 0; + int meta_quoted = 0; + char *esc = get_meta_escape(); + int esclen = strlen(esc); + #endif /* * Move cursor to end of word. *************** *** 692,697 **** --- 754,760 ---- * We're already at the end of the word. */ ; + #if 0 } else { /* *************** *** 699,713 **** * Huh? There's no word here. */ return (NULL); } /* ! * Search backwards for beginning of the word. */ if (cp == cmdbuf) return (NULL); ! for (word = cp-1; word > cmdbuf; word--) ! if (word[-1] == ' ') break; return (word); } --- 762,808 ---- * Huh? There's no word here. */ return (NULL); + #endif } /* ! * Find the beginning of the word which the cursor is in. */ if (cp == cmdbuf) return (NULL); ! #if SPACES_IN_FILENAMES ! /* ! * If we have an unbalanced quote (that is, an open quote ! * without a corresponding close quote), we return everything ! * from the open quote, including spaces. ! */ ! for (word = cmdbuf; word < cp; word++) ! if (*word != ' ') break; + if (word >= cp) + return (cp); + for (p = cmdbuf; p < cp; p++) + { + if (meta_quoted) + { + meta_quoted = 0; + } else if (esclen > 0 && p + esclen < cp && + strncmp(p, esc, esclen) == 0) + { + meta_quoted = 1; + p += esclen - 1; + } else if (delim_quoted) + { + if (*p == closequote) + delim_quoted = 0; + } else /* (!delim_quoted) */ + { + if (*p == openquote) + delim_quoted = 1; + else if (*p == ' ') + word = p+1; + } + } + #endif return (word); } *************** *** 755,761 **** */ c = *cp; *cp = '\0'; ! tk_text = fcomplete(word); *cp = c; } --- 850,869 ---- */ c = *cp; *cp = '\0'; ! if (*word != openquote) ! { ! tk_text = fcomplete(word); ! } else ! { ! char *qword = shell_quote(word+1); ! if (qword == NULL) ! tk_text = fcomplete(word+1); ! else ! { ! tk_text = fcomplete(qword); ! free(qword); ! } ! } *cp = c; } *************** *** 764,770 **** */ static char * next_compl(action, prev) ! int action; char *prev; { switch (action) --- 872,878 ---- */ static char * next_compl(action, prev) ! int action; char *prev; { switch (action) *************** *** 773,782 **** return (forw_textlist(&tk_tlist, prev)); case EC_B_COMPLETE: return (back_textlist(&tk_tlist, prev)); - default: - /* Cannot happen */ - return ("?"); } } /* --- 881,889 ---- return (forw_textlist(&tk_tlist, prev)); case EC_B_COMPLETE: return (back_textlist(&tk_tlist, prev)); } + /* Cannot happen */ + return ("?"); } /* *************** *** 789,794 **** --- 896,902 ---- cmd_complete(action) int action; { + char *s; if (!in_completion || action == EC_EXPAND) { *************** *** 849,854 **** --- 957,975 ---- */ if (cmd_istr(tk_trial) != CC_OK) goto fail; + /* + * If it is a directory, append a slash. + */ + if (is_dir(tk_trial)) + { + if (cp > cmdbuf && cp[-1] == closequote) + (void) cmd_erase(); + s = lgetenv("LESSSEPARATOR"); + if (s == NULL) + s = PATHNAME_SEP; + if (cmd_istr(s) != CC_OK) + goto fail; + } } return (CC_OK); *************** *** 903,932 **** /* * Insert the char into the command buffer. */ ! action = cmd_ichar(c); ! if (action != CC_OK) ! return (action); ! return (CC_OK); } /* * Return the number currently in the command buffer. */ ! public int cmd_int() { ! return (atoi(cmdbuf)); ! } ! /* ! * Display a string, usually as a prompt for input into the command buffer. ! */ ! public void ! cmd_putstr(s) ! char *s; ! { ! putstr(s); ! cmd_col += strlen(s); } /* --- 1024,1044 ---- /* * Insert the char into the command buffer. */ ! return (cmd_ichar(c)); } /* * Return the number currently in the command buffer. */ ! public LINENUM cmd_int() { ! register char *p; ! LINENUM n = 0; ! for (p = cmdbuf; *p != '\0'; p++) ! n = (10 * n) + (*p - '0'); ! return (n); } /*