Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.bin / tput / tput.c
1 /*-
2  * Copyright (c) 1980, 1988, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * @(#) Copyright (c) 1980, 1988, 1993 The Regents of the University of California.  All rights reserved.
34  * @(#)tput.c   8.2 (Berkeley) 3/19/94
35  * $FreeBSD: src/usr.bin/tput/tput.c,v 1.7.6.3 2002/08/17 14:52:50 tjr Exp $
36  * $DragonFly: src/usr.bin/tput/tput.c,v 1.2 2003/06/17 04:29:33 dillon Exp $
37  */
38
39 #include <termios.h>
40
41 #include <err.h>
42 #include <termcap.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #undef putchar
49 #define outc putchar
50
51 static void   prlongname __P((char *));
52 static void   usage __P((void));
53 static char **process __P((char *, char *, char **));
54
55 int
56 main(argc, argv)
57         int argc;
58         char **argv;
59 {
60         int ch, exitval, n;
61         char *cptr, *p, *term, buf[1024], tbuf[1024];
62
63         term = NULL;
64         while ((ch = getopt(argc, argv, "T:")) != -1)
65                 switch(ch) {
66                 case 'T':
67                         term = optarg;
68                         break;
69                 case '?':
70                 default:
71                         usage();
72                 }
73         argc -= optind;
74         argv += optind;
75
76         if (!term && !(term = getenv("TERM")))
77 errx(2, "no terminal type specified and no TERM environmental variable.");
78         if (tgetent(tbuf, term) != 1)
79                 err(2, "tgetent failure");
80         for (exitval = 0; (p = *argv) != NULL; ++argv) {
81                 switch (*p) {
82                 case 'c':
83                         if (!strcmp(p, "clear"))
84                                 p = "cl";
85                         break;
86                 case 'i':
87                         if (!strcmp(p, "init"))
88                                 p = "is";
89                         break;
90                 case 'l':
91                         if (!strcmp(p, "longname")) {
92                                 prlongname(tbuf);
93                                 continue;
94                         }
95                         break;
96                 case 'r':
97                         if (!strcmp(p, "reset"))
98                                 p = "rs";
99                         break;
100                 }
101                 cptr = buf;
102                 if (tgetstr(p, &cptr))
103                         argv = process(p, buf, argv);
104                 else if ((n = tgetnum(p)) != -1)
105                         (void)printf("%d\n", n);
106                 else
107                         exitval = !tgetflag(p);
108         }
109         exit(exitval);
110 }
111
112 static void
113 prlongname(buf)
114         char *buf;
115 {
116         int savech;
117         char *p, *savep;
118
119         for (p = buf; *p && *p != ':'; ++p);
120         savech = *(savep = p);
121         for (*p = '\0'; p >= buf && *p != '|'; --p);
122         (void)printf("%s\n", p + 1);
123         *savep = savech;
124 }
125
126 static char **
127 process(cap, str, argv)
128         char *cap, *str, **argv;
129 {
130         static char errfew[] =
131             "not enough arguments (%d) for capability `%s'";
132         static char errmany[] =
133             "too many arguments (%d) for capability `%s'";
134         static char erresc[] =
135             "unknown %% escape `%c' for capability `%s'";
136         char *cp;
137         int arg_need, arg_rows, arg_cols;
138
139         /* Count how many values we need for this capability. */
140         for (cp = str, arg_need = 0; *cp != '\0'; cp++)
141                 if (*cp == '%')
142                             switch (*++cp) {
143                             case 'd':
144                             case '2':
145                             case '3':
146                             case '.':
147                             case '+':
148                                     arg_need++;
149                                     break;
150                             case '%':
151                             case '>':
152                             case 'i':
153                             case 'r':
154                             case 'n':
155                             case 'B':
156                             case 'D':
157                                     break;
158                             case 'p':
159                                     if (cp[1]) {
160                                         cp++;
161                                         break;
162                                     }
163                             default:
164                                 /*
165                                  * hpux has lot's of them, but we complain
166                                  */
167                                  warnx(erresc, *cp, cap);
168                             }
169
170         /* And print them. */
171         switch (arg_need) {
172         case 0:
173                 (void)tputs(str, 1, outc);
174                 break;
175         case 1:
176                 arg_cols = 0;
177
178                 if (*++argv == NULL || *argv[0] == '\0')
179                         errx(2, errfew, 1, cap);
180                 arg_rows = atoi(*argv);
181
182                 (void)tputs(tgoto(str, arg_cols, arg_rows), 1, outc);
183                 break;
184         case 2:
185                 if (*++argv == NULL || *argv[0] == '\0')
186                         errx(2, errfew, 2, cap);
187                 arg_cols = atoi(*argv);
188
189                 if (*++argv == NULL || *argv[0] == '\0')
190                         errx(2, errfew, 2, cap);
191                 arg_rows = atoi(*argv);
192
193                 (void) tputs(tgoto(str, arg_cols, arg_rows), arg_rows, outc);
194                 break;
195
196         default:
197                 errx(2, errmany, arg_need, cap);
198         }
199         return (argv);
200 }
201
202 static void
203 usage()
204 {
205         (void)fprintf(stderr, "usage: tput [-T term] attribute ...\n");
206         exit(1);
207 }