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