ncurses 5.0
[ncurses.git] / progs / tput.c
1 /****************************************************************************
2  * Copyright (c) 1998 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 /*
36  * tput.c -- shellscript access to terminal capabilities
37  *
38  * by Eric S. Raymond <esr@snark.thyrsus.com>, portions based on code from
39  * Ross Ridge's mytinfo package.
40  */
41
42 #include <progs.priv.h>
43 #ifndef PURE_TERMINFO
44 #include <termsort.c>
45 #endif
46
47 MODULE_ID("$Id: tput.c,v 1.14 1999/07/31 21:18:29 Goran.Uddeborg Exp $")
48
49 #define PUTS(s)         fputs(s, stdout)
50 #define PUTCHAR(c)      putchar(c)
51 #define FLUSH           fflush(stdout)
52
53 static char *prg_name;
54
55 static void 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 usage(void)
67 {
68         fprintf(stderr, "usage: %s [-S] [-T term] capname\n", prg_name);
69         exit(EXIT_FAILURE);
70 }
71
72 static int tput(int argc, char *argv[])
73 {
74 char *name;
75 char *s;
76 int i, j, c;
77 int reset, status;
78 FILE *f;
79
80         reset = 0;
81         name = argv[0];
82         if (strcmp(name, "reset") == 0) {
83                 reset = 1;
84         }
85         if (reset || strcmp(name, "init") == 0) {
86                 if (init_prog != NULL) {
87                         system(init_prog);
88                 }
89                 FLUSH;
90
91                 if (reset && reset_1string != NULL) {
92                         PUTS(reset_1string);
93                 } else if (init_1string != NULL) {
94                         PUTS(init_1string);
95                 }
96                 FLUSH;
97
98                 if (reset && reset_2string != NULL) {
99                         PUTS(reset_2string);
100                 } else if (init_2string != NULL) {
101                         PUTS(init_2string);
102                 }
103                 FLUSH;
104
105                 if (set_lr_margin != NULL) {
106                         PUTS(tparm(set_lr_margin, 0, columns - 1));
107                 } else if (set_left_margin_parm != NULL
108                            && set_right_margin_parm != NULL) {
109                         PUTS(tparm(set_left_margin_parm, 0));
110                         PUTS(tparm(set_right_margin_parm, columns - 1));
111                 } else if (clear_margins != NULL && set_left_margin != NULL
112                            && set_right_margin != NULL) {
113                         PUTS(clear_margins);
114                         if (carriage_return != NULL) {
115                                 PUTS(carriage_return);
116                         } else {
117                                 PUTCHAR('\r');
118                         }
119                         PUTS(set_left_margin);
120                         if (parm_right_cursor) {
121                                 PUTS(tparm(parm_right_cursor, columns - 1));
122                         } else {
123                                 for(i = 0; i < columns - 1; i++) {
124                                         PUTCHAR(' ');
125                                 }
126                         }
127                         PUTS(set_right_margin);
128                         if (carriage_return != NULL) {
129                                 PUTS(carriage_return);
130                         } else {
131                                 PUTCHAR('\r');
132                         }
133                 }
134                 FLUSH;
135
136                 if (init_tabs != 8) {
137                         if (clear_all_tabs != NULL && set_tab != NULL) {
138                                 for(i = 0; i < columns - 1; i += 8) {
139                                         if (parm_right_cursor) {
140                                                 PUTS(tparm(parm_right_cursor, 8));
141                                         } else {
142                                                 for(j = 0; j < 8; j++)
143                                                         PUTCHAR(' ');
144                                         }
145                                         PUTS(set_tab);
146                                 }
147                                 FLUSH;
148                         }
149                 }
150
151                 if (reset && reset_file != NULL) {
152                         f = fopen(reset_file, "r");
153                         if (f == NULL) {
154                                 quit(errno, "Can't open reset_file: '%s'", reset_file);
155                         }
156                         while((c = fgetc(f)) != EOF) {
157                                 PUTCHAR(c);
158                         }
159                         fclose(f);
160                 } else if (init_file != NULL) {
161                         f = fopen(init_file, "r");
162                         if (f == NULL) {
163                                 quit(errno, "Can't open init_file: '%s'", init_file);
164                         }
165                         while((c = fgetc(f)) != EOF) {
166                                 PUTCHAR(c);
167                         }
168                         fclose(f);
169                 }
170                 FLUSH;
171
172                 if (reset && reset_3string != NULL) {
173                         PUTS(reset_3string);
174                 } else if (init_2string != NULL) {
175                         PUTS(init_2string);
176                 }
177                 FLUSH;
178                 return 0;
179         }
180
181         if (strcmp(name, "longname") == 0) {
182                 PUTS(longname());
183                 return 0;
184         }
185
186 #ifndef PURE_TERMINFO
187         {
188                 const struct name_table_entry   *np;
189
190                 if ((np = _nc_find_entry(name, _nc_get_hash_table(1))) != 0)
191                         switch(np->nte_type)
192                         {
193                         case BOOLEAN:
194                                 if (bool_from_termcap[np->nte_index])
195                                         name = boolnames[np->nte_index];
196                                 break;
197
198                         case NUMBER:
199                                 if (num_from_termcap[np->nte_index])
200                                         name = numnames[np->nte_index];
201                                 break;
202
203                         case STRING:
204                                 if (str_from_termcap[np->nte_index])
205                                         name = strnames[np->nte_index];
206                                 break;
207                         }
208         }
209 #endif
210
211         if ((status = tigetflag(name)) != -1)
212                 return(status != 0);
213         else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
214                 (void) printf("%d\n", status);
215                 return(0);
216         }
217         else if ((s = tigetstr(name)) == CANCELLED_STRING)
218                 quit(4, "%s: unknown terminfo capability '%s'", prg_name, name);
219         else if (s != (char *)NULL) {
220                 if (argc > 1) {
221                 int k;
222
223                         /* Nasty hack time. The tparm function needs to see numeric
224                          * parameters as numbers, not as pointers to their string
225                          * representations
226                          */
227
228                          for (k = 1; k < argc; k++)
229                                 if (isdigit(argv[k][0])) {
230                                         long val = atol(argv[k]);
231                                         argv[k] = (char *)val;
232                                 }
233
234                                 s = tparm(s,argv[1],argv[2],argv[3],argv[4],
235                                             argv[5],argv[6],argv[7],argv[8],
236                                             argv[9]);
237                 }
238
239                 /* use putp() in order to perform padding */
240                 putp(s);
241                 return(0);
242         }
243         return(0);
244 }
245
246 int main(int argc, char **argv)
247 {
248 char *s, *term;
249 int errret, cmdline = 1;
250 int c;
251 char    buf[BUFSIZ];
252 int errors = 0;
253
254         prg_name = argv[0];
255         s = strrchr(prg_name, '/');
256         if (s != NULL && *++s != '\0')
257         prg_name = s;
258
259         term = getenv("TERM");
260
261         while ((c = getopt (argc, argv, "ST:")) != EOF)
262             switch (c)
263             {
264             case 'S':
265                 cmdline = 0;
266                 break;
267             case 'T':
268                 use_env(FALSE);
269                 term = optarg;
270                 break;
271             default:
272                 usage();
273                 /* NOTREACHED */
274             }
275         argc -= optind;
276         argv += optind;
277
278         if (cmdline && argc == 0) {
279                 usage();
280                 /* NOTREACHED */
281         }
282
283         if (term == NULL || *term == '\0')
284                 quit(2, "No value for $TERM and no -T specified");
285
286         if (setupterm(term, STDOUT_FILENO, &errret) != OK && errret <= 0) 
287                 quit(3, "unknown terminal \"%s\"", term);
288
289         if (cmdline)
290                 return tput(argc, argv);
291
292         while (fgets(buf, sizeof(buf), stdin) != (char *)NULL) {
293                 char    *argvec[16];    /* command, 9 parms, null, & slop */
294                 int      argnum = 0;
295                 char    *cp;
296
297                 /* crack the argument list into a dope vector */
298                 for (cp = buf; *cp; cp++) {
299                         if (isspace(*cp))
300                                 *cp = '\0';
301                         else if (cp == buf || cp[-1] == 0)
302                                 argvec[argnum++] = cp;
303                 }
304                 argvec[argnum] = (char *)NULL;
305
306                 if (tput(argnum, argvec) != 0)
307                         errors++;
308         }
309
310         return errors > 0;
311 }
312