2 * Copyright (C) 1984-2012 Mark Nudelman
3 * Modified for use with illumos by Garrett D'Amore.
4 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Less License, as specified in the README file.
9 * For more information, see the README file.
13 * High level routines dealing with the output to the screen.
18 int errmsgs
; /* Count of messages displayed by error() */
20 extern volatile sig_atomic_t sigs
;
22 extern int so_s_width
, so_e_width
;
23 extern int screen_trashed
;
24 extern int any_display
;
31 * Display the line which is in the line buffer.
42 * Don't output if a signal is pending.
48 for (i
= 0; (c
= gline(i
, &a
)) != '\0'; i
++) {
59 static char obuf
[OUTBUF_SIZE
];
60 static char *ob
= obuf
;
63 * Flush buffered output.
65 * If we haven't displayed any file data yet,
66 * output messages on error output (file descriptor 2),
67 * otherwise output on standard output (file descriptor 1).
69 * This has the desirable effect of producing all
70 * error messages on error output if standard output
71 * is directed to a file. It also does the same if
72 * we never produce any real output; for example, if
73 * the input file(s) cannot be opened. If we do
74 * eventually produce output, code in edit() makes
75 * sure these messages can be seen before they are
76 * overwritten or scrolled away.
79 flush(int ignore_errors
)
85 n
= (intptr_t)ob
- (intptr_t)obuf
;
89 fd
= (any_display
) ? STDOUT_FILENO
: STDERR_FILENO
;
90 nwritten
= write(fd
, obuf
, n
);
92 if (nwritten
== -1 && !ignore_errors
)
100 * Output a character.
110 * Some versions of flush() write to *ob, so we must flush
111 * when we are still one char from the end of obuf.
113 if (ob
>= &obuf
[sizeof (obuf
)-1])
123 putstr(const char *s
)
131 * Convert an integral type to a string.
133 #define TYPE_TO_A_FUNC(funcname, type) \
135 funcname(type num, char *buf, size_t len) \
137 int neg = (num < 0); \
139 char *s = tbuf + sizeof (tbuf); \
144 *--s = (num % 10) + '0'; \
145 } while ((num /= 10) != 0); \
148 (void) strlcpy(buf, s, len); \
151 TYPE_TO_A_FUNC(postoa
, off_t
)
152 TYPE_TO_A_FUNC(inttoa
, int)
155 * Output an integer in a given radix.
162 inttoa(num
, buf
, sizeof (buf
));
164 return (strlen(buf
));
168 * Output a line number in a given radix.
171 iprint_linenum(off_t num
)
175 postoa(num
, buf
, sizeof(buf
));
177 return (strlen(buf
));
181 * This function implements printf-like functionality
182 * using a more portable argument list mechanism than printf's.
185 less_printf(const char *fmt
, PARG
*parg
)
191 while (*fmt
!= '\0') {
193 (void) putchr(*fmt
++);
207 col
+= iprint_int(parg
->p_int
);
211 col
+= iprint_linenum(parg
->p_linenum
);
222 * If some other non-trivial char is pressed, unget it, so it will
223 * become the next command.
231 if (c
!= '\n' && c
!= '\r' && c
!= ' ' && c
!= READ_INTR
)
236 * Output a message in the lower left corner of the screen
237 * and wait for carriage return.
240 error(const char *fmt
, PARG
*parg
)
243 static char return_to_continue
[] = " (press RETURN)";
247 if (any_display
&& is_tty
) {
252 at_enter(AT_STANDOUT
);
256 col
+= less_printf(fmt
, parg
);
258 if (!(any_display
&& is_tty
)) {
263 putstr(return_to_continue
);
265 col
+= sizeof (return_to_continue
) + so_e_width
;
273 * Printing the message has probably scrolled the screen.
274 * {{ Unless the terminal doesn't have auto margins,
275 * in which case we just hammered on the right margin. }}
282 static char intr_to_abort
[] = "... (interrupt to abort)";
285 * Output a message in the lower left corner of the screen
286 * and don't wait for carriage return.
287 * Usually used to warn that we are beginning a potentially
288 * time-consuming operation.
291 ierror(const char *fmt
, PARG
*parg
)
295 at_enter(AT_STANDOUT
);
296 (void) less_printf(fmt
, parg
);
297 putstr(intr_to_abort
);
304 * Output a message in the lower left corner of the screen
305 * and return a single-character response.
308 query(const char *fmt
, PARG
*parg
)
313 if (any_display
&& is_tty
)
316 (void) less_printf(fmt
, parg
);
319 if (!(any_display
&& is_tty
)) {