diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2015-11-05 22:08:45 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2015-11-05 22:08:45 +0000 |
commit | bbf6e0df84a550def496315d87fd6e3fd4c01f79 (patch) | |
tree | 7afab0058e7f754101db35be2a89c08b5c56736c /usr.bin/less/prompt.c | |
parent | fc3f216f35058a68bee51fbaa32b206e6fa8ea59 (diff) |
Replace less with the cleaned-up fork of less 458 maintained by Garrett
D'Amore at https://github.com/gdamore/less-fork. This has significantly
less portability goop, has a tidied up code style, uses terminfo instead
of termcap, and is has stricter POSIX compliance.
Many of our local changes have been accepted upstream: substantial
remaining local changes are code to read help files from /usr/share
rather than compiling them in, man page and help improvements, and some
tweaks to the default options.
Review and testing by millert, ok deraadt
Diffstat (limited to 'usr.bin/less/prompt.c')
-rw-r--r-- | usr.bin/less/prompt.c | 347 |
1 files changed, 153 insertions, 194 deletions
diff --git a/usr.bin/less/prompt.c b/usr.bin/less/prompt.c index fc02de3ef8e..0b5b25a13ed 100644 --- a/usr.bin/less/prompt.c +++ b/usr.bin/less/prompt.c @@ -6,14 +6,17 @@ * * For more information, see the README file. */ - +/* + * Modified for use with illumos. + * Copyright 2014 Garrett D'Amore <garrett@damore.org> + */ /* * Prompting and other messages. * There are three flavors of prompts, SHORT, MEDIUM and LONG, * selected by the -m/-M options. * There is also the "equals message", printed by the = command. - * A prompt is a message composed of various pieces, such as the + * A prompt is a message composed of various pieces, such as the * name of the file being viewed, the percentage into the file, etc. */ @@ -30,32 +33,40 @@ extern int sc_height; extern int jump_sline; extern int less_is_more; extern IFILE curr_ifile; -#if EDITOR extern char *editor; extern char *editproto; -#endif /* * Prototypes for the three flavors of prompts. * These strings are expanded by pr_expand(). */ -static constant char s_proto[] = - "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t"; -static constant char m_proto[] = - "?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(%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(%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 const char s_proto[] = + "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t"; +static const char m_proto[] = + "?n?f%f .?m(%T %i of %m) ..?e(END) " + "?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t"; +static const char M_proto[] = + "?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 const char e_proto[] = + "?f%f .?m(%T %i of %m) .?ltlines " + "%lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t"; +static const char h_proto[] = + "HELP -- ?eEND -- Press g to see it again:" + "Press RETURN for more., or q when done"; +static const char w_proto[] = + "Waiting for data"; +static const char more_proto[] = + "%f (?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)"; +static const char more_M_proto[] = + "%f (?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)" + "[Press space to continue, q to quit, h for help]"; + +char *prproto[3]; +char const *eqproto = e_proto; +char const *hproto = h_proto; +char const *wproto = w_proto; static char message[PROMPT_SIZE]; static char *mp; @@ -63,12 +74,12 @@ static char *mp; /* * Initialize the prompt prototype strings. */ - public void -init_prompt() +void +init_prompt(void) { prproto[0] = save(s_proto); - prproto[1] = save(m_proto); - prproto[2] = save(M_proto); + prproto[1] = save(less_is_more ? more_proto : m_proto); + prproto[2] = save(less_is_more ? more_M_proto : M_proto); eqproto = save(e_proto); hproto = save(h_proto); wproto = save(w_proto); @@ -77,16 +88,15 @@ init_prompt() /* * Append a string to the end of the message. */ - static void -ap_str(s) - char *s; +static void +ap_str(char *s) { int len; len = strlen(s); if (mp + len >= message + PROMPT_SIZE) len = message + PROMPT_SIZE - mp - 1; - strncpy(mp, s, len); + (void) strncpy(mp, s, len); mp += len; *mp = '\0'; } @@ -94,9 +104,8 @@ ap_str(s) /* * Append a character to the end of the message. */ - static void -ap_char(c) - char c; +static void +ap_char(char c) { char buf[2]; @@ -106,49 +115,46 @@ ap_char(c) } /* - * Append a POSITION (as a decimal integer) to the end of the message. + * Append a off_t (as a decimal integer) to the end of the message. */ - static void -ap_pos(pos) - POSITION pos; +static void +ap_pos(off_t pos) { char buf[INT_STRLEN_BOUND(pos) + 2]; - postoa(pos, buf, sizeof(buf)); + postoa(pos, buf, sizeof buf); ap_str(buf); } /* * Append a line number to the end of the message. */ - static void -ap_linenum(linenum) - LINENUM linenum; +static void +ap_linenum(LINENUM linenum) { char buf[INT_STRLEN_BOUND(linenum) + 2]; - linenumtoa(linenum, buf, sizeof(buf)); + linenumtoa(linenum, buf, sizeof buf); ap_str(buf); } /* * Append an integer to the end of the message. */ - static void -ap_int(num) - int num; +static void +ap_int(int num) { char buf[INT_STRLEN_BOUND(num) + 2]; - inttoa(num, buf, sizeof(buf)); + inttoa(num, buf, sizeof buf); ap_str(buf); } /* * Append a question mark to the end of the message. */ - static void -ap_quest() +static void +ap_quest(void) { ap_str("?"); } @@ -156,39 +162,35 @@ ap_quest() /* * Return the "current" byte offset in the file. */ - static POSITION -curr_byte(where) - int where; +static off_t +curr_byte(int where) { - POSITION pos; + off_t pos; pos = position(where); - while (pos == NULL_POSITION && where >= 0 && where < sc_height-1) + while (pos == -1 && where >= 0 && where < sc_height-1) pos = position(++where); - if (pos == NULL_POSITION) + if (pos == -1) pos = ch_length(); return (pos); } /* * Return the value of a prototype conditional. - * A prototype string may include conditionals which consist of a + * A prototype string may include conditionals which consist of a * question mark followed by a single letter. * Here we decode that letter and return the appropriate boolean value. */ - static int -cond(c, where) - char c; - int where; +static int +cond(char c, int where) { - POSITION len; + off_t len; - switch (c) - { + switch (c) { case 'a': /* Anything in the message yet? */ return (mp > message); case 'b': /* Current byte offset known? */ - return (curr_byte(where) != NULL_POSITION); + return (curr_byte(where) != -1); case 'c': return (hshift != 0); case 'e': /* At end of file? */ @@ -200,34 +202,22 @@ cond(c, where) return (linenums); case 'L': /* Final line number known? */ case 'D': /* Final page number known? */ - return (linenums && ch_length() != NULL_POSITION); + return (linenums && ch_length() != -1); case 'm': /* More than one file? */ -#if TAGS return (ntags() ? (ntags() > 1) : (nifile() > 1)); -#else - return (nifile() > 1); -#endif case 'n': /* First prompt in a new file? */ -#if TAGS return (ntags() ? 1 : new_file); -#else - return (new_file); -#endif case 'p': /* Percent into file (bytes) known? */ - return (curr_byte(where) != NULL_POSITION && - ch_length() > 0); + return (curr_byte(where) != -1 && ch_length() > 0); case 'P': /* Percent into file (lines) known? */ return (currline(where) != 0 && - (len = ch_length()) > 0 && - find_linenum(len) != 0); + (len = ch_length()) > 0 && find_linenum(len) != 0); case 's': /* Size of file known? */ case 'B': - return (ch_length() != NULL_POSITION); + return (ch_length() != -1); case 'x': /* Is there a "next" file? */ -#if TAGS if (ntags()) return (0); -#endif return (next_ifile(curr_ifile) != NULL_IFILE); } return (0); @@ -240,27 +230,23 @@ cond(c, where) * Here we decode that letter and take the appropriate action, * usually by appending something to the message being built. */ - static void -protochar(c, where, iseditproto) - int c; - int where; - int iseditproto; +static void +protochar(int c, int where) { - POSITION pos; - POSITION len; + off_t pos; + off_t len; int n; LINENUM linenum; LINENUM last_linenum; IFILE h; -#undef PAGE_NUM -#define PAGE_NUM(linenum) ((((linenum) - 1) / (sc_height - 1)) + 1) +#undef PAGE_NUM +#define PAGE_NUM(linenum) ((((linenum) - 1) / (sc_height - 1)) + 1) - switch (c) - { + switch (c) { case 'b': /* Current byte offset */ pos = curr_byte(where); - if (pos != NULL_POSITION) + if (pos != -1) ap_pos(pos); else ap_quest(); @@ -278,25 +264,22 @@ protochar(c, where, iseditproto) case 'D': /* Final page number */ /* Find the page number of the last byte in the file (len-1). */ len = ch_length(); - if (len == NULL_POSITION) + if (len == -1) { ap_quest(); - else if (len == 0) + } else if (len == 0) { /* An empty file has no pages. */ ap_linenum(0); - else - { + } else { linenum = find_linenum(len - 1); if (linenum <= 0) ap_quest(); - else + else ap_linenum(PAGE_NUM(linenum)); } break; -#if EDITOR case 'E': /* Editor name */ ap_str(editor); break; -#endif case 'f': /* File name */ ap_str(get_filename(curr_ifile)); break; @@ -304,11 +287,9 @@ protochar(c, where, iseditproto) ap_str(last_component(get_filename(curr_ifile))); break; case 'i': /* Index into list of files */ -#if TAGS if (ntags()) ap_int(curr_tag()); else -#endif ap_int(get_index(curr_ifile)); break; case 'l': /* Current line number */ @@ -320,33 +301,31 @@ protochar(c, where, iseditproto) break; case 'L': /* Final line number */ len = ch_length(); - if (len == NULL_POSITION || len == ch_zero() || + if (len == -1 || len == ch_zero() || (linenum = find_linenum(len)) <= 0) ap_quest(); else ap_linenum(linenum-1); break; case 'm': /* Number of files */ -#if TAGS n = ntags(); if (n) ap_int(n); else -#endif ap_int(nifile()); break; case 'p': /* Percent into file (bytes) */ pos = curr_byte(where); len = ch_length(); - if (pos != NULL_POSITION && len > 0) - ap_int(percentage(pos,len)); + if (pos != -1 && len > 0) + ap_int(percentage(pos, len)); else ap_quest(); break; case 'P': /* Percent into file (lines) */ linenum = currline(where); if (linenum == 0 || - (len = ch_length()) == NULL_POSITION || len == ch_zero() || + (len = ch_length()) == -1 || len == ch_zero() || (last_linenum = find_linenum(len)) <= 0) ap_quest(); else @@ -355,7 +334,7 @@ protochar(c, where, iseditproto) case 's': /* Size of file */ case 'B': len = ch_length(); - if (len != NULL_POSITION) + if (len != -1) ap_pos(len); else ap_quest(); @@ -366,11 +345,9 @@ protochar(c, where, iseditproto) *mp = '\0'; break; case 'T': /* Type of list */ -#if TAGS if (ntags()) ap_str("tag"); else -#endif ap_str("file"); break; case 'x': /* Name of next file */ @@ -385,16 +362,15 @@ protochar(c, where, iseditproto) /* * Skip a false conditional. - * When a false condition is found (either a false IF or the ELSE part + * When a false condition is found (either a false IF or the ELSE part * of a true IF), this routine scans the prototype string to decide * where to resume parsing the string. * We must keep track of nested IFs and skip them properly. */ - static constant char * -skipcond(p) - register constant char *p; +static const char * +skipcond(const char *p) { - register int iflevel; + int iflevel; /* * We came in here after processing a ? or :, @@ -402,45 +378,46 @@ skipcond(p) */ iflevel = 1; - for (;;) switch (*++p) - { - case '?': - /* - * Start of a nested IF. - */ - iflevel++; - break; - case ':': - /* - * Else. - * If this matches the IF we came in here with, - * then we're done. - */ - if (iflevel == 1) - return (p); - break; - case '.': - /* - * Endif. - * If this matches the IF we came in here with, - * then we're done. - */ - if (--iflevel == 0) - return (p); - break; - case '\\': - /* - * Backslash escapes the next character. - */ - ++p; - break; - case '\0': - /* - * Whoops. Hit end of string. - * This is a malformed conditional, but just treat it - * as if all active conditionals ends here. - */ - return (p-1); + for (;;) { + switch (*++p) { + case '?': + /* + * Start of a nested IF. + */ + iflevel++; + break; + case ':': + /* + * Else. + * If this matches the IF we came in here with, + * then we're done. + */ + if (iflevel == 1) + return (p); + break; + case '.': + /* + * Endif. + * If this matches the IF we came in here with, + * then we're done. + */ + if (--iflevel == 0) + return (p); + break; + case '\\': + /* + * Backslash escapes the next character. + */ + ++p; + break; + case '\0': + /* + * Whoops. Hit end of string. + * This is a malformed conditional, but just treat it + * as if all active conditionals ends here. + */ + return (p-1); + } } /*NOTREACHED*/ } @@ -448,16 +425,12 @@ skipcond(p) /* * Decode a char that represents a position on the screen. */ - static constant char * -wherechar(p, wp) - char constant *p; - int *wp; +static const char * +wherechar(const char *p, int *wp) { - switch (*p) - { + switch (*p) { case 'b': case 'd': case 'l': case 'p': case 'P': - switch (*++p) - { + switch (*++p) { case 't': *wp = TOP; break; case 'm': *wp = MIDDLE; break; case 'b': *wp = BOTTOM; break; @@ -472,13 +445,11 @@ wherechar(p, wp) /* * Construct a message based on a prototype string. */ - public char * -pr_expand(proto, maxwidth) - constant char *proto; - int maxwidth; +char * +pr_expand(const char *proto, int maxwidth) { - register constant char *p; - register int c; + const char *p; + int c; int where; mp = message; @@ -486,10 +457,8 @@ pr_expand(proto, maxwidth) if (*proto == '\0') return (""); - for (p = proto; *p != '\0'; p++) - { - switch (*p) - { + for (p = proto; *p != '\0'; p++) { + switch (*p) { default: /* Just put the character in the message */ ap_char(*p); break; @@ -498,10 +467,9 @@ pr_expand(proto, maxwidth) ap_char(*p); break; case '?': /* Conditional (IF) */ - if ((c = *++p) == '\0') + if ((c = *++p) == '\0') { --p; - else - { + } else { where = 0; p = wherechar(p, &where); if (!cond(c, where)) @@ -514,19 +482,12 @@ pr_expand(proto, maxwidth) case '.': /* ENDIF */ break; case '%': /* Percent escape */ - if ((c = *++p) == '\0') + if ((c = *++p) == '\0') { --p; - else - { + } else { where = 0; p = wherechar(p, &where); - protochar(c, where, -#if EDITOR - (proto == editproto)); -#else - 0); -#endif - + protochar(c, where); } break; } @@ -534,8 +495,7 @@ pr_expand(proto, maxwidth) if (mp == message) return (""); - if (maxwidth > 0 && mp >= message + maxwidth) - { + if (maxwidth > 0 && mp >= message + maxwidth) { /* * Message is too long. * Return just the final portion of it. @@ -548,8 +508,8 @@ pr_expand(proto, maxwidth) /* * Return a message suitable for printing by the "=" command. */ - public char * -eq_message() +char * +eq_message(void) { return (pr_expand(eqproto, 0)); } @@ -560,16 +520,15 @@ eq_message() * If we can't come up with an appropriate prompt, return NULL * and the caller will prompt with a colon. */ - public char * -pr_string() +char * +prompt_string(void) { char *prompt; int type; - type = (!less_is_more) ? pr_type : pr_type ? 0 : 1; + type = pr_type; prompt = pr_expand((ch_getflags() & CH_HELPFILE) ? - hproto : prproto[type], - sc_width-so_s_width-so_e_width-2); + hproto : prproto[type], sc_width-so_s_width-so_e_width-2); new_file = 0; return (prompt); } @@ -577,8 +536,8 @@ pr_string() /* * Return a message suitable for printing while waiting in the F command. */ - public char * -wait_message() +char * +wait_message(void) { return (pr_expand(wproto, sc_width-so_s_width-so_e_width-2)); } |