From 8fd4165cc499e9e16013a1fcff66055739e5075f Mon Sep 17 00:00:00 2001 From: Paul Saab Date: Mon, 7 Jan 2002 20:37:09 +0000 Subject: [PATCH] Merge vendor changes onto mainline. --- contrib/less/command.c | 67 ++++++++++- contrib/less/less.h | 25 ++++- contrib/less/main.c | 16 ++- contrib/less/prompt.c | 74 ++++++++++--- contrib/less/screen.c | 244 ++++++++++++++++++++++++++++++++--------- contrib/less/search.c | 18 --- 6 files changed, 348 insertions(+), 96 deletions(-) diff --git a/contrib/less/command.c b/contrib/less/command.c index 000cf0b1e848..d9c177c2bb64 100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@ -15,6 +15,9 @@ */ #include "less.h" +#if MSDOS_COMPILER==WIN32C +#include +#endif #include "position.h" #include "option.h" #include "cmd.h" @@ -216,6 +219,8 @@ exec_mca() if (secure) break; edit_list(cbuf); + /* If tag structure is loaded then clean it up. */ + cleantags(); break; #endif #if SHELL_ESCAPE @@ -286,7 +291,7 @@ mca_char(c) * Terminated by a non-digit. */ if ((c < '0' || c > '9') && - editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE) == A_INVALID) + editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) { /* * Not part of the number. @@ -614,6 +619,13 @@ prompt() quit(QUIT_OK); #endif +#if MSDOS_COMPILER==WIN32C + /* + * In Win32, display the file name in the window title. + */ + if (!(ch_getflags() & CH_HELPFILE)) + SetConsoleTitle(pr_expand("Less?f - %f.", 0)); +#endif /* * Select the proper prompt and display it. */ @@ -838,6 +850,7 @@ commands() PARG parg; IFILE old_ifile; IFILE new_ifile; + char *tagfile; search_type = SRCH_FORW; wscroll = (sc_height + 1) / 2; @@ -1355,6 +1368,11 @@ commands() /* * Examine next file. */ + if (ntags()) + { + error("No next file", NULL_PARG); + break; + } if (number <= 0) number = 1; if (edit_next(number)) @@ -1371,6 +1389,11 @@ commands() /* * Examine previous file. */ + if (ntags()) + { + error("No previous file", NULL_PARG); + break; + } if (number <= 0) number = 1; if (edit_prev(number)) @@ -1380,6 +1403,40 @@ commands() } break; + case A_NEXT_TAG: + if (number <= 0) + number = 1; + tagfile = nexttag(number); + if (tagfile == NULL) + { + error("No next tag", NULL_PARG); + break; + } + if (edit(tagfile) == 0) + { + POSITION pos = tagsearch(); + if (pos != NULL_POSITION) + jump_loc(pos, jump_sline); + } + break; + + case A_PREV_TAG: + if (number <= 0) + number = 1; + tagfile = prevtag(number); + if (tagfile == NULL) + { + error("No previous tag", NULL_PARG); + break; + } + if (edit(tagfile) == 0) + { + POSITION pos = tagsearch(); + if (pos != NULL_POSITION) + jump_loc(pos, jump_sline); + } + break; + case A_INDEX_FILE: /* * Examine a particular file. @@ -1508,7 +1565,9 @@ commands() goto again; case A_LSHIFT: - if (number <= 0) + if (number > 0) + shift_count = number; + else number = (shift_count > 0) ? shift_count : sc_width / 2; if (number > hshift) @@ -1518,7 +1577,9 @@ commands() break; case A_RSHIFT: - if (number <= 0) + if (number > 0) + shift_count = number; + else number = (shift_count > 0) ? shift_count : sc_width / 2; hshift += number; diff --git a/contrib/less/less.h b/contrib/less/less.h index ca307d38c0c4..0fb8020e437f 100644 --- a/contrib/less/less.h +++ b/contrib/less/less.h @@ -71,6 +71,9 @@ #if HAVE_CTYPE_H #include #endif +#if HAVE_LIMITS_H +#include +#endif #if HAVE_STDLIB_H #include #endif @@ -81,7 +84,7 @@ #include #include #endif -#if MSDOS_COMPILER==WIN32C +#if MSDOS_COMPILER==WIN32C || OS2 #include #endif #if MSDOS_COMPILER==DJGPPC @@ -137,13 +140,21 @@ void free(); #define BAD_LSEEK ((off_t)-1) +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* + * Upper bound on the string length of an integer converted to string. + * 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit; + * add 1 for integer division truncation; add 1 more for a minus sign. + */ +#define INT_STRLEN_BOUND(t) ((sizeof(t) * CHAR_BIT - 1) * 302 / 1000 + 1 + 1) + /* * Special types and constants. */ typedef off_t POSITION; -#define PR_POSITION "%lld" -#define MAX_PRINT_POSITION 20 -#define MAX_PRINT_INT 10 #define NULL_POSITION ((POSITION)(-1)) @@ -180,7 +191,7 @@ typedef off_t POSITION; #if MSDOS_COMPILER==MSOFTC #define SET_BINARY(f) _setmode(f, _O_BINARY); #else -#if MSDOS_COMPILER +#if MSDOS_COMPILER || OS2 #define SET_BINARY(f) setmode(f, O_BINARY) #else #define SET_BINARY(f) @@ -284,6 +295,10 @@ struct textlist #define AT_INVIS (4) #define AT_STANDOUT (5) +#if '0' == 240 +#define IS_EBCDIC_HOST 1 +#endif + #if IS_EBCDIC_HOST /* * Long definition for EBCDIC. diff --git a/contrib/less/main.c b/contrib/less/main.c index 9f5e1c3d491a..d1a73a405865 100644 --- a/contrib/less/main.c +++ b/contrib/less/main.c @@ -15,6 +15,9 @@ */ #include "less.h" +#if MSDOS_COMPILER==WIN32C +#include +#endif public char * every_first_cmd = NULL; public int new_file; @@ -44,10 +47,15 @@ public char * editproto; #endif #if TAGS +extern char * tags; extern char * tagoption; extern int jump_sline; #endif +#ifdef WIN32 +static char consoleTitle[256]; +#endif + extern int missing_cap; extern int know_dumb; @@ -96,6 +104,7 @@ main(argc, argv) putenv(env); } } + GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char)); #endif /* WIN32 */ /* @@ -168,7 +177,7 @@ main(argc, argv) ifile = get_ifile(FAKE_HELPFILE, ifile); while (argc-- > 0) { -#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) || OS2 +#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) /* * Because the "shell" doesn't expand filename patterns, * treat each argument as a filename pattern rather than @@ -224,7 +233,7 @@ main(argc, argv) * Select the first file to examine. */ #if TAGS - if (tagoption != NULL) + if (tagoption != NULL || strcmp(tags, "-") == 0) { /* * A -t option was given. @@ -379,6 +388,9 @@ quit(status) * The same bug shows up if we use ^C^C to abort. */ close(2); +#endif +#if WIN32 + SetConsoleTitle(consoleTitle); #endif close_getchr(); exit(status); diff --git a/contrib/less/prompt.c b/contrib/less/prompt.c index 14f8ac4253d1..680b25ffe6a3 100644 --- a/contrib/less/prompt.c +++ b/contrib/less/prompt.c @@ -42,19 +42,22 @@ extern char *editproto; * These strings are expanded by pr_expand(). */ static constant char s_proto[] = - "?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x..%t"; + "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t"; static constant char m_proto[] = - "?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t"; + "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t"; static constant char M_proto[] = - "?f%f .?n?m(file %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t"; + "?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t"; static constant char e_proto[] = - "?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t"; + "?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t"; static constant char h_proto[] = "HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done"; +static constant char w_proto[] = + "Waiting for data"; public char *prproto[3]; public char constant *eqproto = e_proto; public char constant *hproto = h_proto; +public char constant *wproto = w_proto; static char message[PROMPT_SIZE]; static char *mp; @@ -70,6 +73,7 @@ init_prompt() prproto[2] = save(M_proto); eqproto = save(e_proto); hproto = save(h_proto); + wproto = save(w_proto); } /* @@ -110,10 +114,19 @@ ap_char(c) ap_pos(pos) POSITION pos; { - char buf[MAX_PRINT_POSITION]; - - sprintf(buf, PR_POSITION, (long long)pos); - ap_str(buf); + char buf[INT_STRLEN_BOUND(pos) + 1]; + char *p = buf + sizeof(buf) - 1; + int neg = (pos < 0); + + if (neg) + pos = -pos; + *p = '\0'; + do + *--p = '0' + (pos % 10); + while ((pos /= 10) != 0); + if (neg) + *--p = '-'; + ap_str(p); } /* @@ -123,7 +136,7 @@ ap_pos(pos) ap_int(n) int n; { - char buf[MAX_PRINT_INT]; + char buf[INT_STRLEN_BOUND(n) + 1]; sprintf(buf, "%d", n); ap_str(buf); @@ -187,9 +200,9 @@ cond(c, where) case 'D': /* Same as L */ return (linenums && ch_length() != NULL_POSITION); case 'm': /* More than one file? */ - return (nifile() > 1); + return (ntags() ? (ntags() > 1) : (nifile() > 1)); case 'n': /* First prompt in a new file? */ - return (new_file); + return (ntags() ? 1 : new_file); case 'p': /* Percent into file (bytes) known? */ return (curr_byte(where) != NULL_POSITION && ch_length() > 0); @@ -201,6 +214,8 @@ cond(c, where) case 'B': return (ch_length() != NULL_POSITION); case 'x': /* Is there a "next" file? */ + if (ntags()) + return (0); return (next_ifile(curr_ifile) != NULL_IFILE); } return (0); @@ -273,7 +288,10 @@ protochar(c, where, iseditproto) free(s); break; case 'i': /* Index into list of files */ - ap_int(get_index(curr_ifile)); + if (ntags()) + ap_int(curr_tag()); + else + ap_int(get_index(curr_ifile)); break; case 'l': /* Current line number */ n = currline(where); @@ -291,7 +309,11 @@ protochar(c, where, iseditproto) ap_int(n-1); break; case 'm': /* Number of files */ - ap_int(nifile()); + n = ntags(); + if (n) + ap_int(n); + else + ap_int(nifile()); break; case 'p': /* Percent into file (bytes) */ pos = curr_byte(where); @@ -322,6 +344,12 @@ protochar(c, where, iseditproto) while (mp > message && mp[-1] == ' ') mp--; break; + case 'T': /* Type of list */ + if (ntags()) + ap_str("tag"); + else + ap_str("file"); + break; case 'x': /* Name of next file */ h = next_ifile(curr_ifile); if (h != NULL_IFILE) @@ -484,7 +512,6 @@ pr_expand(proto, maxwidth) } } - new_file = 0; if (mp == message) return (NULL); if (maxwidth > 0 && mp >= message + maxwidth) @@ -516,7 +543,20 @@ eq_message() public char * pr_string() { - if (ch_getflags() & CH_HELPFILE) - return (pr_expand(hproto, sc_width-so_s_width-so_e_width-2)); - return (pr_expand(prproto[pr_type], sc_width-so_s_width-so_e_width-2)); + char *prompt; + + prompt = pr_expand((ch_getflags() & CH_HELPFILE) ? + hproto : prproto[pr_type], + sc_width-so_s_width-so_e_width-2); + new_file = 0; + return (prompt); +} + +/* + * Return a message suitable for printing while waiting in the F command. + */ + public char * +wait_message() +{ + return (pr_expand(wproto, sc_width-so_s_width-so_e_width-2)); } diff --git a/contrib/less/screen.c b/contrib/less/screen.c index cd3d885905cb..28bcfac91604 100644 --- a/contrib/less/screen.c +++ b/contrib/less/screen.c @@ -67,6 +67,7 @@ extern int fd0; #endif #if OS2 #include +#include "pckeys.h" #endif #if HAVE_SYS_STREAM_H #include @@ -89,6 +90,7 @@ extern int fd0; #if OS2 #define DEFAULT_TERM "ansi" +static char *windowid; #else #define DEFAULT_TERM "unknown" #endif @@ -226,6 +228,7 @@ extern int swindow; extern int no_init; extern int quit_at_eof; extern int more_mode; +extern int no_keypad; extern int sigs; extern int wscroll; extern int screen_trashed; @@ -422,6 +425,9 @@ raw_mode(on) */ s = save_term; } +#if HAVE_FSYNC + fsync(2); +#endif tcsetattr(2, TCSADRAIN, &s); #if MUST_SET_LINE_DISCIPLINE if (!on) @@ -711,6 +717,27 @@ scrsize() _scrsize(s); sys_width = s[0]; sys_height = s[1]; + /* + * When using terminal emulators for XFree86/OS2, the + * _scrsize function does not work well. + * Call the scrsize.exe program to get the window size. + */ + windowid = getenv("WINDOWID"); + if (windowid != NULL) + { + FILE *fd = popen("scrsize", "rt"); + if (fd != NULL) + { + int w, h; + fscanf(fd, "%i %i", &w, &h); + if (w > 0 && h > 0) + { + sys_width = w; + sys_height = h; + } + pclose(fd); + } + } } #else #ifdef TIOCGWINSZ @@ -834,7 +861,7 @@ special_key_str(key) { static char tbuf[40]; char *s; -#if MSDOS_COMPILER +#if MSDOS_COMPILER || OS2 static char k_right[] = { '\340', PCK_RIGHT, 0 }; static char k_left[] = { '\340', PCK_LEFT, 0 }; static char k_ctl_right[] = { '\340', PCK_CTL_RIGHT, 0 }; @@ -851,12 +878,56 @@ special_key_str(key) static char k_pagedown[] = { '\340', PCK_PAGEDOWN, 0 }; static char k_pageup[] = { '\340', PCK_PAGEUP, 0 }; static char k_f1[] = { '\340', PCK_F1, 0 }; -#else +#endif +#if !MSDOS_COMPILER char *sp = tbuf; #endif switch (key) { +#if OS2 + /* + * If windowid is not NULL, assume less is executed in + * the XFree86 environment. + */ + case SK_RIGHT_ARROW: + s = windowid ? ltgetstr("kr", &sp) : k_right; + break; + case SK_LEFT_ARROW: + s = windowid ? ltgetstr("kl", &sp) : k_left; + break; + case SK_UP_ARROW: + s = windowid ? ltgetstr("ku", &sp) : k_up; + break; + case SK_DOWN_ARROW: + s = windowid ? ltgetstr("kd", &sp) : k_down; + break; + case SK_PAGE_UP: + s = windowid ? ltgetstr("kP", &sp) : k_pageup; + break; + case SK_PAGE_DOWN: + s = windowid ? ltgetstr("kN", &sp) : k_pagedown; + break; + case SK_HOME: + s = windowid ? ltgetstr("kh", &sp) : k_home; + break; + case SK_END: + s = windowid ? ltgetstr("@7", &sp) : k_end; + break; + case SK_DELETE: + if (windowid) + { + s = ltgetstr("kD", &sp); + if (s == NULL) + { + tbuf[0] = '\177'; + tbuf[1] = '\0'; + s = tbuf; + } + } else + s = k_delete; + break; +#endif #if MSDOS_COMPILER case SK_RIGHT_ARROW: s = k_right; @@ -885,6 +956,8 @@ special_key_str(key) case SK_DELETE: s = k_delete; break; +#endif +#if MSDOS_COMPILER || OS2 case SK_INSERT: s = k_insert; break; @@ -1437,21 +1510,15 @@ win32_deinit_term() public void init() { - if (no_init) - { -#if MSDOS_COMPILER==WIN32C - /* no_init or not, never trash win32 console colors. */ - initcolor(); - flush(); -#endif - return; - } #if !MSDOS_COMPILER - tputs(sc_init, sc_height, putchr); - tputs(sc_s_keypad, sc_height, putchr); + if (!no_init) + tputs(sc_init, sc_height, putchr); + if (!no_keypad) + tputs(sc_s_keypad, sc_height, putchr); #else #if MSDOS_COMPILER==WIN32C - win32_init_term(); + if (!no_init) + win32_init_term(); #endif initcolor(); flush(); @@ -1465,24 +1532,22 @@ init() public void deinit() { - if (no_init) - { -#if MSDOS_COMPILER==WIN32C - /* no_init or not, never trash win32 console colors. */ - SETCOLORS(sy_fg_color, sy_bg_color); -#endif - return; - } - if (!init_done) return; #if !MSDOS_COMPILER - tputs(sc_e_keypad, sc_height, putchr); - tputs(sc_deinit, sc_height, putchr); + if (!no_keypad) + tputs(sc_e_keypad, sc_height, putchr); + if (!no_init) + tputs(sc_deinit, sc_height, putchr); #else + /* Restore system colors. */ SETCOLORS(sy_fg_color, sy_bg_color); #if MSDOS_COMPILER==WIN32C - win32_deinit_term(); + if (!no_init) + win32_deinit_term(); +#else + /* Need clreol to make SETCOLORS take effect. */ + clreol(); #endif #endif init_done = 0; @@ -1558,6 +1623,7 @@ add_line() #endif } +#if 0 /* * Remove the n topmost lines and scroll everything below it in the * window upward. This is needed to stop leaking the topmost line @@ -1611,6 +1677,105 @@ remove_top(n) goto_line(sc_height - n - 1); #endif } +#endif + +#if MSDOS_COMPILER==WIN32C +/* + * Clear the screen. + */ + static void +win32_clear() +{ + /* + * This will clear only the currently visible rows of the NT + * console buffer, which means none of the precious scrollback + * rows are touched making for faster scrolling. Note that, if + * the window has fewer columns than the console buffer (i.e. + * there is a horizontal scrollbar as well), the entire width + * of the visible rows will be cleared. + */ + COORD topleft; + DWORD nchars; + DWORD winsz; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + /* get the number of cells in the current buffer */ + GetConsoleScreenBufferInfo(con_out, &csbi); + winsz = csbi.dwSize.X * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1); + topleft.X = 0; + topleft.Y = csbi.srWindow.Top; + + curr_attr = MAKEATTR(nm_fg_color, nm_bg_color); + FillConsoleOutputCharacter(con_out, ' ', winsz, topleft, &nchars); + FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars); +} + +/* + * Remove the n topmost lines and scroll everything below it in the + * window upward. + */ + public void +win32_scroll_up(n) + int n; +{ + SMALL_RECT rcSrc, rcClip; + CHAR_INFO fillchar; + COORD topleft; + COORD new_org; + DWORD nchars; + DWORD size; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + if (n <= 0) + return; + + if (n >= sc_height - 1) + { + win32_clear(); + _settextposition(1,1); + return; + } + + /* Get the extent of what will remain visible after scrolling. */ + GetConsoleScreenBufferInfo(con_out, &csbi); + rcSrc.Left = csbi.srWindow.Left; + rcSrc.Top = csbi.srWindow.Top + n; + rcSrc.Right = csbi.srWindow.Right; + rcSrc.Bottom = csbi.srWindow.Bottom; + + /* Get the clip rectangle. */ + rcClip.Left = rcSrc.Left; + rcClip.Top = csbi.srWindow.Top; + rcClip.Right = rcSrc.Right; + rcClip.Bottom = rcSrc.Bottom ; + + /* Move the source text to the top of the screen. */ + new_org.X = rcSrc.Left; + new_org.Y = 0; + + /* Fill the right character and attributes. */ + fillchar.Char.AsciiChar = ' '; + fillchar.Attributes = MAKEATTR(nm_fg_color, nm_bg_color); + + /* Scroll the window. */ + SetConsoleTextAttribute(con_out, fillchar.Attributes); + ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar); + + /* Clear remaining lines at bottom. */ + topleft.X = csbi.dwCursorPosition.X; + topleft.Y = rcSrc.Bottom - n; + size = (n * csbi.dwSize.X) + (rcSrc.Right - topleft.X); + FillConsoleOutputCharacter(con_out, ' ', size, topleft, + &nchars); + FillConsoleOutputAttribute(con_out, fillchar.Attributes, size, topleft, + &nchars); + SetConsoleTextAttribute(con_out, curr_attr); + + /* Move cursor n lines up from where it was. */ + csbi.dwCursorPosition.Y -= n; + SetConsoleCursorPosition(con_out, csbi.dwCursorPosition); +} +#endif /* * Move cursor to lower left corner of screen. @@ -1806,7 +1971,7 @@ vbell() beep() { #if !MSDOS_COMPILER - putchr('\7'); + putchr(CONTROL('G')); #else #if MSDOS_COMPILER==WIN32C MessageBeep(0); @@ -1839,30 +2004,7 @@ clear() #else flush(); #if MSDOS_COMPILER==WIN32C - /* - * This will clear only the currently visible rows of the NT - * console buffer, which means none of the precious scrollback - * rows are touched making for faster scrolling. Note that, if - * the window has fewer columns than the console buffer (i.e. - * there is a horizontal scrollbar as well), the entire width - * of the visible rows will be cleared. - */ - { - COORD topleft; - DWORD nchars; - DWORD winsz; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - /* get the number of cells in the current buffer */ - GetConsoleScreenBufferInfo(con_out, &csbi); - winsz = csbi.dwSize.X * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1); - topleft.X = 0; - topleft.Y = csbi.srWindow.Top; - - curr_attr = MAKEATTR(nm_fg_color, nm_bg_color); - FillConsoleOutputCharacter(con_out, ' ', winsz, topleft, &nchars); - FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars); - } + win32_clear(); #else _clearscreen(_GCLEARSCREEN); #endif diff --git a/contrib/less/search.c b/contrib/less/search.c index ff00a311d300..dd7e2c8c247a 100644 --- a/contrib/less/search.c +++ b/contrib/less/search.c @@ -1343,21 +1343,3 @@ regerror(s) } #endif -#if !HAVE_STRCHR -/* - * strchr is used by regexp.c. - */ - char * -strchr(s, c) - char *s; - int c; -{ - for ( ; *s != '\0'; s++) - if (*s == c) - return (s); - if (c == '\0') - return (s); - return (NULL); -} -#endif -