ncurses 5.1
[ncurses.git] / progs / tput.c
1 /****************************************************************************
2  * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc.                        *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28
29 /****************************************************************************
30  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
31  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32  ****************************************************************************/
33
34 /*
35  * tput.c -- shellscript access to terminal capabilities
36  *
37  * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
38  * Ross Ridge's mytinfo package.
39  */
40
41 #include <progs.priv.h>
42 #ifndef PURE_TERMINFO
43 #include <termsort.c>
44 #endif
45
46 MODULE_ID("$Id: tput.c,v 1.16 2000/03/19 01:08:08 tom Exp $")
47
48 #define PUTS(s)         fputs(s, stdout)
49 #define PUTCHAR(c)      putchar(c)
50 #define FLUSH           fflush(stdout)
51
52 static char *prg_name;
53
54 static void
55 quit(int status, const char *fmt,...)
56 {
57     va_list argp;
58
59     va_start(argp, fmt);
60     vfprintf(stderr, fmt, argp);
61     fprintf(stderr, "\n");
62     va_end(argp);
63     exit(status);
64 }
65
66 static void
67 usage(void)
68 {
69     fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
70     exit(EXIT_FAILURE);
71 }
72
73 static int
74 tput(int argc, char *argv[])
75 {
76     NCURSES_CONST char *name;
77     char *s;
78     int i, j, c;
79     int reset, status;
80     FILE *f;
81
82     reset = 0;
83     name = argv[0];
84     if (strcmp(name, "reset") == 0) {
85         reset = 1;
86     }
87     if (reset || strcmp(name, "init") == 0) {
88         if (init_prog != 0) {
89             system(init_prog);
90         }
91         FLUSH;
92
93         if (reset && reset_1string != 0) {
94             PUTS(reset_1string);
95         } else if (init_1string != 0) {
96             PUTS(init_1string);
97         }
98         FLUSH;
99
100         if (reset && reset_2string != 0) {
101             PUTS(reset_2string);
102         } else if (init_2string != 0) {
103             PUTS(init_2string);
104         }
105         FLUSH;
106
107         if (set_lr_margin != 0) {
108             PUTS(tparm(set_lr_margin, 0, columns - 1));
109         } else if (set_left_margin_parm != 0
110             && set_right_margin_parm != 0) {
111             PUTS(tparm(set_left_margin_parm, 0));
112             PUTS(tparm(set_right_margin_parm, columns - 1));
113         } else if (clear_margins != 0
114             && set_left_margin != 0
115             && set_right_margin != 0) {
116             PUTS(clear_margins);
117             if (carriage_return != 0) {
118                 PUTS(carriage_return);
119             } else {
120                 PUTCHAR('\r');
121             }
122             PUTS(set_left_margin);
123             if (parm_right_cursor) {
124                 PUTS(tparm(parm_right_cursor, columns - 1));
125             } else {
126                 for (i = 0; i < columns - 1; i++) {
127                     PUTCHAR(' ');
128                 }
129             }
130             PUTS(set_right_margin);
131             if (carriage_return != 0) {
132                 PUTS(carriage_return);
133             } else {
134                 PUTCHAR('\r');
135             }
136         }
137         FLUSH;
138
139         if (init_tabs != 8) {
140             if (clear_all_tabs != 0 && set_tab != 0) {
141                 for (i = 0; i < columns - 1; i += 8) {
142                     if (parm_right_cursor) {
143                         PUTS(tparm(parm_right_cursor, 8));
144                     } else {
145                         for (j = 0; j < 8; j++)
146                             PUTCHAR(' ');
147                     }
148                     PUTS(set_tab);
149                 }
150                 FLUSH;
151             }
152         }
153
154         if (reset && reset_file != 0) {
155             f = fopen(reset_file, "r");
156             if (f == 0) {
157                 quit(errno, "Can't open reset_file: '%s'", reset_file);
158             }
159             while ((c = fgetc(f)) != EOF) {
160                 PUTCHAR(c);
161             }
162             fclose(f);
163         } else if (init_file != 0) {
164             f = fopen(init_file, "r");
165             if (f == 0) {
166                 quit(errno, "Can't open init_file: '%s'", init_file);
167             }
168             while ((c = fgetc(f)) != EOF) {
169                 PUTCHAR(c);
170             }
171             fclose(f);
172         }
173         FLUSH;
174
175         if (reset && reset_3string != 0) {
176             PUTS(reset_3string);
177         } else if (init_2string != 0) {
178             PUTS(init_2string);
179         }
180         FLUSH;
181         return 0;
182     }
183
184     if (strcmp(name, "longname") == 0) {
185         PUTS(longname());
186         return 0;
187     }
188 #ifndef PURE_TERMINFO
189     {
190         const struct name_table_entry *np;
191
192         if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
193             switch (np->nte_type) {
194             case BOOLEAN:
195                 if (bool_from_termcap[np->nte_index])
196                     name = boolnames[np->nte_index];
197                 break;
198
199             case NUMBER:
200                 if (num_from_termcap[np->nte_index])
201                     name = numnames[np->nte_index];
202                 break;
203
204             case STRING:
205                 if (str_from_termcap[np->nte_index])
206                     name = strnames[np->nte_index];
207                 break;
208             }
209     }
210 #endif
211
212     if ((status = tigetflag(name)) != -1) {
213         return (status != 0);
214     } else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
215         (void) printf("%d\n", status);
216         return (0);
217     } else if ((s = tigetstr(name)) == CANCELLED_STRING) {
218         quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
219     } else if (s != 0) {
220         if (argc > 1) {
221             int k;
222             char * params[10];
223
224             /* Nasty hack time. The tparm function needs to see numeric
225              * parameters as numbers, not as pointers to their string
226              * representations
227              */
228
229             for (k = 1; k < argc; k++) {
230                 if (isdigit(argv[k][0])) {
231                     long val = atol(argv[k]);
232                     params[k] = (char *)val;
233                 } else {
234                     params[k] = argv[k];
235                 }
236             }
237             for (k = argc; k <= 9; k++)
238                 params[k] = 0;
239
240             s = tparm(s,
241                 params[1], params[2], params[3],
242                 params[4], params[5], params[6],
243                 params[7], params[8], params[9]);
244         }
245
246         /* use putp() in order to perform padding */
247         putp(s);
248         return (0);
249     }
250     return (0);
251 }
252
253 int
254 main(int argc, char **argv)
255 {
256     char *s, *term;
257     int errret, cmdline = 1;
258     int c;
259     char buf[BUFSIZ];
260     int errors = 0;
261
262     prg_name = argv[0];
263     s = strrchr(prg_name, '/');
264     if (s != 0 && *++s != '\0')
265         prg_name = s;
266
267     term = getenv("TERM");
268
269     while ((c = getopt(argc, argv, "ST:")) != EOF)
270         switch (c) {
271         case 'S':
272             cmdline = 0;
273             break;
274         case 'T':
275             use_env(FALSE);
276             term = optarg;
277             break;
278         default:
279             usage();
280             /* NOTREACHED */
281         }
282     argc -= optind;
283     argv += optind;
284
285     if (cmdline && argc == 0) {
286         usage();
287         /* NOTREACHED */
288     }
289
290     if (term == 0 || *term == '\0')
291         quit(2, "No value for $TERM and no -T specified");
292
293     if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0)
294         quit(3, "unknown terminal \"%s\"", term);
295
296     if (cmdline)
297         return tput(argc, argv);
298
299     while (fgets(buf, sizeof(buf), stdin) != 0) {
300         char *argvec[16];       /* command, 9 parms, null, & slop */
301         int argnum = 0;
302         char *cp;
303
304         /* crack the argument list into a dope vector */
305         for (cp = buf; *cp; cp++) {
306             if (isspace(*cp))
307                 *cp = '\0';
308             else if (cp == buf || cp[-1] == 0)
309                 argvec[argnum++] = cp;
310         }
311         argvec[argnum] = 0;
312
313         if (tput(argnum, argvec) != 0)
314             errors++;
315     }
316
317     return errors > 0;
318 }