diff options
Diffstat (limited to 'format.c')
-rw-r--r-- | format.c | 323 |
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 | |||
36 | static 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) \ | ||
48 | do { \ | ||
49 | char *buf; \ | ||
50 | NV_VSNPRINTF(buf, fmt); \ | ||
51 | vformat(stream, wb, prefix, buf); \ | ||
52 | free (buf); \ | ||
53 | } while(0) | ||
54 | |||
55 | |||
56 | static 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 | |||
67 | void 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 | |||
90 | void 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 | |||
103 | void 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 | |||
116 | void 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 | |||
129 | void 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 | |||
152 | void format(FILE *stream, const char *prefix, const char *fmt, ...) | ||
153 | { | ||
154 | NV_VFORMAT(stream, TRUE, prefix, fmt); | ||
155 | |||
156 | } /* format() */ | ||
157 | |||
158 | |||
159 | |||
160 | static 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 | |||
195 | TextRows *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 | |||
314 | void 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() */ | ||