Module Name: src Committed By: roy Date: Thu Jan 24 10:41:29 UTC 2013
Modified Files: src/lib/libterminfo: term_private.h tparm.c src/usr.bin/tput: Makefile tput.c Log Message: Move the strings vs long analysis to a private function, but allow tput(1) to use it so we can work with string parameters to capabilities. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/lib/libterminfo/term_private.h cvs rdiff -u -r1.11 -r1.12 src/lib/libterminfo/tparm.c cvs rdiff -u -r1.10 -r1.11 src/usr.bin/tput/Makefile cvs rdiff -u -r1.22 -r1.23 src/usr.bin/tput/tput.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libterminfo/term_private.h diff -u src/lib/libterminfo/term_private.h:1.10 src/lib/libterminfo/term_private.h:1.11 --- src/lib/libterminfo/term_private.h:1.10 Sun Jun 3 23:19:10 2012 +++ src/lib/libterminfo/term_private.h Thu Jan 24 10:41:28 2013 @@ -1,7 +1,7 @@ -/* $NetBSD: term_private.h,v 1.10 2012/06/03 23:19:10 joerg Exp $ */ +/* $NetBSD: term_private.h,v 1.11 2013/01/24 10:41:28 roy Exp $ */ /* - * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. + * Copyright (c) 2009, 2010, 2013 The NetBSD Foundation, Inc. * * This code is derived from software contributed to The NetBSD Foundation * by Roy Marples. @@ -157,4 +157,7 @@ size_t _ti_store_extra(TIC *, int, char TIC *_ti_compile(char *, int); ssize_t _ti_flatten(uint8_t **, const TIC *); void _ti_freetic(TIC *); + +#define TPARM_MAX 9 /* not likely to change */ +int _ti_parm_analyse(const char *, int *, int); #endif Index: src/lib/libterminfo/tparm.c diff -u src/lib/libterminfo/tparm.c:1.11 src/lib/libterminfo/tparm.c:1.12 --- src/lib/libterminfo/tparm.c:1.11 Thu Jan 24 10:28:28 2013 +++ src/lib/libterminfo/tparm.c Thu Jan 24 10:41:28 2013 @@ -1,7 +1,7 @@ -/* $NetBSD: tparm.c,v 1.11 2013/01/24 10:28:28 roy Exp $ */ +/* $NetBSD: tparm.c,v 1.12 2013/01/24 10:41:28 roy Exp $ */ /* - * Copyright (c) 2009, 2011 The NetBSD Foundation, Inc. + * Copyright (c) 2009, 2011, 2013 The NetBSD Foundation, Inc. * * This code is derived from software contributed to The NetBSD Foundation * by Roy Marples. @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: tparm.c,v 1.11 2013/01/24 10:28:28 roy Exp $"); +__RCSID("$NetBSD: tparm.c,v 1.12 2013/01/24 10:41:28 roy Exp $"); #include <sys/param.h> #include <assert.h> @@ -42,7 +42,7 @@ __RCSID("$NetBSD: tparm.c,v 1.11 2013/01 #include <term.h> #define LONG_STR_MAX ((CHAR_BIT * sizeof(long)) / 3) -#define BUFINC 128 /* Size to increament the terminal buffer by */ +#define BUFINC 128 /* Size to increament the terminal buffer by */ static TERMINAL *dumbterm; /* For non thread safe functions */ @@ -131,18 +131,63 @@ onum(TERMINAL *term, const char *fmt, in return l; } +/* + Make a pass through the string so we can work out + which parameters are ints and which are char *. + Basically we only use char * if %p[1-9] is followed by %l or %s. +*/ +int +_ti_parm_analyse(const char *str, int *piss, int piss_len) +{ + int nparm, lpop; + char c; + + nparm = 0; + lpop = -1; + while ((c = *str++) != '\0') { + if (c != '%') + continue; + c = *str++; + switch (c) { + case 'l': /* FALLTHROUGH */ + case 's': + if (lpop > 0) { + if (lpop <= piss_len) + piss[lpop - 1] = 1; + else if (piss) + errno = E2BIG; + } + break; + case 'p': + c = *str++; + if (c < '1' || c > '9') { + errno = EINVAL; + continue; + } else { + lpop = c - '0'; + if (lpop > nparm) + nparm = lpop; + } + break; + default: + lpop = -1; + } + } + + return nparm; +} + static char * _ti_tiparm(TERMINAL *term, const char *str, int va_long, va_list parms) { - const char *sp; char c, fmt[64], *fp, *ostr; long val, val2; long dnums[26]; /* dynamic variables a-z, not preserved */ size_t l, max; TPSTACK stack; - TPVAR params[9]; + TPVAR params[TPARM_MAX]; unsigned int done, dot, minus, width, precision, olen; - int piss[9]; /* Parameter IS String - piss ;) */ + int piss[TPARM_MAX]; /* Parameter IS String - piss ;) */ if (str == NULL) return NULL; @@ -172,40 +217,8 @@ _ti_tiparm(TERMINAL *term, const char *s term->_buflen = BUFINC; } - /* - Make a first pass through the string so we can work out - which parameters are ints and which are char *. - Basically we only use char * if %p[1-9] is followed by %l or %s. - */ memset(&piss, 0, sizeof(piss)); - max = 0; - sp = str; - while ((c = *sp++) != '\0') { - if (c != '%') - continue; - c = *sp++; - if (c == '\0') - break; - if (c != 'p') - continue; - c = *sp++; - if (c < '1' || c > '9') { - errno = EINVAL; - continue; - } - l = c - '0'; - if (l > max) - max = l; - if (*sp != '%') - continue; - /* Skip formatting */ - sp++; - while (*sp == '.' || *sp == '#' || *sp == ' ' || *sp == ':' || - *sp == '-' || isdigit((unsigned char)*sp)) - sp++; - if (*sp == 'l' || *sp == 's') - piss[l - 1] = 1; - } + max = _ti_parm_analyse(str, piss, TPARM_MAX); /* Put our parameters into variables */ memset(¶ms, 0, sizeof(params)); Index: src/usr.bin/tput/Makefile diff -u src/usr.bin/tput/Makefile:1.10 src/usr.bin/tput/Makefile:1.11 --- src/usr.bin/tput/Makefile:1.10 Wed Feb 3 15:34:46 2010 +++ src/usr.bin/tput/Makefile Thu Jan 24 10:41:28 2013 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.10 2010/02/03 15:34:46 roy Exp $ +# $NetBSD: Makefile,v 1.11 2013/01/24 10:41:28 roy Exp $ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= tput @@ -7,4 +7,6 @@ LDADD= -lterminfo MLINKS= tput.1 clear.1 SCRIPTS=clear.sh +CPPFLAGS+= -I${.CURDIR}/../../lib/libterminfo + .include <bsd.prog.mk> Index: src/usr.bin/tput/tput.c diff -u src/usr.bin/tput/tput.c:1.22 src/usr.bin/tput/tput.c:1.23 --- src/usr.bin/tput/tput.c:1.22 Tue Oct 4 12:23:14 2011 +++ src/usr.bin/tput/tput.c Thu Jan 24 10:41:29 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: tput.c,v 1.22 2011/10/04 12:23:14 roy Exp $ */ +/* $NetBSD: tput.c,v 1.23 2013/01/24 10:41:29 roy Exp $ */ /*- * Copyright (c) 1980, 1988, 1993 @@ -39,17 +39,19 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)tput.c 8.3 (Berkeley) 4/28/95"; #endif -__RCSID("$NetBSD: tput.c,v 1.22 2011/10/04 12:23:14 roy Exp $"); +__RCSID("$NetBSD: tput.c,v 1.23 2013/01/24 10:41:29 roy Exp $"); #endif /* not lint */ #include <termios.h> #include <err.h> +#include <errno.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <term_private.h> #include <term.h> -#include <termcap.h> #include <unistd.h> static int outc(int); @@ -140,84 +142,47 @@ process(const char *cap, const char *str static const char errfew[] = "Not enough arguments (%d) for capability `%s'"; static const char erresc[] = - "Unknown %% escape `%c' for capability `%s'"; - char c, l; - const char *p; - int arg_need, p1, p2, p3, p4, p5, p6, p7, p8, p9; + "Unknown %% escape (%s) for capability `%s'"; + static const char errnum[] = + "Expected a numeric argument [%d] (%s) for capability `%s'"; + int i, nparams, piss[TPARM_MAX]; + long nums[TPARM_MAX]; + char *strs[TPARM_MAX], *tmp; /* Count how many values we need for this capability. */ - arg_need = 0; - p = str; - while ((c = *p++) != '\0') { - if (c != '%') - continue; - c = *p++; - if (c == '\0') - break; - if (c != 'p') - continue; - c = *p++; - if (c < '1' || c > '9') - errx(2, erresc, c, cap); - l = c - '0'; - if (l > arg_need) - arg_need = l; - } - -#define NEXT_ARG \ - { \ - if (*++argv == NULL || *argv[0] == '\0') \ - errx(2, errfew, 1, cap); \ + errno = 0; + memset(&piss, 0, sizeof(piss)); + nparams = _ti_parm_analyse(str, piss, TPARM_MAX); + if (errno == EINVAL) + errx(2, erresc, str, cap); + + /* Create our arrays of integers and strings */ + for (i = 0; i < nparams; i++) { + if (*++argv == NULL || *argv[0] == '\0') + errx(2, errfew, nparams, cap); + if (piss[i]) + strs[i] = *argv; + else { + errno = 0; + nums[i] = strtol(*argv, &tmp, 0); + if ((errno == ERANGE && + (nums[i] == LONG_MIN || nums[i] == LONG_MAX)) || + (errno != 0 && nums[i] == 0) || + tmp == str || + *tmp != '\0') + errx(2, errnum, i + 1, *argv, cap); + } + if (piss[i]) + printf ("str %d %s\n", i, strs[i]); + else + printf ("num %d %ld\n", i, nums[i]); } - if (arg_need > 0) { - NEXT_ARG; - p1 = atoi(*argv); - } else - p1 = 0; - if (arg_need > 1) { - NEXT_ARG; - p2 = atoi(*argv); - } else - p2 = 0; - if (arg_need > 2) { - NEXT_ARG; - p3 = atoi(*argv); - } else - p3 = 0; - if (arg_need > 3) { - NEXT_ARG; - p4 = atoi(*argv); - } else - p4 = 0; - if (arg_need > 4) { - NEXT_ARG; - p5 = atoi(*argv); - } else - p5 = 0; - if (arg_need > 5) { - NEXT_ARG; - p6 = atoi(*argv); - } else - p6 = 0; - if (arg_need > 6) { - NEXT_ARG; - p7 = atoi(*argv); - } else - p7 = 0; - if (arg_need > 7) { - NEXT_ARG; - p8 = atoi(*argv); - } else - p8 = 0; - if (arg_need > 8) { - NEXT_ARG; - p9 = atoi(*argv); - } else - p9 = 0; + /* And output */ +#define p(i) (i <= nparams ? \ + (piss[i - 1] ? (long)strs[i - 1] : nums[i - 1]) : 0) + puts(tparm(str, p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9))); - /* And print them. */ - (void)tputs(tparm(str, p1, p2, p3, p4, p5, p6, p7, p8, p9), 0, outc); return argv; }