tput.c revision 1.26 1 1.26 roy /* $NetBSD: tput.c,v 1.26 2013/02/05 11:31:56 roy Exp $ */
2 1.5 jtc
3 1.1 cgd /*-
4 1.5 jtc * Copyright (c) 1980, 1988, 1993
5 1.5 jtc * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * Redistribution and use in source and binary forms, with or without
8 1.1 cgd * modification, are permitted provided that the following conditions
9 1.1 cgd * are met:
10 1.1 cgd * 1. Redistributions of source code must retain the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer.
12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 cgd * notice, this list of conditions and the following disclaimer in the
14 1.1 cgd * documentation and/or other materials provided with the distribution.
15 1.15 agc * 3. Neither the name of the University nor the names of its contributors
16 1.1 cgd * may be used to endorse or promote products derived from this software
17 1.1 cgd * without specific prior written permission.
18 1.1 cgd *
19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 1.1 cgd * SUCH DAMAGE.
30 1.1 cgd */
31 1.1 cgd
32 1.9 lukem #include <sys/cdefs.h>
33 1.1 cgd #ifndef lint
34 1.19 lukem __COPYRIGHT("@(#) Copyright (c) 1980, 1988, 1993\
35 1.19 lukem The Regents of the University of California. All rights reserved.");
36 1.1 cgd #endif /* not lint */
37 1.1 cgd
38 1.1 cgd #ifndef lint
39 1.5 jtc #if 0
40 1.8 jtc static char sccsid[] = "@(#)tput.c 8.3 (Berkeley) 4/28/95";
41 1.5 jtc #endif
42 1.26 roy __RCSID("$NetBSD: tput.c,v 1.26 2013/02/05 11:31:56 roy Exp $");
43 1.1 cgd #endif /* not lint */
44 1.1 cgd
45 1.7 jtc #include <termios.h>
46 1.5 jtc
47 1.5 jtc #include <err.h>
48 1.23 roy #include <errno.h>
49 1.23 roy #include <limits.h>
50 1.1 cgd #include <stdio.h>
51 1.5 jtc #include <stdlib.h>
52 1.13 matt #include <string.h>
53 1.23 roy #include <term_private.h>
54 1.20 roy #include <term.h>
55 1.1 cgd #include <unistd.h>
56 1.1 cgd
57 1.18 perry static void usage(void) __dead;
58 1.20 roy static char **process(const char *, const char *, char **);
59 1.3 cgd
60 1.3 cgd int
61 1.17 christos main(int argc, char **argv)
62 1.1 cgd {
63 1.3 cgd int ch, exitval, n;
64 1.21 roy char *term;
65 1.20 roy const char *p, *s;
66 1.22 roy size_t pl;
67 1.1 cgd
68 1.1 cgd term = NULL;
69 1.10 lukem while ((ch = getopt(argc, argv, "T:")) != -1)
70 1.1 cgd switch(ch) {
71 1.1 cgd case 'T':
72 1.1 cgd term = optarg;
73 1.1 cgd break;
74 1.1 cgd case '?':
75 1.1 cgd default:
76 1.1 cgd usage();
77 1.1 cgd }
78 1.1 cgd argc -= optind;
79 1.1 cgd argv += optind;
80 1.1 cgd
81 1.5 jtc if (!term && !(term = getenv("TERM")))
82 1.17 christos errx(2, "No terminal type specified and no TERM "
83 1.17 christos "variable set in the environment.");
84 1.20 roy setupterm(term, 0, NULL);
85 1.3 cgd for (exitval = 0; (p = *argv) != NULL; ++argv) {
86 1.5 jtc switch (*p) {
87 1.1 cgd case 'c':
88 1.1 cgd if (!strcmp(p, "clear"))
89 1.20 roy p = "clear";
90 1.1 cgd break;
91 1.1 cgd case 'i':
92 1.20 roy if (!strcmp(p, "init")) {
93 1.20 roy s = tigetstr("is1");
94 1.20 roy if (s != NULL)
95 1.26 roy putp(s);
96 1.20 roy p = "is2";
97 1.20 roy }
98 1.1 cgd break;
99 1.1 cgd case 'l':
100 1.4 cgd if (!strcmp(p, "longname")) {
101 1.21 roy (void)printf("%s\n", longname());
102 1.4 cgd continue;
103 1.4 cgd }
104 1.4 cgd break;
105 1.1 cgd case 'r':
106 1.20 roy if (!strcmp(p, "reset")) {
107 1.20 roy s = tigetstr("rs1");
108 1.20 roy if (s != NULL)
109 1.26 roy putp(s);
110 1.20 roy p = "rs2";
111 1.20 roy }
112 1.1 cgd break;
113 1.1 cgd }
114 1.22 roy pl = strlen(p);
115 1.20 roy if (((s = tigetstr(p)) != NULL && s != (char *)-1) ||
116 1.22 roy (pl <= 2 && (s = tgetstr(p, NULL)) != NULL))
117 1.20 roy argv = process(p, s, argv);
118 1.22 roy else if ((((n = tigetnum(p)) != -1 && n != -2 ) ||
119 1.22 roy (pl <= 2 && (n = tgetnum(p)) != -1)))
120 1.1 cgd (void)printf("%d\n", n);
121 1.20 roy else {
122 1.20 roy exitval = tigetflag(p);
123 1.22 roy if (exitval == -1) {
124 1.22 roy if (pl <= 2)
125 1.22 roy exitval = !tgetflag(p);
126 1.22 roy else
127 1.22 roy exitval = 1;
128 1.22 roy } else
129 1.20 roy exitval = !exitval;
130 1.20 roy }
131 1.3 cgd
132 1.3 cgd if (argv == NULL)
133 1.3 cgd break;
134 1.1 cgd }
135 1.17 christos return argv ? exitval : 2;
136 1.1 cgd }
137 1.1 cgd
138 1.3 cgd static char **
139 1.20 roy process(const char *cap, const char *str, char **argv)
140 1.3 cgd {
141 1.14 is static const char errfew[] =
142 1.17 christos "Not enough arguments (%d) for capability `%s'";
143 1.14 is static const char erresc[] =
144 1.23 roy "Unknown %% escape (%s) for capability `%s'";
145 1.23 roy static const char errnum[] =
146 1.23 roy "Expected a numeric argument [%d] (%s) for capability `%s'";
147 1.25 roy static const char errcharlong[] =
148 1.25 roy "Platform does not fit a string into a long for capability '%s'";
149 1.23 roy int i, nparams, piss[TPARM_MAX];
150 1.23 roy long nums[TPARM_MAX];
151 1.23 roy char *strs[TPARM_MAX], *tmp;
152 1.5 jtc
153 1.5 jtc /* Count how many values we need for this capability. */
154 1.23 roy errno = 0;
155 1.23 roy memset(&piss, 0, sizeof(piss));
156 1.23 roy nparams = _ti_parm_analyse(str, piss, TPARM_MAX);
157 1.23 roy if (errno == EINVAL)
158 1.23 roy errx(2, erresc, str, cap);
159 1.23 roy
160 1.23 roy /* Create our arrays of integers and strings */
161 1.23 roy for (i = 0; i < nparams; i++) {
162 1.23 roy if (*++argv == NULL || *argv[0] == '\0')
163 1.23 roy errx(2, errfew, nparams, cap);
164 1.25 roy if (piss[i]) {
165 1.25 roy if (sizeof(char *) > sizeof(long) /* CONSTCOND */)
166 1.25 roy errx(2, errcharlong, cap);
167 1.23 roy strs[i] = *argv;
168 1.25 roy } else {
169 1.23 roy errno = 0;
170 1.23 roy nums[i] = strtol(*argv, &tmp, 0);
171 1.23 roy if ((errno == ERANGE &&
172 1.23 roy (nums[i] == LONG_MIN || nums[i] == LONG_MAX)) ||
173 1.23 roy (errno != 0 && nums[i] == 0) ||
174 1.23 roy tmp == str ||
175 1.23 roy *tmp != '\0')
176 1.23 roy errx(2, errnum, i + 1, *argv, cap);
177 1.23 roy }
178 1.20 roy }
179 1.20 roy
180 1.23 roy /* And output */
181 1.23 roy #define p(i) (i <= nparams ? \
182 1.23 roy (piss[i - 1] ? (long)strs[i - 1] : nums[i - 1]) : 0)
183 1.26 roy putp(tparm(str, p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9)));
184 1.3 cgd
185 1.17 christos return argv;
186 1.5 jtc }
187 1.5 jtc
188 1.5 jtc static void
189 1.17 christos usage(void)
190 1.5 jtc {
191 1.16 wiz (void)fprintf(stderr,
192 1.17 christos "Usage: %s [-T term] attribute [attribute-args] ...\n",
193 1.16 wiz getprogname());
194 1.17 christos exit(2);
195 1.1 cgd }
196