summaryrefslogtreecommitdiff
path: root/usr.bin/less/prompt.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-04-13 18:26:27 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-04-13 18:26:27 +0000
commit5569f8a6b6c831077f77d24e2c23d2e2d41fb95f (patch)
treeb79fe763d81906631382fbdc80f3b42a44b6c668 /usr.bin/less/prompt.c
parent6b9d6b99a4fdda2ee6d9a30dec452d8202fb2017 (diff)
Merge in less-381 w/ local changes and remove obsolete files.
Diffstat (limited to 'usr.bin/less/prompt.c')
-rw-r--r--usr.bin/less/prompt.c264
1 files changed, 190 insertions, 74 deletions
diff --git a/usr.bin/less/prompt.c b/usr.bin/less/prompt.c
index 5a7159b18ce..9a257809fab 100644
--- a/usr.bin/less/prompt.c
+++ b/usr.bin/less/prompt.c
@@ -1,29 +1,11 @@
-/* $OpenBSD: prompt.c,v 1.6 2003/04/06 23:38:07 deraadt Exp $ */
-
/*
- * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman
- * All rights reserved.
+ * Copyright (C) 1984-2002 Mark Nudelman
*
- * 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.
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Less License, as specified in the README file.
*
- * 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.
+ * For more information about less, or for information on how to
+ * contact the author, see the README file.
*/
@@ -45,30 +27,41 @@ extern int new_file;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int linenums;
+extern int hshift;
+extern int ismore;
extern int sc_height;
extern int jump_sline;
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 char s_proto[] =
- "?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x..%t";
-static char m_proto[] =
- "?f%f .?m(file %i of %m) .?e(END) ?x- Next\\: %x.:(?pB%pB\\%:byte %bB?s/%s..).%t";
-static char M_proto[] =
- "?f%f .?n?m(file %i of %m) ..?ltline %lt?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t";
-static char e_proto[] =
- "?f%f .?m(file %i of %m) .?ltline %lt?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t";
+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 more_proto[] =
+ "--More--.?e(END) ?x- Next\\: %x.:(?pB%pB\\%:byte %bB?s/%s..).%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 *eqproto = e_proto;
+public char constant *eqproto = e_proto;
+public char constant *hproto = h_proto;
+public char constant *wproto = w_proto;
-static char message[250];
+static char message[PROMPT_SIZE];
static char *mp;
/*
@@ -77,20 +70,43 @@ static char *mp;
public void
init_prompt()
{
- prproto[0] = save(s_proto);
+ prproto[0] = save(ismore ? more_proto : s_proto);
prproto[1] = save(m_proto);
prproto[2] = save(M_proto);
eqproto = save(e_proto);
+ hproto = save(h_proto);
+ wproto = save(w_proto);
}
/*
- * Set the message pointer to the end of the message string.
+ * Append a string to the end of the message.
*/
static void
-setmp()
+ap_str(s)
+ char *s;
{
- while (*mp != '\0')
- mp++;
+ int len;
+
+ len = strlen(s);
+ if (mp + len >= message + PROMPT_SIZE)
+ len = message + PROMPT_SIZE - mp - 1;
+ strncpy(mp, s, len);
+ mp += len;
+ *mp = '\0';
+}
+
+/*
+ * Append a character to the end of the message.
+ */
+ static void
+ap_char(c)
+ char c;
+{
+ char buf[2];
+
+ buf[0] = c;
+ buf[1] = '\0';
+ ap_str(buf);
}
/*
@@ -100,30 +116,36 @@ setmp()
ap_pos(pos)
POSITION pos;
{
- snprintf(mp, message + sizeof message - mp, "%qd", pos);
- setmp();
+ char buf[INT_STRLEN_BOUND(pos) + 2];
+
+ postoa(pos, buf, sizeof(buf));
+ ap_str(buf);
}
/*
- * Append an integer to the end of the message.
+ * Append a line number to the end of the message.
*/
- static void
-ap_int(n)
- int n;
+ static void
+ap_linenum(linenum)
+ LINENUM linenum;
{
- snprintf(mp, message + sizeof message - mp, "%d", n);
- setmp();
+ char buf[INT_STRLEN_BOUND(linenum) + 2];
+
+ linenumtoa(linenum, buf, sizeof(buf));
+ ap_str(buf);
}
/*
- * Append a string to the end of the message.
+ * Append an integer to the end of the message.
*/
static void
-ap_str(s)
- char *s;
+ap_int(num)
+ int num;
{
- strtcpy(mp, s, (unsigned int)(&message[sizeof(message)] - mp));
- setmp();
+ char buf[INT_STRLEN_BOUND(num) + 2];
+
+ inttoa(num, buf, sizeof(buf));
+ ap_str(buf);
}
/*
@@ -132,8 +154,7 @@ ap_str(s)
static void
ap_quest()
{
- if (mp < message + sizeof message - 1)
- *mp++ = '?';
+ ap_str("?");
}
/*
@@ -164,31 +185,53 @@ cond(c, where)
char c;
int where;
{
+ POSITION len;
+
switch (c)
{
case 'a': /* Anything in the message yet? */
return (mp > message);
case 'b': /* Current byte offset known? */
return (curr_byte(where) != NULL_POSITION);
+ case 'c':
+ return (hshift != 0);
case 'e': /* At end of file? */
return (hit_eof);
case 'f': /* Filename known? */
return (strcmp(get_filename(curr_ifile), "-") != 0);
case 'l': /* Line number known? */
+ case 'd': /* Same as l */
return (linenums);
case 'L': /* Final line number known? */
+ case 'D': /* Same as L */
return (linenums && ch_length() != NULL_POSITION);
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);
- case 'p': /* Percent into file known? */
+#endif
+ case 'p': /* Percent into file (bytes) known? */
return (curr_byte(where) != NULL_POSITION &&
ch_length() > 0);
+ case 'P': /* Percent into file (lines) known? */
+ return (currline(where) != 0 &&
+ (len = ch_length()) > 0 &&
+ find_linenum(len) != 0);
case 's': /* Size of file known? */
case 'B':
return (ch_length() != NULL_POSITION);
case 'x': /* Is there a "next" file? */
+#if TAGS
+ if (ntags())
+ return (0);
+#endif
return (next_ifile(curr_ifile) != NULL_IFILE);
}
return (0);
@@ -202,13 +245,16 @@ cond(c, where)
* usually by appending something to the message being built.
*/
static void
-protochar(c, where)
+protochar(c, where, iseditproto)
int c;
int where;
+ int iseditproto;
{
POSITION pos;
POSITION len;
int n;
+ LINENUM linenum;
+ LINENUM last_linenum;
IFILE h;
switch (c)
@@ -220,6 +266,24 @@ protochar(c, where)
else
ap_quest();
break;
+ case 'c':
+ ap_int(hshift);
+ break;
+ case 'd': /* Current page number */
+ linenum = currline(where);
+ if (linenum > 0 && sc_height > 1)
+ ap_linenum(((linenum - 1) / (sc_height - 1)) + 1);
+ else
+ ap_quest();
+ break;
+ case 'D': /* Last page number */
+ len = ch_length();
+ if (len == NULL_POSITION || len == ch_zero() ||
+ (linenum = find_linenum(len)) <= 0)
+ ap_quest();
+ else
+ ap_linenum(((linenum - 1) / (sc_height - 1)) + 1);
+ break;
#if EDITOR
case 'E': /* Editor name */
ap_str(editor);
@@ -229,27 +293,38 @@ protochar(c, where)
ap_str(get_filename(curr_ifile));
break;
case 'i': /* Index into list of files */
- ap_int(get_index(curr_ifile));
+#if TAGS
+ if (ntags())
+ ap_int(curr_tag());
+ else
+#endif
+ ap_int(get_index(curr_ifile));
break;
case 'l': /* Current line number */
- n = currline(where);
- if (n != 0)
- ap_int(n);
+ linenum = currline(where);
+ if (linenum != 0)
+ ap_linenum(linenum);
else
ap_quest();
break;
case 'L': /* Final line number */
len = ch_length();
if (len == NULL_POSITION || len == ch_zero() ||
- (n = find_linenum(len)) <= 0)
+ (linenum = find_linenum(len)) <= 0)
ap_quest();
else
- ap_int(n-1);
+ ap_linenum(linenum-1);
break;
case 'm': /* Number of files */
- ap_int(nifile());
+#if TAGS
+ n = ntags();
+ if (n)
+ ap_int(n);
+ else
+#endif
+ ap_int(nifile());
break;
- case 'p': /* Percent into file */
+ case 'p': /* Percent into file (bytes) */
pos = curr_byte(where);
len = ch_length();
if (pos != NULL_POSITION && len > 0)
@@ -257,6 +332,15 @@ protochar(c, where)
else
ap_quest();
break;
+ case 'P': /* Percent into file (lines) */
+ linenum = currline(where);
+ if (linenum == 0 ||
+ (len = ch_length()) == NULL_POSITION || len == ch_zero() ||
+ (last_linenum = find_linenum(len)) <= 0)
+ ap_quest();
+ else
+ ap_int(percentage(linenum, last_linenum));
+ break;
case 's': /* Size of file */
case 'B':
len = ch_length();
@@ -269,6 +353,14 @@ protochar(c, where)
while (mp > message && mp[-1] == ' ')
mp--;
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 */
h = next_ifile(curr_ifile);
if (h != NULL_IFILE)
@@ -288,9 +380,9 @@ protochar(c, where)
*/
static char *
skipcond(p)
- char *p;
+ register char *p;
{
- int iflevel;
+ register int iflevel;
/*
* We came in here after processing a ? or :,
@@ -341,6 +433,9 @@ skipcond(p)
/*NOTREACHED*/
}
+/*
+ * Decode a char that represents a position on the screen.
+ */
static char *
wherechar(p, wp)
char *p;
@@ -348,7 +443,7 @@ wherechar(p, wp)
{
switch (*p)
{
- case 'b': case 'l': case 'p':
+ case 'b': case 'd': case 'l': case 'p': case 'P':
switch (*++p)
{
case 't': *wp = TOP; break;
@@ -370,8 +465,8 @@ pr_expand(proto, maxwidth)
char *proto;
int maxwidth;
{
- char *p;
- int c;
+ register char *p;
+ register int c;
int where;
mp = message;
@@ -384,17 +479,18 @@ pr_expand(proto, maxwidth)
switch (*p)
{
default: /* Just put the character in the message */
- *mp++ = *p;
+ ap_char(*p);
break;
case '\\': /* Backslash escapes the next character */
p++;
- *mp++ = *p;
+ ap_char(*p);
break;
case '?': /* Conditional (IF) */
if ((c = *++p) == '\0')
--p;
else
{
+ where = 0;
p = wherechar(p, &where);
if (!cond(c, where))
p = skipcond(p);
@@ -410,17 +506,22 @@ pr_expand(proto, maxwidth)
--p;
else
{
+ where = 0;
p = wherechar(p, &where);
- protochar(c, where);
+ protochar(c, where,
+#if EDITOR
+ (proto == editproto));
+#else
+ 0);
+#endif
+
}
break;
}
}
- new_file = 0;
if (mp == message)
return (NULL);
- *mp = '\0';
if (maxwidth > 0 && mp >= message + maxwidth)
{
/*
@@ -450,5 +551,20 @@ eq_message()
public char *
pr_string()
{
- 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));
}