1e3b7954bSetheisen /*
226ad794dSshadchin * Copyright (C) 1984-2012 Mark Nudelman
3b8c1323eSnicm * Modified for use with illumos by Garrett D'Amore.
4b8c1323eSnicm * Copyright 2014 Garrett D'Amore <garrett@damore.org>
5e3b7954bSetheisen *
645076018Smillert * You may distribute under the terms of either the GNU General Public
745076018Smillert * License or the Less License, as specified in the README file.
8e3b7954bSetheisen *
926ad794dSshadchin * For more information, see the README file.
10e3b7954bSetheisen */
11e3b7954bSetheisen
12e3b7954bSetheisen /*
13e3b7954bSetheisen * Prompting and other messages.
14e3b7954bSetheisen * There are three flavors of prompts, SHORT, MEDIUM and LONG,
15e3b7954bSetheisen * selected by the -m/-M options.
16e3b7954bSetheisen * There is also the "equals message", printed by the = command.
17e3b7954bSetheisen * A prompt is a message composed of various pieces, such as the
18e3b7954bSetheisen * name of the file being viewed, the percentage into the file, etc.
19e3b7954bSetheisen */
20e3b7954bSetheisen
21e3b7954bSetheisen #include "less.h"
22e3b7954bSetheisen #include "position.h"
23e3b7954bSetheisen
24e3b7954bSetheisen extern int pr_type;
25e3b7954bSetheisen extern int new_file;
26e3b7954bSetheisen extern int sc_width;
27e3b7954bSetheisen extern int so_s_width, so_e_width;
28e3b7954bSetheisen extern int linenums;
2945076018Smillert extern int hshift;
30e3b7954bSetheisen extern int sc_height;
31e3b7954bSetheisen extern int jump_sline;
32168565f4Sshadchin extern int less_is_more;
33e3b7954bSetheisen extern IFILE curr_ifile;
34e3b7954bSetheisen extern char *editor;
3545076018Smillert extern char *editproto;
36e3b7954bSetheisen
37e3b7954bSetheisen /*
38e3b7954bSetheisen * Prototypes for the three flavors of prompts.
39e3b7954bSetheisen * These strings are expanded by pr_expand().
40e3b7954bSetheisen */
41171bb95eSnicm static const char s_proto[] =
4245076018Smillert "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t";
43171bb95eSnicm static const char m_proto[] =
44171bb95eSnicm "?n?f%f .?m(%T %i of %m) ..?e(END) "
45171bb95eSnicm "?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t";
46171bb95eSnicm static const char M_proto[] =
47171bb95eSnicm "?f%f .?n?m(%T %i of %m) ..?"
48171bb95eSnicm "ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END)"
49171bb95eSnicm " ?x- Next\\: %x.:?pB%pB\\%..%t";
50171bb95eSnicm static const char e_proto[] =
51171bb95eSnicm "?f%f .?m(%T %i of %m) .?ltlines "
52171bb95eSnicm "%lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t";
53171bb95eSnicm static const char h_proto[] =
54171bb95eSnicm "HELP -- ?eEND -- Press g to see it again:"
55171bb95eSnicm "Press RETURN for more., or q when done";
56171bb95eSnicm static const char w_proto[] =
5745076018Smillert "Waiting for data";
58171bb95eSnicm static const char more_proto[] =
59171bb95eSnicm "%f (?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)";
60171bb95eSnicm static const char more_M_proto[] =
61171bb95eSnicm "%f (?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)"
62171bb95eSnicm "[Press space to continue, q to quit, h for help]";
63e3b7954bSetheisen
64171bb95eSnicm char *prproto[3];
65171bb95eSnicm char const *eqproto = e_proto;
66171bb95eSnicm char const *hproto = h_proto;
67171bb95eSnicm char const *wproto = w_proto;
68e3b7954bSetheisen
6945076018Smillert static char message[PROMPT_SIZE];
70e3b7954bSetheisen static char *mp;
71e3b7954bSetheisen
72e3b7954bSetheisen /*
73e3b7954bSetheisen * Initialize the prompt prototype strings.
74e3b7954bSetheisen */
75171bb95eSnicm void
init_prompt(void)76171bb95eSnicm init_prompt(void)
77e3b7954bSetheisen {
7809370fe9Stedu prproto[0] = estrdup(s_proto);
7909370fe9Stedu prproto[1] = estrdup(less_is_more ? more_proto : m_proto);
8009370fe9Stedu prproto[2] = estrdup(less_is_more ? more_M_proto : M_proto);
8109370fe9Stedu eqproto = estrdup(e_proto);
8209370fe9Stedu hproto = estrdup(h_proto);
8309370fe9Stedu wproto = estrdup(w_proto);
84e3b7954bSetheisen }
85e3b7954bSetheisen
86e3b7954bSetheisen /*
87e3b7954bSetheisen * Append a string to the end of the message.
88e3b7954bSetheisen */
89e3b7954bSetheisen static void
ap_str(char * s)90171bb95eSnicm ap_str(char *s)
91e3b7954bSetheisen {
9245076018Smillert int len;
9345076018Smillert
9445076018Smillert len = strlen(s);
9545076018Smillert if (mp + len >= message + PROMPT_SIZE)
9645076018Smillert len = message + PROMPT_SIZE - mp - 1;
97171bb95eSnicm (void) strncpy(mp, s, len);
9845076018Smillert mp += len;
9945076018Smillert *mp = '\0';
10045076018Smillert }
10145076018Smillert
10245076018Smillert /*
10345076018Smillert * Append a character to the end of the message.
10445076018Smillert */
10545076018Smillert static void
ap_char(char c)106171bb95eSnicm ap_char(char c)
10745076018Smillert {
10845076018Smillert char buf[2];
10945076018Smillert
11045076018Smillert buf[0] = c;
11145076018Smillert buf[1] = '\0';
11245076018Smillert ap_str(buf);
11345076018Smillert }
11445076018Smillert
11545076018Smillert /*
116171bb95eSnicm * Append a off_t (as a decimal integer) to the end of the message.
11745076018Smillert */
11845076018Smillert static void
ap_pos(off_t pos)119171bb95eSnicm ap_pos(off_t pos)
12045076018Smillert {
121*5d322bd6Smmcc char buf[23];
12245076018Smillert
1234ee32741Smmcc postoa(pos, buf, sizeof(buf));
12445076018Smillert ap_str(buf);
12545076018Smillert }
12645076018Smillert
12745076018Smillert /*
12845076018Smillert * Append an integer to the end of the message.
12945076018Smillert */
13045076018Smillert static void
ap_int(int num)131171bb95eSnicm ap_int(int num)
13245076018Smillert {
133*5d322bd6Smmcc char buf[13];
13445076018Smillert
135171bb95eSnicm inttoa(num, buf, sizeof buf);
13645076018Smillert ap_str(buf);
137e3b7954bSetheisen }
138e3b7954bSetheisen
139e3b7954bSetheisen /*
140e3b7954bSetheisen * Append a question mark to the end of the message.
141e3b7954bSetheisen */
142e3b7954bSetheisen static void
ap_quest(void)143171bb95eSnicm ap_quest(void)
144e3b7954bSetheisen {
14545076018Smillert ap_str("?");
146e3b7954bSetheisen }
147e3b7954bSetheisen
148e3b7954bSetheisen /*
149e3b7954bSetheisen * Return the "current" byte offset in the file.
150e3b7954bSetheisen */
151171bb95eSnicm static off_t
curr_byte(int where)152171bb95eSnicm curr_byte(int where)
153e3b7954bSetheisen {
154171bb95eSnicm off_t pos;
155e3b7954bSetheisen
156e3b7954bSetheisen pos = position(where);
157171bb95eSnicm while (pos == -1 && where >= 0 && where < sc_height-1)
158e3b7954bSetheisen pos = position(++where);
159171bb95eSnicm if (pos == -1)
160e3b7954bSetheisen pos = ch_length();
161e3b7954bSetheisen return (pos);
162e3b7954bSetheisen }
163e3b7954bSetheisen
164e3b7954bSetheisen /*
165e3b7954bSetheisen * Return the value of a prototype conditional.
166e3b7954bSetheisen * A prototype string may include conditionals which consist of a
167e3b7954bSetheisen * question mark followed by a single letter.
168e3b7954bSetheisen * Here we decode that letter and return the appropriate boolean value.
169e3b7954bSetheisen */
170e3b7954bSetheisen static int
cond(char c,int where)171171bb95eSnicm cond(char c, int where)
172e3b7954bSetheisen {
173171bb95eSnicm off_t len;
17445076018Smillert
175171bb95eSnicm switch (c) {
176e3b7954bSetheisen case 'a': /* Anything in the message yet? */
177b3fad75eSmmcc return (*message != '\0');
178e3b7954bSetheisen case 'b': /* Current byte offset known? */
179171bb95eSnicm return (curr_byte(where) != -1);
18045076018Smillert case 'c':
18145076018Smillert return (hshift != 0);
182e3b7954bSetheisen case 'e': /* At end of file? */
183168565f4Sshadchin return (eof_displayed());
184e3b7954bSetheisen case 'f': /* Filename known? */
185e3b7954bSetheisen return (strcmp(get_filename(curr_ifile), "-") != 0);
186e3b7954bSetheisen case 'l': /* Line number known? */
18745076018Smillert case 'd': /* Same as l */
188e3b7954bSetheisen return (linenums);
189e3b7954bSetheisen case 'L': /* Final line number known? */
190168565f4Sshadchin case 'D': /* Final page number known? */
191171bb95eSnicm return (linenums && ch_length() != -1);
192e3b7954bSetheisen case 'm': /* More than one file? */
19345076018Smillert return (ntags() ? (ntags() > 1) : (nifile() > 1));
194e3b7954bSetheisen case 'n': /* First prompt in a new file? */
19545076018Smillert return (ntags() ? 1 : new_file);
19645076018Smillert case 'p': /* Percent into file (bytes) known? */
197171bb95eSnicm return (curr_byte(where) != -1 && ch_length() > 0);
19845076018Smillert case 'P': /* Percent into file (lines) known? */
19945076018Smillert return (currline(where) != 0 &&
200171bb95eSnicm (len = ch_length()) > 0 && find_linenum(len) != 0);
201e3b7954bSetheisen case 's': /* Size of file known? */
202e3b7954bSetheisen case 'B':
203171bb95eSnicm return (ch_length() != -1);
204e3b7954bSetheisen case 'x': /* Is there a "next" file? */
20545076018Smillert if (ntags())
20645076018Smillert return (0);
207a030e442Sderaadt return (next_ifile(curr_ifile) != NULL);
208e3b7954bSetheisen }
209e3b7954bSetheisen return (0);
210e3b7954bSetheisen }
211e3b7954bSetheisen
212e3b7954bSetheisen /*
213e3b7954bSetheisen * Decode a "percent" prototype character.
214e3b7954bSetheisen * A prototype string may include various "percent" escapes;
215e3b7954bSetheisen * that is, a percent sign followed by a single letter.
216e3b7954bSetheisen * Here we decode that letter and take the appropriate action,
217e3b7954bSetheisen * usually by appending something to the message being built.
218e3b7954bSetheisen */
219e3b7954bSetheisen static void
protochar(int c,int where)220171bb95eSnicm protochar(int c, int where)
221e3b7954bSetheisen {
222171bb95eSnicm off_t pos;
223171bb95eSnicm off_t len;
224e3b7954bSetheisen int n;
2252a69c85bSmmcc off_t linenum;
2262a69c85bSmmcc off_t last_linenum;
227e3b7954bSetheisen IFILE h;
228e3b7954bSetheisen
229168565f4Sshadchin #undef PAGE_NUM
230168565f4Sshadchin #define PAGE_NUM(linenum) ((((linenum) - 1) / (sc_height - 1)) + 1)
231168565f4Sshadchin
232171bb95eSnicm switch (c) {
233e3b7954bSetheisen case 'b': /* Current byte offset */
234e3b7954bSetheisen pos = curr_byte(where);
235171bb95eSnicm if (pos != -1)
236e3b7954bSetheisen ap_pos(pos);
237e3b7954bSetheisen else
238e3b7954bSetheisen ap_quest();
239e3b7954bSetheisen break;
24045076018Smillert case 'c':
24145076018Smillert ap_int(hshift);
24245076018Smillert break;
24345076018Smillert case 'd': /* Current page number */
24445076018Smillert linenum = currline(where);
24545076018Smillert if (linenum > 0 && sc_height > 1)
2464ee32741Smmcc ap_pos(PAGE_NUM(linenum));
24745076018Smillert else
24845076018Smillert ap_quest();
24945076018Smillert break;
250168565f4Sshadchin case 'D': /* Final page number */
251168565f4Sshadchin /* Find the page number of the last byte in the file (len-1). */
25245076018Smillert len = ch_length();
253171bb95eSnicm if (len == -1) {
254168565f4Sshadchin ap_quest();
255171bb95eSnicm } else if (len == 0) {
256168565f4Sshadchin /* An empty file has no pages. */
2574ee32741Smmcc ap_pos(0);
258171bb95eSnicm } else {
259168565f4Sshadchin linenum = find_linenum(len - 1);
260168565f4Sshadchin if (linenum <= 0)
26145076018Smillert ap_quest();
26245076018Smillert else
2634ee32741Smmcc ap_pos(PAGE_NUM(linenum));
264168565f4Sshadchin }
26545076018Smillert break;
266e3b7954bSetheisen case 'E': /* Editor name */
267e3b7954bSetheisen ap_str(editor);
268e3b7954bSetheisen break;
269e3b7954bSetheisen case 'f': /* File name */
270e3b7954bSetheisen ap_str(get_filename(curr_ifile));
271e3b7954bSetheisen break;
272168565f4Sshadchin case 'F': /* Last component of file name */
273168565f4Sshadchin ap_str(last_component(get_filename(curr_ifile)));
274168565f4Sshadchin break;
275e3b7954bSetheisen case 'i': /* Index into list of files */
27645076018Smillert if (ntags())
27745076018Smillert ap_int(curr_tag());
27845076018Smillert else
279e3b7954bSetheisen ap_int(get_index(curr_ifile));
280e3b7954bSetheisen break;
281e3b7954bSetheisen case 'l': /* Current line number */
28245076018Smillert linenum = currline(where);
28345076018Smillert if (linenum != 0)
2844ee32741Smmcc ap_pos(linenum);
285e3b7954bSetheisen else
286e3b7954bSetheisen ap_quest();
287e3b7954bSetheisen break;
288e3b7954bSetheisen case 'L': /* Final line number */
289e3b7954bSetheisen len = ch_length();
290171bb95eSnicm if (len == -1 || len == ch_zero() ||
29145076018Smillert (linenum = find_linenum(len)) <= 0)
292e3b7954bSetheisen ap_quest();
293e3b7954bSetheisen else
2944ee32741Smmcc ap_pos(linenum-1);
295e3b7954bSetheisen break;
296e3b7954bSetheisen case 'm': /* Number of files */
29745076018Smillert n = ntags();
29845076018Smillert if (n)
29945076018Smillert ap_int(n);
30045076018Smillert else
301e3b7954bSetheisen ap_int(nifile());
302e3b7954bSetheisen break;
30345076018Smillert case 'p': /* Percent into file (bytes) */
304e3b7954bSetheisen pos = curr_byte(where);
305e3b7954bSetheisen len = ch_length();
306171bb95eSnicm if (pos != -1 && len > 0)
307e3b7954bSetheisen ap_int(percentage(pos, len));
308e3b7954bSetheisen else
309e3b7954bSetheisen ap_quest();
310e3b7954bSetheisen break;
31145076018Smillert case 'P': /* Percent into file (lines) */
31245076018Smillert linenum = currline(where);
31345076018Smillert if (linenum == 0 ||
314171bb95eSnicm (len = ch_length()) == -1 || len == ch_zero() ||
31545076018Smillert (last_linenum = find_linenum(len)) <= 0)
31645076018Smillert ap_quest();
31745076018Smillert else
31845076018Smillert ap_int(percentage(linenum, last_linenum));
31945076018Smillert break;
320e3b7954bSetheisen case 's': /* Size of file */
321e3b7954bSetheisen case 'B':
322e3b7954bSetheisen len = ch_length();
323171bb95eSnicm if (len != -1)
324e3b7954bSetheisen ap_pos(len);
325e3b7954bSetheisen else
326e3b7954bSetheisen ap_quest();
327e3b7954bSetheisen break;
328e3b7954bSetheisen case 't': /* Truncate trailing spaces in the message */
329e3b7954bSetheisen while (mp > message && mp[-1] == ' ')
330e3b7954bSetheisen mp--;
3310bb67be8Sjasper *mp = '\0';
332e3b7954bSetheisen break;
33345076018Smillert case 'T': /* Type of list */
33445076018Smillert if (ntags())
33545076018Smillert ap_str("tag");
33645076018Smillert else
33745076018Smillert ap_str("file");
33845076018Smillert break;
339e3b7954bSetheisen case 'x': /* Name of next file */
340e3b7954bSetheisen h = next_ifile(curr_ifile);
341a030e442Sderaadt if (h != NULL)
342e3b7954bSetheisen ap_str(get_filename(h));
343e3b7954bSetheisen else
344e3b7954bSetheisen ap_quest();
345e3b7954bSetheisen break;
346e3b7954bSetheisen }
347e3b7954bSetheisen }
348e3b7954bSetheisen
349e3b7954bSetheisen /*
350e3b7954bSetheisen * Skip a false conditional.
351e3b7954bSetheisen * When a false condition is found (either a false IF or the ELSE part
352e3b7954bSetheisen * of a true IF), this routine scans the prototype string to decide
353e3b7954bSetheisen * where to resume parsing the string.
354e3b7954bSetheisen * We must keep track of nested IFs and skip them properly.
355e3b7954bSetheisen */
356171bb95eSnicm static const char *
skipcond(const char * p)357171bb95eSnicm skipcond(const char *p)
358e3b7954bSetheisen {
359171bb95eSnicm int iflevel;
360e3b7954bSetheisen
361e3b7954bSetheisen /*
362e3b7954bSetheisen * We came in here after processing a ? or :,
363e3b7954bSetheisen * so we start nested one level deep.
364e3b7954bSetheisen */
365e3b7954bSetheisen iflevel = 1;
366e3b7954bSetheisen
367171bb95eSnicm for (;;) {
368171bb95eSnicm switch (*++p) {
369e3b7954bSetheisen case '?':
370e3b7954bSetheisen /*
371e3b7954bSetheisen * Start of a nested IF.
372e3b7954bSetheisen */
373e3b7954bSetheisen iflevel++;
374e3b7954bSetheisen break;
375e3b7954bSetheisen case ':':
376e3b7954bSetheisen /*
377e3b7954bSetheisen * Else.
378e3b7954bSetheisen * If this matches the IF we came in here with,
379e3b7954bSetheisen * then we're done.
380e3b7954bSetheisen */
381e3b7954bSetheisen if (iflevel == 1)
382e3b7954bSetheisen return (p);
383e3b7954bSetheisen break;
384e3b7954bSetheisen case '.':
385e3b7954bSetheisen /*
386e3b7954bSetheisen * Endif.
387e3b7954bSetheisen * If this matches the IF we came in here with,
388e3b7954bSetheisen * then we're done.
389e3b7954bSetheisen */
390e3b7954bSetheisen if (--iflevel == 0)
391e3b7954bSetheisen return (p);
392e3b7954bSetheisen break;
393e3b7954bSetheisen case '\\':
394e3b7954bSetheisen /*
395e3b7954bSetheisen * Backslash escapes the next character.
396e3b7954bSetheisen */
397e3b7954bSetheisen ++p;
398e3b7954bSetheisen break;
399e3b7954bSetheisen case '\0':
400e3b7954bSetheisen /*
401e3b7954bSetheisen * Whoops. Hit end of string.
402e3b7954bSetheisen * This is a malformed conditional, but just treat it
403e3b7954bSetheisen * as if all active conditionals ends here.
404e3b7954bSetheisen */
405e3b7954bSetheisen return (p-1);
406e3b7954bSetheisen }
407171bb95eSnicm }
408e3b7954bSetheisen }
409e3b7954bSetheisen
41045076018Smillert /*
41145076018Smillert * Decode a char that represents a position on the screen.
41245076018Smillert */
413171bb95eSnicm static const char *
wherechar(const char * p,int * wp)414171bb95eSnicm wherechar(const char *p, int *wp)
415e3b7954bSetheisen {
416171bb95eSnicm switch (*p) {
41745076018Smillert case 'b': case 'd': case 'l': case 'p': case 'P':
418171bb95eSnicm switch (*++p) {
419e3b7954bSetheisen case 't': *wp = TOP; break;
420e3b7954bSetheisen case 'm': *wp = MIDDLE; break;
421e3b7954bSetheisen case 'b': *wp = BOTTOM; break;
422e3b7954bSetheisen case 'B': *wp = BOTTOM_PLUS_ONE; break;
423e3b7954bSetheisen case 'j': *wp = adjsline(jump_sline); break;
424e3b7954bSetheisen default: *wp = TOP; p--; break;
425e3b7954bSetheisen }
426e3b7954bSetheisen }
427e3b7954bSetheisen return (p);
428e3b7954bSetheisen }
429e3b7954bSetheisen
430e3b7954bSetheisen /*
431e3b7954bSetheisen * Construct a message based on a prototype string.
432e3b7954bSetheisen */
433171bb95eSnicm char *
pr_expand(const char * proto,int maxwidth)434171bb95eSnicm pr_expand(const char *proto, int maxwidth)
435e3b7954bSetheisen {
436171bb95eSnicm const char *p;
437171bb95eSnicm int c;
438e3b7954bSetheisen int where;
439e3b7954bSetheisen
440e3b7954bSetheisen mp = message;
441e3b7954bSetheisen
442e3b7954bSetheisen if (*proto == '\0')
443e3b7954bSetheisen return ("");
444e3b7954bSetheisen
445171bb95eSnicm for (p = proto; *p != '\0'; p++) {
446171bb95eSnicm switch (*p) {
447e3b7954bSetheisen default: /* Just put the character in the message */
44845076018Smillert ap_char(*p);
449e3b7954bSetheisen break;
450e3b7954bSetheisen case '\\': /* Backslash escapes the next character */
451e3b7954bSetheisen p++;
45245076018Smillert ap_char(*p);
453e3b7954bSetheisen break;
454e3b7954bSetheisen case '?': /* Conditional (IF) */
455171bb95eSnicm if ((c = *++p) == '\0') {
456e3b7954bSetheisen --p;
457171bb95eSnicm } else {
45845076018Smillert where = 0;
459e3b7954bSetheisen p = wherechar(p, &where);
460e3b7954bSetheisen if (!cond(c, where))
461e3b7954bSetheisen p = skipcond(p);
462e3b7954bSetheisen }
463e3b7954bSetheisen break;
464e3b7954bSetheisen case ':': /* ELSE */
465e3b7954bSetheisen p = skipcond(p);
466e3b7954bSetheisen break;
467e3b7954bSetheisen case '.': /* ENDIF */
468e3b7954bSetheisen break;
469e3b7954bSetheisen case '%': /* Percent escape */
470171bb95eSnicm if ((c = *++p) == '\0') {
471e3b7954bSetheisen --p;
472171bb95eSnicm } else {
47345076018Smillert where = 0;
474e3b7954bSetheisen p = wherechar(p, &where);
475171bb95eSnicm protochar(c, where);
476e3b7954bSetheisen }
477e3b7954bSetheisen break;
478e3b7954bSetheisen }
479e3b7954bSetheisen }
480e3b7954bSetheisen
481b3fad75eSmmcc if (*message == '\0')
482168565f4Sshadchin return ("");
483171bb95eSnicm if (maxwidth > 0 && mp >= message + maxwidth) {
484e3b7954bSetheisen /*
485e3b7954bSetheisen * Message is too long.
486e3b7954bSetheisen * Return just the final portion of it.
487e3b7954bSetheisen */
488e3b7954bSetheisen return (mp - maxwidth);
489e3b7954bSetheisen }
490e3b7954bSetheisen return (message);
491e3b7954bSetheisen }
492e3b7954bSetheisen
493e3b7954bSetheisen /*
494e3b7954bSetheisen * Return a message suitable for printing by the "=" command.
495e3b7954bSetheisen */
496171bb95eSnicm char *
eq_message(void)497171bb95eSnicm eq_message(void)
498e3b7954bSetheisen {
499e3b7954bSetheisen return (pr_expand(eqproto, 0));
500e3b7954bSetheisen }
501e3b7954bSetheisen
502e3b7954bSetheisen /*
503e3b7954bSetheisen * Return a prompt.
504e3b7954bSetheisen * This depends on the prompt type (SHORT, MEDIUM, LONG), etc.
505e3b7954bSetheisen * If we can't come up with an appropriate prompt, return NULL
506e3b7954bSetheisen * and the caller will prompt with a colon.
507e3b7954bSetheisen */
508171bb95eSnicm char *
prompt_string(void)509171bb95eSnicm prompt_string(void)
510e3b7954bSetheisen {
51145076018Smillert char *prompt;
512168565f4Sshadchin int type;
51345076018Smillert
514171bb95eSnicm type = pr_type;
515168565f4Sshadchin prompt = pr_expand((ch_getflags() & CH_HELPFILE) ?
516171bb95eSnicm hproto : prproto[type], sc_width-so_s_width-so_e_width-2);
51745076018Smillert new_file = 0;
51845076018Smillert return (prompt);
51945076018Smillert }
52045076018Smillert
52145076018Smillert /*
52245076018Smillert * Return a message suitable for printing while waiting in the F command.
52345076018Smillert */
524171bb95eSnicm char *
wait_message(void)525171bb95eSnicm wait_message(void)
52645076018Smillert {
52745076018Smillert return (pr_expand(wproto, sc_width-so_s_width-so_e_width-2));
528e3b7954bSetheisen }
529