1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996, by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate * All rights reserved.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate * tabs.c
31*7c478bd9Sstevel@tonic-gate *
32*7c478bd9Sstevel@tonic-gate * Copyright 1990, 1992 by Mortice Kern Systems Inc. All rights reserved.
33*7c478bd9Sstevel@tonic-gate *
34*7c478bd9Sstevel@tonic-gate * PORTABILITY:
35*7c478bd9Sstevel@tonic-gate * POSIX.2a UPE full support
36*7c478bd9Sstevel@tonic-gate * SVID 3 full support except +m option is stubbed
37*7c478bd9Sstevel@tonic-gate * XPG full support except +m option is stubbed
38*7c478bd9Sstevel@tonic-gate *
39*7c478bd9Sstevel@tonic-gate * SYNOPSIS:
40*7c478bd9Sstevel@tonic-gate * tabs [-T term] [+m[n]] [-n]
41*7c478bd9Sstevel@tonic-gate * tabs [-T term] [+m[n]] -t tablist
42*7c478bd9Sstevel@tonic-gate * tabs [-T term] [+m[n]] n1[,n2,...]
43*7c478bd9Sstevel@tonic-gate * tabs [-T term] [+m[n]] tabspec
44*7c478bd9Sstevel@tonic-gate *
45*7c478bd9Sstevel@tonic-gate * DESCRIPTION:
46*7c478bd9Sstevel@tonic-gate * The tabs utility shall display a series of characters that first clears
47*7c478bd9Sstevel@tonic-gate * the hardware terminal tab settings and then initializes the tab stops
48*7c478bd9Sstevel@tonic-gate * at the specified positions.
49*7c478bd9Sstevel@tonic-gate *
50*7c478bd9Sstevel@tonic-gate * The phrase "tab-stop position N" shall be taken to mean that, from the
51*7c478bd9Sstevel@tonic-gate * start of a line of output, tabbing to position N shall cause the next
52*7c478bd9Sstevel@tonic-gate * character output to be in the (N+1)th column position on that line.
53*7c478bd9Sstevel@tonic-gate * The maximum number of tab stops allowed is terminal dependent.
54*7c478bd9Sstevel@tonic-gate *
55*7c478bd9Sstevel@tonic-gate * 'tabspec' is one of the following:
56*7c478bd9Sstevel@tonic-gate *
57*7c478bd9Sstevel@tonic-gate * Assembler:
58*7c478bd9Sstevel@tonic-gate * -a 1,10,16,36,72
59*7c478bd9Sstevel@tonic-gate * -a2 1,10,16,40,72
60*7c478bd9Sstevel@tonic-gate * -u 1,12,20,44
61*7c478bd9Sstevel@tonic-gate *
62*7c478bd9Sstevel@tonic-gate * COBOL:
63*7c478bd9Sstevel@tonic-gate * -c 1,8,12,16,20,55
64*7c478bd9Sstevel@tonic-gate * -c2 1,6,10,14,49
65*7c478bd9Sstevel@tonic-gate * -c3 1,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62,67
66*7c478bd9Sstevel@tonic-gate *
67*7c478bd9Sstevel@tonic-gate * FORTRAN:
68*7c478bd9Sstevel@tonic-gate * -f 1,7,11,15,19,23
69*7c478bd9Sstevel@tonic-gate *
70*7c478bd9Sstevel@tonic-gate * PL/I:
71*7c478bd9Sstevel@tonic-gate * -p 1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61
72*7c478bd9Sstevel@tonic-gate *
73*7c478bd9Sstevel@tonic-gate * SNOBOL:
74*7c478bd9Sstevel@tonic-gate * -s 1,10,55
75*7c478bd9Sstevel@tonic-gate *
76*7c478bd9Sstevel@tonic-gate *
77*7c478bd9Sstevel@tonic-gate * EXIT STATUS:
78*7c478bd9Sstevel@tonic-gate * 0 successful completion.
79*7c478bd9Sstevel@tonic-gate *
80*7c478bd9Sstevel@tonic-gate * >0 An error occured.
81*7c478bd9Sstevel@tonic-gate */
82*7c478bd9Sstevel@tonic-gate #ifdef M_RCSID
83*7c478bd9Sstevel@tonic-gate #ifndef lint
84*7c478bd9Sstevel@tonic-gate static char rcsID[] = "$Id: tabs.c 1.20 1995/09/21 21:00:28 ant Exp $";
85*7c478bd9Sstevel@tonic-gate #endif
86*7c478bd9Sstevel@tonic-gate #endif
87*7c478bd9Sstevel@tonic-gate
88*7c478bd9Sstevel@tonic-gate #include <mks.h>
89*7c478bd9Sstevel@tonic-gate #include <curses.h>
90*7c478bd9Sstevel@tonic-gate #define SINGLE 1 /* only one terminal to be concerned about */
91*7c478bd9Sstevel@tonic-gate #include <term.h>
92*7c478bd9Sstevel@tonic-gate #include <ctype.h>
93*7c478bd9Sstevel@tonic-gate #include <stdarg.h>
94*7c478bd9Sstevel@tonic-gate #include <stdio.h>
95*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
96*7c478bd9Sstevel@tonic-gate #include <string.h>
97*7c478bd9Sstevel@tonic-gate
98*7c478bd9Sstevel@tonic-gate extern char *_cmdname;
99*7c478bd9Sstevel@tonic-gate
100*7c478bd9Sstevel@tonic-gate
101*7c478bd9Sstevel@tonic-gate /* Exit Status */
102*7c478bd9Sstevel@tonic-gate #define SUCCESS 0
103*7c478bd9Sstevel@tonic-gate #define NOT_DEFINED 1
104*7c478bd9Sstevel@tonic-gate #define USAGE 2
105*7c478bd9Sstevel@tonic-gate #define BAD_TERMINAL 3
106*7c478bd9Sstevel@tonic-gate #define NOT_VALID 4
107*7c478bd9Sstevel@tonic-gate #define ERROR 5
108*7c478bd9Sstevel@tonic-gate
109*7c478bd9Sstevel@tonic-gate #define NO_FORM 0
110*7c478bd9Sstevel@tonic-gate #define N_FORM 1 /* tabs [-T term] [+m[n]] [-<n>] */
111*7c478bd9Sstevel@tonic-gate #define T_FORM 2 /* tabs [-T term] [+m[n]] -t tablist */
112*7c478bd9Sstevel@tonic-gate #define P_FORM 3 /* tabs [-T term] [+m[n]] n1[,n2,...] and
113*7c478bd9Sstevel@tonic-gate * tabs [-T term] [+m[n]] tabspec
114*7c478bd9Sstevel@tonic-gate */
115*7c478bd9Sstevel@tonic-gate
116*7c478bd9Sstevel@tonic-gate
117*7c478bd9Sstevel@tonic-gate static int form = NO_FORM;
118*7c478bd9Sstevel@tonic-gate static int n_width = 8;
119*7c478bd9Sstevel@tonic-gate static int margin = 0;
120*7c478bd9Sstevel@tonic-gate static wchar_t *tablist;
121*7c478bd9Sstevel@tonic-gate
122*7c478bd9Sstevel@tonic-gate typedef struct {
123*7c478bd9Sstevel@tonic-gate char *option;
124*7c478bd9Sstevel@tonic-gate char *list;
125*7c478bd9Sstevel@tonic-gate } predefined;
126*7c478bd9Sstevel@tonic-gate
127*7c478bd9Sstevel@tonic-gate static predefined tabspec[] = {
128*7c478bd9Sstevel@tonic-gate { "a", "1,10,16,36,72" },
129*7c478bd9Sstevel@tonic-gate { "a2", "1,10,16,40,72" },
130*7c478bd9Sstevel@tonic-gate { "u", "1,12,20,44" },
131*7c478bd9Sstevel@tonic-gate { "c", "1,8,12,16,20,55" },
132*7c478bd9Sstevel@tonic-gate { "c2", "1,6,10,14,49" },
133*7c478bd9Sstevel@tonic-gate { "c3", "1,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62,67" },
134*7c478bd9Sstevel@tonic-gate { "f", "1,7,11,15,19,23" },
135*7c478bd9Sstevel@tonic-gate { "p", "1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61" },
136*7c478bd9Sstevel@tonic-gate { "s", "1,10,55" },
137*7c478bd9Sstevel@tonic-gate { NULL, NULL }
138*7c478bd9Sstevel@tonic-gate };
139*7c478bd9Sstevel@tonic-gate
140*7c478bd9Sstevel@tonic-gate static char *term_name;
141*7c478bd9Sstevel@tonic-gate static char dumb_term[] = "dumb";
142*7c478bd9Sstevel@tonic-gate static char missing_tablist[] = m_textstr(1828, "Missing tab list after -t.\n", "E");
143*7c478bd9Sstevel@tonic-gate static char missing_terminal[] = m_textstr(1829, "Missing terminal type after -T.\n", "E");
144*7c478bd9Sstevel@tonic-gate static char unknown_option[] = m_textstr(433, "Unknown option \"-%s\".\n", "E option");
145*7c478bd9Sstevel@tonic-gate static char bad_list[] = m_textstr(1830, "Illegal tabs in \"%s\".\n", "E tablist");
146*7c478bd9Sstevel@tonic-gate static char no_margins[] = m_textstr(1831, "Cannot set margins on terminal \"%s\".\n", "E term");
147*7c478bd9Sstevel@tonic-gate static char no_tabs[] = m_textstr(1832, "Cannot set tabs on terminal \"%s\".\n", "E term");
148*7c478bd9Sstevel@tonic-gate static char not_ascending[] = m_textstr(1833, "\"%s\" are not in ascending order.\n", "E tablist");
149*7c478bd9Sstevel@tonic-gate static char usage_msg[] = m_textstr(1834, "\
150*7c478bd9Sstevel@tonic-gate Usage: tabs [-T term] [+m[n]] [-n]\n\
151*7c478bd9Sstevel@tonic-gate tabs [-T term] [+m[n]] -t <tablist>\n\
152*7c478bd9Sstevel@tonic-gate tabs [-T term] [+m[n]] n1[,n2,...]\n\
153*7c478bd9Sstevel@tonic-gate tabs [-T term] [+m[n]] -a|a2|u|c|c2|c3|f|p|s\n", "U");
154*7c478bd9Sstevel@tonic-gate
155*7c478bd9Sstevel@tonic-gate
156*7c478bd9Sstevel@tonic-gate STATREF int do_tabs ANSI((void));
157*7c478bd9Sstevel@tonic-gate STATREF void err_msg ANSI((char *fmt, ...)); /* GENTEXT: err_msg */
158*7c478bd9Sstevel@tonic-gate STATREF void mvcol ANSI((int oc, int nc));
159*7c478bd9Sstevel@tonic-gate STATREF void set_every ANSI((int n));
160*7c478bd9Sstevel@tonic-gate STATREF void set_tab_at ANSI((int x));
161*7c478bd9Sstevel@tonic-gate STATREF int usage ANSI((void));
162*7c478bd9Sstevel@tonic-gate
163*7c478bd9Sstevel@tonic-gate
164*7c478bd9Sstevel@tonic-gate /*f
165*7c478bd9Sstevel@tonic-gate * mainline for tabs
166*7c478bd9Sstevel@tonic-gate */
167*7c478bd9Sstevel@tonic-gate int
main(argc,argv)168*7c478bd9Sstevel@tonic-gate main(argc, argv)
169*7c478bd9Sstevel@tonic-gate int argc;
170*7c478bd9Sstevel@tonic-gate char **argv;
171*7c478bd9Sstevel@tonic-gate {
172*7c478bd9Sstevel@tonic-gate char *ap;
173*7c478bd9Sstevel@tonic-gate int i;
174*7c478bd9Sstevel@tonic-gate int err_code;
175*7c478bd9Sstevel@tonic-gate predefined *p;
176*7c478bd9Sstevel@tonic-gate setlocale(LC_ALL, "");
177*7c478bd9Sstevel@tonic-gate _cmdname = m_cmdname(*argv);
178*7c478bd9Sstevel@tonic-gate if ((term_name = getenv("TERM")) == NULL)
179*7c478bd9Sstevel@tonic-gate term_name = dumb_term;
180*7c478bd9Sstevel@tonic-gate while (0 < --argc && (**++argv == '-' || **argv == '+')) {
181*7c478bd9Sstevel@tonic-gate ap = &argv[0][1];
182*7c478bd9Sstevel@tonic-gate
183*7c478bd9Sstevel@tonic-gate /* Check for standard io '-' */
184*7c478bd9Sstevel@tonic-gate if (*ap == '\0')
185*7c478bd9Sstevel@tonic-gate break;
186*7c478bd9Sstevel@tonic-gate /* End option list '--'? */
187*7c478bd9Sstevel@tonic-gate if (*ap == '-' && ap[1] == '\0') {
188*7c478bd9Sstevel@tonic-gate ++argv;
189*7c478bd9Sstevel@tonic-gate --argc;
190*7c478bd9Sstevel@tonic-gate break;
191*7c478bd9Sstevel@tonic-gate }
192*7c478bd9Sstevel@tonic-gate if (**argv == '-') {
193*7c478bd9Sstevel@tonic-gate /* '-xyz...' or '-xyzF<parm>' or '-xyzF <parm>' */
194*7c478bd9Sstevel@tonic-gate for (;*ap != '\0'; ++ap) {
195*7c478bd9Sstevel@tonic-gate switch (*ap) {
196*7c478bd9Sstevel@tonic-gate case 't':
197*7c478bd9Sstevel@tonic-gate if (form != NO_FORM)
198*7c478bd9Sstevel@tonic-gate return (usage());
199*7c478bd9Sstevel@tonic-gate form = T_FORM;
200*7c478bd9Sstevel@tonic-gate if (*++ap != '\0') {
201*7c478bd9Sstevel@tonic-gate tablist = m_mbstowcsdup(ap);
202*7c478bd9Sstevel@tonic-gate break;
203*7c478bd9Sstevel@tonic-gate } else if (1 < argc) {
204*7c478bd9Sstevel@tonic-gate tablist = m_mbstowcsdup(*++argv);
205*7c478bd9Sstevel@tonic-gate --argc;
206*7c478bd9Sstevel@tonic-gate break;
207*7c478bd9Sstevel@tonic-gate }
208*7c478bd9Sstevel@tonic-gate err_msg(missing_tablist);
209*7c478bd9Sstevel@tonic-gate return (usage());
210*7c478bd9Sstevel@tonic-gate break;
211*7c478bd9Sstevel@tonic-gate case 'T':
212*7c478bd9Sstevel@tonic-gate /* '-T<term>' or '-T <term>' */
213*7c478bd9Sstevel@tonic-gate if (*++ap != '\0') {
214*7c478bd9Sstevel@tonic-gate term_name = ap;
215*7c478bd9Sstevel@tonic-gate break;
216*7c478bd9Sstevel@tonic-gate } else if (1 < argc) {
217*7c478bd9Sstevel@tonic-gate term_name = *++argv;
218*7c478bd9Sstevel@tonic-gate --argc;
219*7c478bd9Sstevel@tonic-gate break;
220*7c478bd9Sstevel@tonic-gate }
221*7c478bd9Sstevel@tonic-gate err_msg(missing_terminal);
222*7c478bd9Sstevel@tonic-gate return (usage());
223*7c478bd9Sstevel@tonic-gate default:
224*7c478bd9Sstevel@tonic-gate if (isdigit(*ap)) {
225*7c478bd9Sstevel@tonic-gate if (form != NO_FORM)
226*7c478bd9Sstevel@tonic-gate return (usage());
227*7c478bd9Sstevel@tonic-gate form = N_FORM;
228*7c478bd9Sstevel@tonic-gate n_width = *ap - '0';
229*7c478bd9Sstevel@tonic-gate continue;
230*7c478bd9Sstevel@tonic-gate }
231*7c478bd9Sstevel@tonic-gate for (p = tabspec;
232*7c478bd9Sstevel@tonic-gate p->option != NULL
233*7c478bd9Sstevel@tonic-gate && strcmp(p->option, ap) != 0;
234*7c478bd9Sstevel@tonic-gate ++p)
235*7c478bd9Sstevel@tonic-gate ;
236*7c478bd9Sstevel@tonic-gate if (p->option != NULL) {
237*7c478bd9Sstevel@tonic-gate form = P_FORM;
238*7c478bd9Sstevel@tonic-gate tablist = m_mbstowcsdup(p->list);
239*7c478bd9Sstevel@tonic-gate break;
240*7c478bd9Sstevel@tonic-gate }
241*7c478bd9Sstevel@tonic-gate err_msg(unknown_option, ap);
242*7c478bd9Sstevel@tonic-gate return (usage());
243*7c478bd9Sstevel@tonic-gate }
244*7c478bd9Sstevel@tonic-gate break;
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate } else {
247*7c478bd9Sstevel@tonic-gate /* All '+' options. */
248*7c478bd9Sstevel@tonic-gate if (*ap == 'm') {
249*7c478bd9Sstevel@tonic-gate margin = (int) strtol(++ap, NULL, 0);
250*7c478bd9Sstevel@tonic-gate if (margin == 0)
251*7c478bd9Sstevel@tonic-gate margin = 10;
252*7c478bd9Sstevel@tonic-gate } else {
253*7c478bd9Sstevel@tonic-gate err_msg(unknown_option, ap);
254*7c478bd9Sstevel@tonic-gate return (usage());
255*7c478bd9Sstevel@tonic-gate }
256*7c478bd9Sstevel@tonic-gate }
257*7c478bd9Sstevel@tonic-gate }
258*7c478bd9Sstevel@tonic-gate if (form == NO_FORM) {
259*7c478bd9Sstevel@tonic-gate switch (argc) {
260*7c478bd9Sstevel@tonic-gate case 0:
261*7c478bd9Sstevel@tonic-gate form = N_FORM;
262*7c478bd9Sstevel@tonic-gate break;
263*7c478bd9Sstevel@tonic-gate case 1:
264*7c478bd9Sstevel@tonic-gate form = P_FORM;
265*7c478bd9Sstevel@tonic-gate tablist = m_mbstowcsdup(*argv);
266*7c478bd9Sstevel@tonic-gate break;
267*7c478bd9Sstevel@tonic-gate default:
268*7c478bd9Sstevel@tonic-gate return (usage());
269*7c478bd9Sstevel@tonic-gate }
270*7c478bd9Sstevel@tonic-gate } else if (0 < argc) {
271*7c478bd9Sstevel@tonic-gate return (usage());
272*7c478bd9Sstevel@tonic-gate }
273*7c478bd9Sstevel@tonic-gate (void) setupterm(term_name, fileno(stdout), &err_code);
274*7c478bd9Sstevel@tonic-gate switch (err_code) {
275*7c478bd9Sstevel@tonic-gate case 1:
276*7c478bd9Sstevel@tonic-gate break;
277*7c478bd9Sstevel@tonic-gate case 0:
278*7c478bd9Sstevel@tonic-gate err_msg(m_textstr(202, "Unknown terminal \"%s\".\n", "E term"), term_name);
279*7c478bd9Sstevel@tonic-gate return (BAD_TERMINAL);
280*7c478bd9Sstevel@tonic-gate case -1:
281*7c478bd9Sstevel@tonic-gate err_msg(m_textstr(203, "No terminfo database.\n", "E"));
282*7c478bd9Sstevel@tonic-gate return (BAD_TERMINAL);
283*7c478bd9Sstevel@tonic-gate }
284*7c478bd9Sstevel@tonic-gate if (save_cursor != NULL)
285*7c478bd9Sstevel@tonic-gate putp(save_cursor);
286*7c478bd9Sstevel@tonic-gate err_code = do_tabs();
287*7c478bd9Sstevel@tonic-gate if (restore_cursor != NULL)
288*7c478bd9Sstevel@tonic-gate putp(restore_cursor);
289*7c478bd9Sstevel@tonic-gate else
290*7c478bd9Sstevel@tonic-gate mvcol(0, 0);
291*7c478bd9Sstevel@tonic-gate return (err_code);
292*7c478bd9Sstevel@tonic-gate }
293*7c478bd9Sstevel@tonic-gate
294*7c478bd9Sstevel@tonic-gate /*f
295*7c478bd9Sstevel@tonic-gate * actually do tabs
296*7c478bd9Sstevel@tonic-gate */
297*7c478bd9Sstevel@tonic-gate STATIC int
do_tabs()298*7c478bd9Sstevel@tonic-gate do_tabs()
299*7c478bd9Sstevel@tonic-gate {
300*7c478bd9Sstevel@tonic-gate int oc = 0;
301*7c478bd9Sstevel@tonic-gate int nc = 0;
302*7c478bd9Sstevel@tonic-gate wchar_t *p = tablist;
303*7c478bd9Sstevel@tonic-gate if (clear_all_tabs == NULL || set_tab == NULL) {
304*7c478bd9Sstevel@tonic-gate err_msg(no_tabs, term_name);
305*7c478bd9Sstevel@tonic-gate return (NOT_DEFINED);
306*7c478bd9Sstevel@tonic-gate }
307*7c478bd9Sstevel@tonic-gate mvcol(0, 0);
308*7c478bd9Sstevel@tonic-gate putp(clear_all_tabs);
309*7c478bd9Sstevel@tonic-gate #if 0 /* margins are not yet supported in terminfo */
310*7c478bd9Sstevel@tonic-gate if (clear_margins == NULL || set_left_margin == NULL) {
311*7c478bd9Sstevel@tonic-gate err_msg(no_margins, term_name);
312*7c478bd9Sstevel@tonic-gate return (NOT_DEFINED);
313*7c478bd9Sstevel@tonic-gate } else {
314*7c478bd9Sstevel@tonic-gate putp(clear_margins);
315*7c478bd9Sstevel@tonic-gate mvcol(0, margin);
316*7c478bd9Sstevel@tonic-gate putp(set_left_margin);
317*7c478bd9Sstevel@tonic-gate }
318*7c478bd9Sstevel@tonic-gate #endif
319*7c478bd9Sstevel@tonic-gate switch (form) {
320*7c478bd9Sstevel@tonic-gate case N_FORM:
321*7c478bd9Sstevel@tonic-gate if (0 < n_width)
322*7c478bd9Sstevel@tonic-gate set_every(n_width);
323*7c478bd9Sstevel@tonic-gate break;
324*7c478bd9Sstevel@tonic-gate case T_FORM:
325*7c478bd9Sstevel@tonic-gate nc = (int) wcstol(p, &p, 0);
326*7c478bd9Sstevel@tonic-gate if (p == tablist || nc < 0) {
327*7c478bd9Sstevel@tonic-gate err_msg(bad_list, tablist);
328*7c478bd9Sstevel@tonic-gate return (NOT_VALID);
329*7c478bd9Sstevel@tonic-gate }
330*7c478bd9Sstevel@tonic-gate if (*p == '\0') {
331*7c478bd9Sstevel@tonic-gate set_every(nc);
332*7c478bd9Sstevel@tonic-gate break;
333*7c478bd9Sstevel@tonic-gate }
334*7c478bd9Sstevel@tonic-gate do {
335*7c478bd9Sstevel@tonic-gate if (nc <= oc) {
336*7c478bd9Sstevel@tonic-gate err_msg(not_ascending, tablist);
337*7c478bd9Sstevel@tonic-gate return (NOT_VALID);
338*7c478bd9Sstevel@tonic-gate }
339*7c478bd9Sstevel@tonic-gate if (*p != '\0' && *p != ',' && !iswblank(*p)) {
340*7c478bd9Sstevel@tonic-gate err_msg(bad_list, tablist);
341*7c478bd9Sstevel@tonic-gate return (NOT_VALID);
342*7c478bd9Sstevel@tonic-gate }
343*7c478bd9Sstevel@tonic-gate ++p;
344*7c478bd9Sstevel@tonic-gate oc = nc;
345*7c478bd9Sstevel@tonic-gate set_tab_at(nc);
346*7c478bd9Sstevel@tonic-gate nc = (int) wcstol(p, &p, 0);
347*7c478bd9Sstevel@tonic-gate } while (nc != 0);
348*7c478bd9Sstevel@tonic-gate break;
349*7c478bd9Sstevel@tonic-gate case P_FORM:
350*7c478bd9Sstevel@tonic-gate if (*p == '+' || *p == '-') {
351*7c478bd9Sstevel@tonic-gate err_msg(bad_list, tablist);
352*7c478bd9Sstevel@tonic-gate return (NOT_VALID);
353*7c478bd9Sstevel@tonic-gate }
354*7c478bd9Sstevel@tonic-gate for (;;) {
355*7c478bd9Sstevel@tonic-gate nc += (int) wcstol(p, &p, 0);
356*7c478bd9Sstevel@tonic-gate if (nc == 0)
357*7c478bd9Sstevel@tonic-gate break;
358*7c478bd9Sstevel@tonic-gate if (nc <= oc) {
359*7c478bd9Sstevel@tonic-gate err_msg(not_ascending, tablist);
360*7c478bd9Sstevel@tonic-gate return (NOT_VALID);
361*7c478bd9Sstevel@tonic-gate }
362*7c478bd9Sstevel@tonic-gate if (*p != '\0' && *p != ',' && !iswblank(*p)) {
363*7c478bd9Sstevel@tonic-gate err_msg(bad_list, tablist);
364*7c478bd9Sstevel@tonic-gate return (NOT_VALID);
365*7c478bd9Sstevel@tonic-gate }
366*7c478bd9Sstevel@tonic-gate ++p;
367*7c478bd9Sstevel@tonic-gate oc = nc;
368*7c478bd9Sstevel@tonic-gate set_tab_at(nc);
369*7c478bd9Sstevel@tonic-gate if (*p == '+')
370*7c478bd9Sstevel@tonic-gate ++p;
371*7c478bd9Sstevel@tonic-gate else
372*7c478bd9Sstevel@tonic-gate nc = 0;
373*7c478bd9Sstevel@tonic-gate }
374*7c478bd9Sstevel@tonic-gate break;
375*7c478bd9Sstevel@tonic-gate }
376*7c478bd9Sstevel@tonic-gate return (SUCCESS);
377*7c478bd9Sstevel@tonic-gate }
378*7c478bd9Sstevel@tonic-gate
379*7c478bd9Sstevel@tonic-gate /*f
380*7c478bd9Sstevel@tonic-gate * Set a tab every n columns starting with column 0.
381*7c478bd9Sstevel@tonic-gate */
382*7c478bd9Sstevel@tonic-gate STATIC void
set_every(n)383*7c478bd9Sstevel@tonic-gate set_every(n)
384*7c478bd9Sstevel@tonic-gate int n;
385*7c478bd9Sstevel@tonic-gate {
386*7c478bd9Sstevel@tonic-gate int x;
387*7c478bd9Sstevel@tonic-gate for (x = 0; x < columns; x += n)
388*7c478bd9Sstevel@tonic-gate set_tab_at(x);
389*7c478bd9Sstevel@tonic-gate }
390*7c478bd9Sstevel@tonic-gate
391*7c478bd9Sstevel@tonic-gate /*f
392*7c478bd9Sstevel@tonic-gate * Set tab at column x. Assume that cursor has been positioned at the
393*7c478bd9Sstevel@tonic-gate * start of the line before settiing the first tab.
394*7c478bd9Sstevel@tonic-gate */
395*7c478bd9Sstevel@tonic-gate STATIC void
set_tab_at(x)396*7c478bd9Sstevel@tonic-gate set_tab_at(x)
397*7c478bd9Sstevel@tonic-gate int x;
398*7c478bd9Sstevel@tonic-gate {
399*7c478bd9Sstevel@tonic-gate static int col = 0;
400*7c478bd9Sstevel@tonic-gate mvcol(col, x);
401*7c478bd9Sstevel@tonic-gate putp(set_tab);
402*7c478bd9Sstevel@tonic-gate col = x;
403*7c478bd9Sstevel@tonic-gate }
404*7c478bd9Sstevel@tonic-gate
405*7c478bd9Sstevel@tonic-gate /*f
406*7c478bd9Sstevel@tonic-gate * Move the cursor on the current row from column 'col' to column 'x'.
407*7c478bd9Sstevel@tonic-gate * We can't use mvcur() because we have no idea what row we're on.
408*7c478bd9Sstevel@tonic-gate */
409*7c478bd9Sstevel@tonic-gate STATIC void
mvcol(oc,nc)410*7c478bd9Sstevel@tonic-gate mvcol(oc, nc)
411*7c478bd9Sstevel@tonic-gate int oc, nc;
412*7c478bd9Sstevel@tonic-gate {
413*7c478bd9Sstevel@tonic-gate int diff = nc - oc;
414*7c478bd9Sstevel@tonic-gate if (nc == 0) {
415*7c478bd9Sstevel@tonic-gate putchar('\r');
416*7c478bd9Sstevel@tonic-gate } else if (column_address != NULL) {
417*7c478bd9Sstevel@tonic-gate putp(tparm(column_address, nc, 0, 0, 0, 0, 0, 0, 0, 0));
418*7c478bd9Sstevel@tonic-gate } else if (parm_right_cursor != NULL) {
419*7c478bd9Sstevel@tonic-gate putp(tparm(parm_right_cursor, diff, 0, 0, 0, 0, 0, 0, 0, 0));
420*7c478bd9Sstevel@tonic-gate } else if (cursor_right != NULL) {
421*7c478bd9Sstevel@tonic-gate while (diff--)
422*7c478bd9Sstevel@tonic-gate putp(cursor_right);
423*7c478bd9Sstevel@tonic-gate } else {
424*7c478bd9Sstevel@tonic-gate while (diff--)
425*7c478bd9Sstevel@tonic-gate putchar(' ');
426*7c478bd9Sstevel@tonic-gate }
427*7c478bd9Sstevel@tonic-gate }
428*7c478bd9Sstevel@tonic-gate
429*7c478bd9Sstevel@tonic-gate /*f
430*7c478bd9Sstevel@tonic-gate * usage message for tabs
431*7c478bd9Sstevel@tonic-gate */
432*7c478bd9Sstevel@tonic-gate STATIC int
usage()433*7c478bd9Sstevel@tonic-gate usage()
434*7c478bd9Sstevel@tonic-gate {
435*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, m_strmsg(usage_msg));
436*7c478bd9Sstevel@tonic-gate return (USAGE);
437*7c478bd9Sstevel@tonic-gate }
438*7c478bd9Sstevel@tonic-gate
439*7c478bd9Sstevel@tonic-gate /*f
440*7c478bd9Sstevel@tonic-gate * display error message
441*7c478bd9Sstevel@tonic-gate */
442*7c478bd9Sstevel@tonic-gate STATIC void
VARARG1(char *,fmt)443*7c478bd9Sstevel@tonic-gate err_msg VARARG1(char*, fmt)
444*7c478bd9Sstevel@tonic-gate {
445*7c478bd9Sstevel@tonic-gate va_list ap;
446*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", _cmdname);
447*7c478bd9Sstevel@tonic-gate va_start(ap, fmt);
448*7c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, m_strmsg(fmt), ap);
449*7c478bd9Sstevel@tonic-gate va_end(ap);
450*7c478bd9Sstevel@tonic-gate }
451