summaryrefslogtreecommitdiff
path: root/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'format.c')
-rw-r--r--format.c323
1 files changed, 0 insertions, 323 deletions
diff --git a/format.c b/format.c
deleted file mode 100644
index c67773e..0000000
--- a/format.c
+++ /dev/null
@@ -1,323 +0,0 @@
1/*
2 * nvidia-installer: A tool for installing NVIDIA software packages on
3 * Unix and Linux systems.
4 *
5 * Copyright (C) 2003 NVIDIA Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses>.
18 *
19 *
20 * format.c - this source file contains routines for formatting string
21 * output.
22 */
23
24
25#include <ctype.h>
26#include <stdio.h>
27#include <unistd.h>
28#include <sys/ioctl.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "nvidia-installer.h"
33#include "format.h"
34#include "misc.h"
35
36static unsigned short __terminal_width = 0;
37
38
39
40#define DEFAULT_WIDTH 75
41
42/*
43 * Format and display a printf style string such that it fits within
44 * the terminal width
45 */
46
47#define NV_VFORMAT(stream, wb, prefix, fmt) \
48do { \
49 char *buf; \
50 NV_VSNPRINTF(buf, fmt); \
51 vformat(stream, wb, prefix, buf); \
52 free (buf); \
53} while(0)
54
55
56static void vformat(FILE *stream, const int wb,
57 const char *prefix, const char *buf);
58
59
60/*
61 * reset_current_terminal_width() - if new_val is zero, then use the
62 * TIOCGWINSZ ioctl to get the current width of the terminal, and
63 * assign it the value to __terminal_width. If the ioctl fails, use a
64 * hardcoded constant. If new_val is non-zero, then use new_val.
65 */
66
67void reset_current_terminal_width(unsigned short new_val)
68{
69 struct winsize ws;
70
71 if (new_val) {
72 __terminal_width = new_val;
73 return;
74 }
75
76 if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
77 __terminal_width = DEFAULT_WIDTH;
78 } else {
79 __terminal_width = ws.ws_col - 1;
80 }
81} /* get_current_terminal_width() */
82
83
84
85/*
86 * fmtout() - stdout format function: prints the given string to
87 * stdout with no prefix.
88 */
89
90void fmtout(const char *fmt, ...)
91{
92 NV_VFORMAT(stdout, TRUE, NULL, fmt);
93
94} /* fmtout() */
95
96
97
98/*
99 * fmtoutp() - stdout format function with prefix: prints the given
100 * string to stdout with the given prefix.
101 */
102
103void fmtoutp(const char *prefix, const char *fmt, ...)
104{
105 NV_VFORMAT(stdout, TRUE, prefix, fmt);
106
107} /* fmtoutp() */
108
109
110
111/*
112 * fmterr() - stderr format function: prints the given string to
113 * stderr with no prefix.
114 */
115
116void fmterr(const char *fmt, ...)
117{
118 NV_VFORMAT(stderr, TRUE, NULL, fmt);
119
120} /* fmterr() */
121
122
123
124/*
125 * fmterrp() - stderr format function: prints the given string to
126 * stderr with the given prefix.
127 */
128
129void fmterrp(const char *prefix, const char *fmt, ...)
130{
131 NV_VFORMAT(stderr, TRUE, prefix, fmt);
132
133} /* fmterrp() */
134
135
136
137/*
138 * format() & vformat() - these takes a printf-style format string and
139 * a variable list of args. We use NV_VSNPRINTF to generate the
140 * desired string, and then call nv_format_text_rows() to format the
141 * string so that not more than __terminal_width characters are
142 * printed across.
143 *
144 * The resulting formatted output is written to the specified stream.
145 * The output may also include an optional prefix (to be prepended on
146 * the first line, and filled with spaces on subsequent lines.
147 *
148 * The wb argument indicates whether the line wrapping should only
149 * break on word boundaries.
150 */
151
152void format(FILE *stream, const char *prefix, const char *fmt, ...)
153{
154 NV_VFORMAT(stream, TRUE, prefix, fmt);
155
156} /* format() */
157
158
159
160static void vformat(FILE *stream, const int wb,
161 const char *prefix, const char *buf)
162{
163 int i;
164 TextRows *t;
165
166 if (!__terminal_width) reset_current_terminal_width(0);
167
168 t = nv_format_text_rows(prefix, buf, __terminal_width, wb);
169
170 for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]);
171
172 nv_free_text_rows(t);
173
174} /* vformat() */
175
176
177
178/*
179 * nv_format_text_rows() - this function breaks the given string str
180 * into some number of rows, where each row is not longer than the
181 * specified width.
182 *
183 * If prefix is non-NULL, the first line is prepended with the prefix,
184 * and subsequent lines are indented to line up with the prefix.
185 *
186 * If word_boundary is TRUE, then attempt to only break lines on
187 * boundaries between words.
188 *
189 * XXX Note that we don't use nvalloc() or any of the other wrapper
190 * functions from here, so that this function doesn't require any
191 * non-c library symbols (so that it can be called from dlopen()'ed
192 * user interfaces.
193 */
194
195TextRows *nv_format_text_rows(const char *prefix, const char *str,
196 int width, int word_boundary)
197{
198 int len, prefix_len, z, w, i;
199 char *line, *buf, *local_prefix, *a, *b, *c;
200 TextRows *t;
201
202 /* initialize the TextRows structure */
203
204 t = (TextRows *) malloc(sizeof(TextRows));
205 t->t = NULL;
206 t->n = 0;
207 t->m = 0;
208
209 if (!str) return t;
210
211 buf = strdup(str);
212
213 z = strlen(buf); /* length of entire string */
214 a = buf; /* pointer to the start of the string */
215
216 /* initialize the prefix fields */
217
218 if (prefix) {
219 prefix_len = strlen(prefix);
220 local_prefix = nvstrdup(prefix);
221 } else {
222 prefix_len = 0;
223 local_prefix = NULL;
224 }
225
226 /* adjust the max width for any prefix */
227
228 w = width - prefix_len;
229
230 do {
231 /*
232 * if the string will fit on one line, point b to the end of the
233 * string
234 */
235
236 if (z < w) b = a + z;
237
238 /*
239 * if the string won't fit on one line, move b to where the
240 * end of the line should be, and then move b back until we
241 * find a space; if we don't find a space before we back b all
242 * the way up to a, just assign b to where the line should end.
243 */
244
245 else {
246 b = a + w;
247
248 if (word_boundary) {
249 while ((b >= a) && (!isspace(*b))) b--;
250 if (b <= a) b = a + w;
251 }
252 }
253
254 /* look for any newline inbetween a and b, and move b to it */
255
256 for (c = a; c < b; c++) if (*c == '\n') { b = c; break; }
257
258 /*
259 * copy the string that starts at a and ends at b, prepending
260 * with a prefix, if present
261 */
262
263 len = b-a;
264 len += prefix_len;
265 line = (char *) malloc(len+1);
266 if (local_prefix) strncpy(line, local_prefix, prefix_len);
267 strncpy(line + prefix_len, a, len - prefix_len);
268 line[len] = '\0';
269
270 /* append the new line to the array of text rows */
271
272 t->t = (char **) realloc(t->t, sizeof(char *) * (t->n + 1));
273 t->t[t->n] = line;
274 t->n++;
275
276 if (t->m < len) t->m = len;
277
278 /*
279 * adjust the length of the string and move the pointer to the
280 * beginning of the new line
281 */
282
283 z -= (b - a + 1);
284 a = b + 1;
285
286 /* move to the first non whitespace character (excluding newlines) */
287
288 if (word_boundary && isspace(*b)) {
289 while ((z) && (isspace(*a)) && (*a != '\n')) a++, z--;
290 } else {
291 if (!isspace(*b)) z++, a--;
292 }
293
294 if (local_prefix) {
295 for (i = 0; i < prefix_len; i++) local_prefix[i] = ' ';
296 }
297
298 } while (z > 0);
299
300 if (local_prefix) free(local_prefix);
301 free(buf);
302
303 return t;
304
305} /* nv_format_text_rows() */
306
307
308
309/*
310 * nv_free_text_rows() - free the TextRows data structure allocated by
311 * nv_format_text_rows()
312 */
313
314void nv_free_text_rows(TextRows *t)
315{
316 int i;
317
318 if (!t) return;
319 for (i = 0; i < t->n; i++) free(t->t[i]);
320 if (t->t) free(t->t);
321 free(t);
322
323} /* nv_free_text_rows() */