tparm.c revision 1.7.2.3 1 1.7.2.3 yamt /* $NetBSD: tparm.c,v 1.7.2.3 2014/05/22 11:37:00 yamt Exp $ */
2 1.1 roy
3 1.1 roy /*
4 1.7.2.3 yamt * Copyright (c) 2009, 2011, 2013 The NetBSD Foundation, Inc.
5 1.1 roy *
6 1.1 roy * This code is derived from software contributed to The NetBSD Foundation
7 1.1 roy * by Roy Marples.
8 1.1 roy *
9 1.1 roy * Redistribution and use in source and binary forms, with or without
10 1.1 roy * modification, are permitted provided that the following conditions
11 1.1 roy * are met:
12 1.1 roy * 1. Redistributions of source code must retain the above copyright
13 1.1 roy * notice, this list of conditions and the following disclaimer.
14 1.1 roy * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 roy * notice, this list of conditions and the following disclaimer in the
16 1.1 roy * documentation and/or other materials provided with the distribution.
17 1.1 roy *
18 1.1 roy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 roy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 roy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 roy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 roy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.1 roy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 roy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 roy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 roy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.1 roy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 roy */
29 1.1 roy
30 1.1 roy #include <sys/cdefs.h>
31 1.7.2.3 yamt __RCSID("$NetBSD: tparm.c,v 1.7.2.3 2014/05/22 11:37:00 yamt Exp $");
32 1.7.2.1 yamt #include <sys/param.h>
33 1.1 roy
34 1.1 roy #include <assert.h>
35 1.1 roy #include <ctype.h>
36 1.1 roy #include <errno.h>
37 1.1 roy #include <stdarg.h>
38 1.1 roy #include <stdio.h>
39 1.1 roy #include <stdlib.h>
40 1.1 roy #include <string.h>
41 1.1 roy #include <term_private.h>
42 1.1 roy #include <term.h>
43 1.1 roy
44 1.7.2.3 yamt #define LONG_STR_MAX ((CHAR_BIT * sizeof(long)) / 3)
45 1.7.2.3 yamt #define BUFINC 128 /* Size to increament the terminal buffer by */
46 1.7.2.3 yamt
47 1.7.2.3 yamt #define VA_LONG_LONG 1
48 1.7.2.3 yamt #define VA_CHAR_INT 2
49 1.7.2.3 yamt //#define VA_CHAR_LONG 3 /* No need for this yet */
50 1.7.2.3 yamt
51 1.1 roy static TERMINAL *dumbterm; /* For non thread safe functions */
52 1.1 roy
53 1.2 roy typedef struct {
54 1.7.2.3 yamt long nums[20];
55 1.1 roy char *strings[20];
56 1.1 roy size_t offset;
57 1.1 roy } TPSTACK;
58 1.1 roy
59 1.2 roy typedef struct {
60 1.7.2.3 yamt long num;
61 1.1 roy char *string;
62 1.1 roy } TPVAR;
63 1.1 roy
64 1.1 roy static int
65 1.7.2.3 yamt push(long num, char *string, TPSTACK *stack)
66 1.1 roy {
67 1.7.2.2 yamt if (stack->offset >= sizeof(stack->nums)) {
68 1.1 roy errno = E2BIG;
69 1.1 roy return -1;
70 1.1 roy }
71 1.1 roy stack->nums[stack->offset] = num;
72 1.1 roy stack->strings[stack->offset] = string;
73 1.1 roy stack->offset++;
74 1.1 roy return 0;
75 1.1 roy }
76 1.1 roy
77 1.1 roy static int
78 1.7.2.3 yamt pop(long *num, char **string, TPSTACK *stack)
79 1.1 roy {
80 1.1 roy if (stack->offset == 0) {
81 1.5 roy if (num)
82 1.5 roy *num = 0;
83 1.5 roy if (string)
84 1.5 roy *string = NULL;
85 1.1 roy errno = E2BIG;
86 1.1 roy return -1;
87 1.1 roy }
88 1.1 roy stack->offset--;
89 1.1 roy if (num)
90 1.1 roy *num = stack->nums[stack->offset];
91 1.1 roy if (string)
92 1.1 roy *string = stack->strings[stack->offset];
93 1.1 roy return 0;
94 1.1 roy }
95 1.1 roy
96 1.1 roy static char *
97 1.1 roy checkbuf(TERMINAL *term, size_t len)
98 1.1 roy {
99 1.1 roy char *buf;
100 1.7.2.3 yamt
101 1.1 roy if (term->_bufpos + len >= term->_buflen) {
102 1.7.2.3 yamt len = term->_buflen + MAX(len, BUFINC);
103 1.1 roy buf = realloc(term->_buf, len);
104 1.1 roy if (buf == NULL)
105 1.7.2.1 yamt return NULL;
106 1.1 roy term->_buf = buf;
107 1.1 roy term->_buflen = len;
108 1.1 roy }
109 1.1 roy return term->_buf;
110 1.1 roy }
111 1.1 roy
112 1.1 roy static size_t
113 1.1 roy ochar(TERMINAL *term, int c)
114 1.1 roy {
115 1.1 roy if (c == 0)
116 1.1 roy c = 0200;
117 1.1 roy /* Check we have space and a terminator */
118 1.1 roy if (checkbuf(term, 2) == NULL)
119 1.1 roy return 0;
120 1.1 roy term->_buf[term->_bufpos++] = (char)c;
121 1.1 roy return 1;
122 1.1 roy }
123 1.1 roy
124 1.1 roy static size_t
125 1.7.2.3 yamt onum(TERMINAL *term, const char *fmt, int num, unsigned int len)
126 1.1 roy {
127 1.1 roy size_t l;
128 1.1 roy
129 1.7.2.3 yamt if (len < LONG_STR_MAX)
130 1.7.2.3 yamt len = LONG_STR_MAX;
131 1.7.2.3 yamt if (checkbuf(term, len + 2) == NULL)
132 1.1 roy return 0;
133 1.1 roy l = sprintf(term->_buf + term->_bufpos, fmt, num);
134 1.1 roy term->_bufpos += l;
135 1.1 roy return l;
136 1.1 roy }
137 1.1 roy
138 1.7.2.3 yamt /*
139 1.7.2.3 yamt Make a pass through the string so we can work out
140 1.7.2.3 yamt which parameters are ints and which are char *.
141 1.7.2.3 yamt Basically we only use char * if %p[1-9] is followed by %l or %s.
142 1.7.2.3 yamt */
143 1.7.2.3 yamt int
144 1.7.2.3 yamt _ti_parm_analyse(const char *str, int *piss, int piss_len)
145 1.7.2.3 yamt {
146 1.7.2.3 yamt int nparm, lpop;
147 1.7.2.3 yamt char c;
148 1.7.2.3 yamt
149 1.7.2.3 yamt nparm = 0;
150 1.7.2.3 yamt lpop = -1;
151 1.7.2.3 yamt while ((c = *str++) != '\0') {
152 1.7.2.3 yamt if (c != '%')
153 1.7.2.3 yamt continue;
154 1.7.2.3 yamt c = *str++;
155 1.7.2.3 yamt switch (c) {
156 1.7.2.3 yamt case 'l': /* FALLTHROUGH */
157 1.7.2.3 yamt case 's':
158 1.7.2.3 yamt if (lpop > 0) {
159 1.7.2.3 yamt if (lpop <= piss_len)
160 1.7.2.3 yamt piss[lpop - 1] = 1;
161 1.7.2.3 yamt else if (piss)
162 1.7.2.3 yamt errno = E2BIG;
163 1.7.2.3 yamt }
164 1.7.2.3 yamt break;
165 1.7.2.3 yamt case 'p':
166 1.7.2.3 yamt c = *str++;
167 1.7.2.3 yamt if (c < '1' || c > '9') {
168 1.7.2.3 yamt errno = EINVAL;
169 1.7.2.3 yamt continue;
170 1.7.2.3 yamt } else {
171 1.7.2.3 yamt lpop = c - '0';
172 1.7.2.3 yamt if (lpop > nparm)
173 1.7.2.3 yamt nparm = lpop;
174 1.7.2.3 yamt }
175 1.7.2.3 yamt break;
176 1.7.2.3 yamt default:
177 1.7.2.3 yamt lpop = -1;
178 1.7.2.3 yamt }
179 1.7.2.3 yamt }
180 1.7.2.3 yamt
181 1.7.2.3 yamt return nparm;
182 1.7.2.3 yamt }
183 1.7.2.3 yamt
184 1.1 roy static char *
185 1.7.2.3 yamt _ti_tiparm(TERMINAL *term, const char *str, int va_type, va_list parms)
186 1.1 roy {
187 1.1 roy char c, fmt[64], *fp, *ostr;
188 1.7.2.3 yamt long val, val2;
189 1.7.2.3 yamt long dnums[26]; /* dynamic variables a-z, not preserved */
190 1.1 roy size_t l, max;
191 1.1 roy TPSTACK stack;
192 1.7.2.3 yamt TPVAR params[TPARM_MAX];
193 1.7.2.3 yamt unsigned int done, dot, minus, width, precision, olen;
194 1.7.2.3 yamt int piss[TPARM_MAX]; /* Parameter IS String - piss ;) */
195 1.1 roy
196 1.1 roy if (str == NULL)
197 1.1 roy return NULL;
198 1.1 roy
199 1.1 roy /*
200 1.1 roy If not passed a terminal, malloc a dummy one.
201 1.1 roy This means we can preserve buffers and variables per terminal and
202 1.1 roy still work with non thread safe functions (which sadly are still the
203 1.1 roy norm and standard).
204 1.1 roy */
205 1.1 roy if (term == NULL) {
206 1.1 roy if (dumbterm == NULL) {
207 1.1 roy dumbterm = malloc(sizeof(*dumbterm));
208 1.1 roy if (dumbterm == NULL)
209 1.1 roy return NULL;
210 1.1 roy dumbterm->_buflen = 0;
211 1.1 roy }
212 1.1 roy term = dumbterm;
213 1.1 roy }
214 1.1 roy
215 1.1 roy term->_bufpos = 0;
216 1.1 roy /* Ensure we have an initial buffer */
217 1.1 roy if (term->_buflen == 0) {
218 1.7.2.3 yamt term->_buf = malloc(BUFINC);
219 1.1 roy if (term->_buf == NULL)
220 1.1 roy return NULL;
221 1.7.2.3 yamt term->_buflen = BUFINC;
222 1.1 roy }
223 1.1 roy
224 1.1 roy memset(&piss, 0, sizeof(piss));
225 1.7.2.3 yamt max = _ti_parm_analyse(str, piss, TPARM_MAX);
226 1.1 roy
227 1.1 roy /* Put our parameters into variables */
228 1.1 roy memset(¶ms, 0, sizeof(params));
229 1.1 roy for (l = 0; l < max; l++) {
230 1.7.2.3 yamt if (piss[l]) {
231 1.7.2.3 yamt if (va_type == VA_LONG_LONG) {
232 1.7.2.3 yamt /* This only works if char * fits into a long
233 1.7.2.3 yamt * on this platform. */
234 1.7.2.3 yamt if (sizeof(char *) <= sizeof(long)/*CONSTCOND*/)
235 1.7.2.3 yamt params[l].string =
236 1.7.2.3 yamt (char *)va_arg(parms, long);
237 1.7.2.3 yamt else {
238 1.7.2.3 yamt errno = ENOTSUP;
239 1.7.2.3 yamt return NULL;
240 1.7.2.3 yamt }
241 1.7.2.3 yamt } else
242 1.7.2.3 yamt params[l].string = va_arg(parms, char *);
243 1.7.2.3 yamt } else {
244 1.7.2.3 yamt if (va_type == VA_CHAR_INT)
245 1.7.2.3 yamt params[l].num = (long)va_arg(parms, int);
246 1.7.2.3 yamt else
247 1.7.2.3 yamt params[l].num = va_arg(parms, long);
248 1.7.2.3 yamt }
249 1.1 roy }
250 1.1 roy
251 1.1 roy memset(&stack, 0, sizeof(stack));
252 1.1 roy while ((c = *str++) != '\0') {
253 1.1 roy if (c != '%' || (c = *str++) == '%') {
254 1.1 roy if (c == '\0')
255 1.1 roy break;
256 1.1 roy if (ochar(term, c) == 0)
257 1.1 roy return NULL;
258 1.1 roy continue;
259 1.1 roy }
260 1.1 roy
261 1.1 roy /* Handle formatting. */
262 1.1 roy fp = fmt;
263 1.1 roy *fp++ = '%';
264 1.1 roy done = dot = minus = width = precision = 0;
265 1.1 roy val = 0;
266 1.1 roy while (done == 0 && (size_t)(fp - fmt) < sizeof(fmt)) {
267 1.1 roy switch (c) {
268 1.1 roy case 'c': /* FALLTHROUGH */
269 1.7.2.3 yamt case 's':
270 1.7.2.3 yamt *fp++ = c;
271 1.7.2.3 yamt done = 1;
272 1.7.2.3 yamt break;
273 1.1 roy case 'd': /* FALLTHROUGH */
274 1.1 roy case 'o': /* FALLTHROUGH */
275 1.1 roy case 'x': /* FALLTHROUGH */
276 1.1 roy case 'X': /* FALLTHROUGH */
277 1.7.2.3 yamt *fp++ = 'l';
278 1.1 roy *fp++ = c;
279 1.1 roy done = 1;
280 1.1 roy break;
281 1.1 roy case '#': /* FALLTHROUGH */
282 1.1 roy case ' ':
283 1.1 roy *fp++ = c;
284 1.1 roy break;
285 1.1 roy case '.':
286 1.1 roy *fp++ = c;
287 1.1 roy if (dot == 0) {
288 1.1 roy dot = 1;
289 1.1 roy width = val;
290 1.1 roy } else
291 1.1 roy done = 2;
292 1.1 roy val = 0;
293 1.1 roy break;
294 1.1 roy case ':':
295 1.1 roy minus = 1;
296 1.1 roy break;
297 1.1 roy case '-':
298 1.1 roy if (minus)
299 1.1 roy *fp++ = c;
300 1.1 roy else
301 1.1 roy done = 1;
302 1.1 roy break;
303 1.1 roy default:
304 1.1 roy if (isdigit((unsigned char)c)) {
305 1.1 roy val = (val * 10) + (c - '0');
306 1.1 roy if (val > 10000)
307 1.1 roy done = 2;
308 1.1 roy else
309 1.1 roy *fp++ = c;
310 1.1 roy } else
311 1.1 roy done = 1;
312 1.1 roy }
313 1.1 roy if (done == 0)
314 1.1 roy c = *str++;
315 1.1 roy }
316 1.1 roy if (done == 2) {
317 1.1 roy /* Found an error in the format */
318 1.1 roy fp = fmt + 1;
319 1.1 roy *fp = *str;
320 1.1 roy olen = 0;
321 1.1 roy } else {
322 1.1 roy if (dot == 0)
323 1.1 roy width = val;
324 1.1 roy else
325 1.1 roy precision = val;
326 1.7.2.3 yamt olen = MAX(width, precision);
327 1.1 roy }
328 1.1 roy *fp++ = '\0';
329 1.1 roy
330 1.1 roy /* Handle commands */
331 1.1 roy switch (c) {
332 1.1 roy case 'c':
333 1.5 roy pop(&val, NULL, &stack);
334 1.1 roy if (ochar(term, (unsigned char)val) == 0)
335 1.1 roy return NULL;
336 1.1 roy break;
337 1.1 roy case 's':
338 1.5 roy pop(NULL, &ostr, &stack);
339 1.1 roy if (ostr != NULL) {
340 1.1 roy l = strlen(ostr);
341 1.1 roy if (l < (size_t)olen)
342 1.1 roy l = olen;
343 1.1 roy if (checkbuf(term, (size_t)(l + 1)) == NULL)
344 1.1 roy return NULL;
345 1.1 roy l = sprintf(term->_buf + term->_bufpos,
346 1.1 roy fmt, ostr);
347 1.1 roy term->_bufpos += l;
348 1.1 roy }
349 1.1 roy break;
350 1.1 roy case 'l':
351 1.5 roy pop(NULL, &ostr, &stack);
352 1.1 roy if (ostr == NULL)
353 1.1 roy l = 0;
354 1.1 roy else
355 1.1 roy l = strlen(ostr);
356 1.7.2.3 yamt #ifdef NCURSES_COMPAT_57
357 1.7.2.3 yamt if (onum(term, "%ld", (long)l, 0) == 0)
358 1.1 roy return NULL;
359 1.7.2.3 yamt #else
360 1.7.2.3 yamt push((long)l, NULL, &stack);
361 1.7.2.3 yamt #endif
362 1.1 roy break;
363 1.1 roy case 'd': /* FALLTHROUGH */
364 1.1 roy case 'o': /* FALLTHROUGH */
365 1.1 roy case 'x': /* FALLTHROUGH */
366 1.1 roy case 'X':
367 1.5 roy pop(&val, NULL, &stack);
368 1.7.2.3 yamt if (onum(term, fmt, (int)val, olen) == 0)
369 1.1 roy return NULL;
370 1.1 roy break;
371 1.1 roy case 'p':
372 1.5 roy if (*str < '1' || *str > '9')
373 1.5 roy break;
374 1.1 roy l = *str++ - '1';
375 1.1 roy if (push(params[l].num, params[l].string, &stack))
376 1.1 roy return NULL;
377 1.1 roy break;
378 1.1 roy case 'P':
379 1.5 roy pop(&val, NULL, &stack);
380 1.1 roy if (*str >= 'a' && *str <= 'z')
381 1.1 roy dnums[*str - 'a'] = val;
382 1.1 roy else if (*str >= 'A' && *str <= 'Z')
383 1.1 roy term->_snums[*str - 'A'] = val;
384 1.1 roy break;
385 1.1 roy case 'g':
386 1.1 roy if (*str >= 'a' && *str <= 'z') {
387 1.1 roy if (push(dnums[*str - 'a'], NULL, &stack))
388 1.1 roy return NULL;
389 1.1 roy } else if (*str >= 'A' && *str <= 'Z') {
390 1.1 roy if (push(term->_snums[*str - 'A'],
391 1.1 roy NULL, &stack))
392 1.1 roy return NULL;
393 1.1 roy }
394 1.1 roy break;
395 1.1 roy case 'i':
396 1.1 roy if (piss[0] == 0)
397 1.1 roy params[0].num++;
398 1.1 roy if (piss[1] == 0)
399 1.1 roy params[1].num++;
400 1.1 roy break;
401 1.1 roy case '\'':
402 1.7.2.3 yamt if (push((long)(unsigned char)*str++, NULL, &stack))
403 1.1 roy return NULL;
404 1.1 roy while (*str != '\0' && *str != '\'')
405 1.1 roy str++;
406 1.1 roy if (*str == '\'')
407 1.1 roy str++;
408 1.1 roy break;
409 1.1 roy case '{':
410 1.1 roy val = 0;
411 1.3 roy for (; isdigit((unsigned char)*str); str++)
412 1.1 roy val = (val * 10) + (*str - '0');
413 1.1 roy if (push(val, NULL, &stack))
414 1.1 roy return NULL;
415 1.1 roy while (*str != '\0' && *str != '}')
416 1.1 roy str++;
417 1.1 roy if (*str == '}')
418 1.1 roy str++;
419 1.1 roy break;
420 1.1 roy case '+': /* FALLTHROUGH */
421 1.1 roy case '-': /* FALLTHROUGH */
422 1.1 roy case '*': /* FALLTHROUGH */
423 1.1 roy case '/': /* FALLTHROUGH */
424 1.1 roy case 'm': /* FALLTHROUGH */
425 1.1 roy case 'A': /* FALLTHROUGH */
426 1.1 roy case 'O': /* FALLTHROUGH */
427 1.1 roy case '&': /* FALLTHROUGH */
428 1.1 roy case '|': /* FALLTHROUGH */
429 1.1 roy case '^': /* FALLTHROUGH */
430 1.1 roy case '=': /* FALLTHROUGH */
431 1.1 roy case '<': /* FALLTHROUGH */
432 1.1 roy case '>':
433 1.5 roy pop(&val, NULL, &stack);
434 1.5 roy pop(&val2, NULL, &stack);
435 1.1 roy switch (c) {
436 1.1 roy case '+':
437 1.1 roy val = val + val2;
438 1.1 roy break;
439 1.1 roy case '-':
440 1.1 roy val = val2 - val;
441 1.1 roy break;
442 1.1 roy case '*':
443 1.1 roy val = val * val2;
444 1.1 roy break;
445 1.1 roy case '/':
446 1.1 roy val = val ? val2 / val : 0;
447 1.1 roy break;
448 1.1 roy case 'm':
449 1.1 roy val = val ? val2 % val : 0;
450 1.1 roy break;
451 1.1 roy case 'A':
452 1.1 roy val = val && val2;
453 1.1 roy break;
454 1.1 roy case 'O':
455 1.1 roy val = val || val2;
456 1.1 roy break;
457 1.1 roy case '&':
458 1.1 roy val = val & val2;
459 1.1 roy break;
460 1.1 roy case '|':
461 1.1 roy val = val | val2;
462 1.1 roy break;
463 1.1 roy case '^':
464 1.1 roy val = val ^ val2;
465 1.1 roy break;
466 1.1 roy case '=':
467 1.1 roy val = val == val2;
468 1.1 roy break;
469 1.1 roy case '<':
470 1.1 roy val = val2 < val;
471 1.1 roy break;
472 1.1 roy case '>':
473 1.1 roy val = val2 > val;
474 1.1 roy break;
475 1.1 roy }
476 1.1 roy if (push(val, NULL, &stack))
477 1.1 roy return NULL;
478 1.1 roy break;
479 1.1 roy case '!':
480 1.1 roy case '~':
481 1.5 roy pop(&val, NULL, &stack);
482 1.7.2.3 yamt switch (c) {
483 1.1 roy case '!':
484 1.1 roy val = !val;
485 1.1 roy break;
486 1.1 roy case '~':
487 1.1 roy val = ~val;
488 1.1 roy break;
489 1.1 roy }
490 1.1 roy if (push(val, NULL, &stack))
491 1.1 roy return NULL;
492 1.1 roy break;
493 1.1 roy case '?': /* if */
494 1.1 roy break;
495 1.1 roy case 't': /* then */
496 1.5 roy pop(&val, NULL, &stack);
497 1.7.2.3 yamt if (val == 0) {
498 1.1 roy l = 0;
499 1.1 roy for (; *str != '\0'; str++) {
500 1.1 roy if (*str != '%')
501 1.1 roy continue;
502 1.1 roy str++;
503 1.1 roy if (*str == '?')
504 1.1 roy l++;
505 1.1 roy else if (*str == ';') {
506 1.1 roy if (l > 0)
507 1.1 roy l--;
508 1.7.2.3 yamt else {
509 1.7.2.3 yamt str++;
510 1.1 roy break;
511 1.7.2.3 yamt }
512 1.7.2.3 yamt } else if (*str == 'e' && l == 0) {
513 1.7.2.3 yamt str++;
514 1.1 roy break;
515 1.7.2.3 yamt }
516 1.1 roy }
517 1.1 roy }
518 1.1 roy break;
519 1.1 roy case 'e': /* else */
520 1.1 roy l = 0;
521 1.1 roy for (; *str != '\0'; str++) {
522 1.1 roy if (*str != '%')
523 1.1 roy continue;
524 1.1 roy str++;
525 1.1 roy if (*str == '?')
526 1.1 roy l++;
527 1.1 roy else if (*str == ';') {
528 1.1 roy if (l > 0)
529 1.1 roy l--;
530 1.7.2.3 yamt else {
531 1.7.2.3 yamt str++;
532 1.1 roy break;
533 1.7.2.3 yamt }
534 1.1 roy }
535 1.1 roy }
536 1.1 roy break;
537 1.1 roy case ';': /* fi */
538 1.1 roy break;
539 1.1 roy }
540 1.1 roy }
541 1.1 roy term->_buf[term->_bufpos] = '\0';
542 1.1 roy return term->_buf;
543 1.1 roy }
544 1.1 roy
545 1.1 roy char *
546 1.6 roy ti_tiparm(TERMINAL *term, const char *str, ...)
547 1.1 roy {
548 1.1 roy va_list va;
549 1.1 roy char *ret;
550 1.1 roy
551 1.1 roy _DIAGASSERT(term != NULL);
552 1.1 roy _DIAGASSERT(str != NULL);
553 1.1 roy
554 1.1 roy va_start(va, str);
555 1.7.2.3 yamt ret = _ti_tiparm(term, str, VA_CHAR_INT, va);
556 1.1 roy va_end(va);
557 1.1 roy return ret;
558 1.1 roy }
559 1.1 roy
560 1.1 roy char *
561 1.6 roy tiparm(const char *str, ...)
562 1.1 roy {
563 1.1 roy va_list va;
564 1.1 roy char *ret;
565 1.7.2.3 yamt
566 1.7.2.3 yamt _DIAGASSERT(str != NULL);
567 1.7.2.3 yamt
568 1.7.2.3 yamt va_start(va, str);
569 1.7.2.3 yamt ret = _ti_tiparm(NULL, str, VA_CHAR_INT, va);
570 1.7.2.3 yamt va_end(va);
571 1.7.2.3 yamt return ret;
572 1.7.2.3 yamt }
573 1.7.2.3 yamt
574 1.7.2.3 yamt #ifdef VA_CHAR_LONG
575 1.7.2.3 yamt char *
576 1.7.2.3 yamt ti_tlparm(TERMINAL *term, const char *str, ...)
577 1.7.2.3 yamt {
578 1.7.2.3 yamt va_list va;
579 1.7.2.3 yamt char *ret;
580 1.7.2.3 yamt
581 1.7.2.3 yamt _DIAGASSERT(term != NULL);
582 1.7.2.3 yamt _DIAGASSERT(str != NULL);
583 1.7.2.3 yamt
584 1.7.2.3 yamt va_start(va, str);
585 1.7.2.3 yamt ret = _ti_tiparm(term, str, VA_CHAR_LONG, va);
586 1.7.2.3 yamt va_end(va);
587 1.7.2.3 yamt return ret;
588 1.7.2.3 yamt }
589 1.7.2.3 yamt
590 1.7.2.3 yamt char *
591 1.7.2.3 yamt tlparm(const char *str, ...)
592 1.7.2.3 yamt {
593 1.7.2.3 yamt va_list va;
594 1.7.2.3 yamt char *ret;
595 1.7.2.3 yamt
596 1.7.2.3 yamt _DIAGASSERT(str != NULL);
597 1.7.2.3 yamt
598 1.7.2.3 yamt va_start(va, str);
599 1.7.2.3 yamt ret = _ti_tiparm(NULL, str, VA_CHAR_LONG, va);
600 1.7.2.3 yamt va_end(va);
601 1.7.2.3 yamt return ret;
602 1.7.2.3 yamt }
603 1.7.2.3 yamt #endif
604 1.7.2.3 yamt
605 1.7.2.3 yamt static char *
606 1.7.2.3 yamt _tparm(const char *str, ...)
607 1.7.2.3 yamt {
608 1.7.2.3 yamt va_list va;
609 1.7.2.3 yamt char *ret;
610 1.7.2.3 yamt
611 1.1 roy _DIAGASSERT(str != NULL);
612 1.1 roy
613 1.1 roy va_start(va, str);
614 1.7.2.3 yamt ret = _ti_tiparm(NULL, str, VA_LONG_LONG, va);
615 1.1 roy va_end(va);
616 1.1 roy return ret;
617 1.1 roy }
618 1.1 roy
619 1.1 roy char *
620 1.1 roy tparm(const char *str,
621 1.7.2.3 yamt long p1, long p2, long p3, long p4, long p5,
622 1.7.2.3 yamt long p6, long p7, long p8, long p9)
623 1.1 roy {
624 1.7 roy
625 1.7.2.3 yamt return _tparm(str, p1, p2, p3, p4, p5, p6, p7, p8, p9);
626 1.1 roy }
627