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 1996 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * tabs [tabspec] [+mn] [-Ttype] 34*7c478bd9Sstevel@tonic-gate * set tabs (and margin, if +mn), for terminal type 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #include <stdio.h> 39*7c478bd9Sstevel@tonic-gate #include <signal.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 41*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 42*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 44*7c478bd9Sstevel@tonic-gate #include <curses.h> 45*7c478bd9Sstevel@tonic-gate #include <term.h> 46*7c478bd9Sstevel@tonic-gate #include <locale.h> 47*7c478bd9Sstevel@tonic-gate #include <unistd.h> 48*7c478bd9Sstevel@tonic-gate #include <string.h> 49*7c478bd9Sstevel@tonic-gate #include <ctype.h> 50*7c478bd9Sstevel@tonic-gate #include <limits.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #define EQ(a, b) (strcmp(a, b) == 0) 53*7c478bd9Sstevel@tonic-gate /* max # columns used (needed for GSI) */ 54*7c478bd9Sstevel@tonic-gate #define NCOLS 256 55*7c478bd9Sstevel@tonic-gate #define NTABS 65 /* max # tabs +1 (to be set) */ 56*7c478bd9Sstevel@tonic-gate #define NTABSCL 21 /* max # tabs + 1 that will be cleared */ 57*7c478bd9Sstevel@tonic-gate #define ESC 033 58*7c478bd9Sstevel@tonic-gate #define CLEAR '2' 59*7c478bd9Sstevel@tonic-gate #define SET '1' 60*7c478bd9Sstevel@tonic-gate #define TAB '\t' 61*7c478bd9Sstevel@tonic-gate #define CR '\r' 62*7c478bd9Sstevel@tonic-gate #define NMG 0 /* no margin setting */ 63*7c478bd9Sstevel@tonic-gate #define GMG 1 /* DTC300s margin */ 64*7c478bd9Sstevel@tonic-gate #define TMG 2 /* TERMINET margin */ 65*7c478bd9Sstevel@tonic-gate #define DMG 3 /* DASI450 margin */ 66*7c478bd9Sstevel@tonic-gate #define FMG 4 /* TTY 43 margin */ 67*7c478bd9Sstevel@tonic-gate #define TRMG 5 /* Trendata 4000a */ 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #define TCLRLN 0 /* long, repetitive, general tab clear */ 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate static char tsethp[] = {ESC, '1', 0}; /* (default) */ 72*7c478bd9Sstevel@tonic-gate static char tsetibm[] = {ESC, '0', 0}; /* ibm */ 73*7c478bd9Sstevel@tonic-gate static char tclrhp[] = {ESC, '3', CR, 0}; /* hp terminals */ 74*7c478bd9Sstevel@tonic-gate /* short sequence for many terminals */ 75*7c478bd9Sstevel@tonic-gate static char tclrsh[] = {ESC, CLEAR, CR, 0}; 76*7c478bd9Sstevel@tonic-gate static char tclrgs[] = {ESC, TAB, CR, 0}; /* short, for 300s */ 77*7c478bd9Sstevel@tonic-gate static char tclr40[] = {ESC, 'R', CR, 0}; /* TTY 40/2, 4424 */ 78*7c478bd9Sstevel@tonic-gate static char tclribm[] = {ESC, '1', CR, 0}; /* ibm */ 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate static struct ttab { 81*7c478bd9Sstevel@tonic-gate char *ttype; /* -Tttype */ 82*7c478bd9Sstevel@tonic-gate char *tclr; /* char sequence to clear tabs and return carriage */ 83*7c478bd9Sstevel@tonic-gate int tmaxtab; /* maximum allowed position */ 84*7c478bd9Sstevel@tonic-gate } *tt; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate static struct ttab termtab[] = { 87*7c478bd9Sstevel@tonic-gate "", tclrsh, 132, 88*7c478bd9Sstevel@tonic-gate "1620-12", tclrsh, 158, 89*7c478bd9Sstevel@tonic-gate "1620-12-8", tclrsh, 158, 90*7c478bd9Sstevel@tonic-gate "1700-12", tclrsh, 132, 91*7c478bd9Sstevel@tonic-gate "1700-12-8", tclrsh, 158, 92*7c478bd9Sstevel@tonic-gate "300-12", TCLRLN, 158, 93*7c478bd9Sstevel@tonic-gate "300s-12", tclrgs, 158, 94*7c478bd9Sstevel@tonic-gate "4424", tclr40, 80, 95*7c478bd9Sstevel@tonic-gate "4000a", tclrsh, 132, 96*7c478bd9Sstevel@tonic-gate "4000a-12", tclrsh, 158, 97*7c478bd9Sstevel@tonic-gate "450-12", tclrsh, 158, 98*7c478bd9Sstevel@tonic-gate "450-12-8", tclrsh, 158, 99*7c478bd9Sstevel@tonic-gate "2631", tclrhp, 240, 100*7c478bd9Sstevel@tonic-gate "2631-c", tclrhp, 240, 101*7c478bd9Sstevel@tonic-gate "ibm", tclribm, 80, 102*7c478bd9Sstevel@tonic-gate 0 103*7c478bd9Sstevel@tonic-gate }; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate static int err; 106*7c478bd9Sstevel@tonic-gate static int tmarg; 107*7c478bd9Sstevel@tonic-gate static char settab[32], clear_tabs[32]; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate static int maxtab; /* max tab for repetitive spec */ 110*7c478bd9Sstevel@tonic-gate static int margin; 111*7c478bd9Sstevel@tonic-gate static int margflg; /* >0 ==> +m option used, 0 ==> not */ 112*7c478bd9Sstevel@tonic-gate static char *terminal = ""; 113*7c478bd9Sstevel@tonic-gate static char *tabspec = "-8"; /* default tab specification */ 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate static struct termio ttyold; /* tty table */ 116*7c478bd9Sstevel@tonic-gate static int ttyisave; /* save for input modes */ 117*7c478bd9Sstevel@tonic-gate static int ttyosave; /* save for output modes */ 118*7c478bd9Sstevel@tonic-gate static int istty; /* 1 ==> is actual tty */ 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate static struct stat statbuf; 121*7c478bd9Sstevel@tonic-gate static char *devtty; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate static void scantab(char *scan, int tabvect[NTABS], int level); 124*7c478bd9Sstevel@tonic-gate static void repetab(char *scan, int tabvect[NTABS]); 125*7c478bd9Sstevel@tonic-gate static void arbitab(char *scan, int tabvect[NTABS]); 126*7c478bd9Sstevel@tonic-gate static void filetab(char *scan, int tabvect[NTABS], int level); 127*7c478bd9Sstevel@tonic-gate static int getmarg(char *term); 128*7c478bd9Sstevel@tonic-gate static struct ttab *termadj(); 129*7c478bd9Sstevel@tonic-gate static void settabs(int tabvect[NTABS]); 130*7c478bd9Sstevel@tonic-gate static char *cleartabs(register char *p, char *qq); 131*7c478bd9Sstevel@tonic-gate static int getnum(char **scan1); 132*7c478bd9Sstevel@tonic-gate static void endup(); 133*7c478bd9Sstevel@tonic-gate static int stdtab(char option[], int tabvect[]); 134*7c478bd9Sstevel@tonic-gate static void usage(); 135*7c478bd9Sstevel@tonic-gate static int chk_codes(char *codes); 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate void 138*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 139*7c478bd9Sstevel@tonic-gate { 140*7c478bd9Sstevel@tonic-gate int tabvect[NTABS]; /* build tab list here */ 141*7c478bd9Sstevel@tonic-gate char *scan; /* scan pointer to next char */ 142*7c478bd9Sstevel@tonic-gate char operand[LINE_MAX]; 143*7c478bd9Sstevel@tonic-gate int option_end = 0; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 148*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 149*7c478bd9Sstevel@tonic-gate #endif 150*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate signal(SIGINT, endup); 153*7c478bd9Sstevel@tonic-gate if (ioctl(1, TCGETA, &ttyold) == 0) { 154*7c478bd9Sstevel@tonic-gate ttyisave = ttyold.c_iflag; 155*7c478bd9Sstevel@tonic-gate ttyosave = ttyold.c_oflag; 156*7c478bd9Sstevel@tonic-gate (void) fstat(1, &statbuf); 157*7c478bd9Sstevel@tonic-gate devtty = ttyname(1); 158*7c478bd9Sstevel@tonic-gate (void) chmod(devtty, 0000); /* nobody, not even us */ 159*7c478bd9Sstevel@tonic-gate istty++; 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate tabvect[0] = 0; /* mark as not yet filled in */ 162*7c478bd9Sstevel@tonic-gate while (--argc > 0) { 163*7c478bd9Sstevel@tonic-gate scan = *++argv; 164*7c478bd9Sstevel@tonic-gate if (*scan == '+') { 165*7c478bd9Sstevel@tonic-gate if (!option_end) { 166*7c478bd9Sstevel@tonic-gate if (*++scan == 'm') { 167*7c478bd9Sstevel@tonic-gate margflg++; 168*7c478bd9Sstevel@tonic-gate if (*++scan) 169*7c478bd9Sstevel@tonic-gate margin = getnum(&scan); 170*7c478bd9Sstevel@tonic-gate else 171*7c478bd9Sstevel@tonic-gate margin = 10; 172*7c478bd9Sstevel@tonic-gate } else { 173*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 174*7c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab spec\n"), scan-1); 175*7c478bd9Sstevel@tonic-gate usage(); 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate } else { 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * only n1[,n2,...] operand can follow 180*7c478bd9Sstevel@tonic-gate * end of options delimiter "--" 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 183*7c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab stop operand\n"), scan); 184*7c478bd9Sstevel@tonic-gate usage(); 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate } else if (*scan == '-') { 187*7c478bd9Sstevel@tonic-gate if (!option_end) { 188*7c478bd9Sstevel@tonic-gate if (*(scan+1) == 'T') { 189*7c478bd9Sstevel@tonic-gate /* allow space or no space after -T */ 190*7c478bd9Sstevel@tonic-gate if (*(scan+2) == '\0') { 191*7c478bd9Sstevel@tonic-gate if (--argc > 0) 192*7c478bd9Sstevel@tonic-gate terminal = *++argv; 193*7c478bd9Sstevel@tonic-gate else 194*7c478bd9Sstevel@tonic-gate usage(); 195*7c478bd9Sstevel@tonic-gate } else 196*7c478bd9Sstevel@tonic-gate terminal = scan+2; 197*7c478bd9Sstevel@tonic-gate } else if (*(scan+1) == '-') 198*7c478bd9Sstevel@tonic-gate if (*(scan+2) == '\0') 199*7c478bd9Sstevel@tonic-gate option_end = 1; 200*7c478bd9Sstevel@tonic-gate else 201*7c478bd9Sstevel@tonic-gate tabspec = scan; /* --file */ 202*7c478bd9Sstevel@tonic-gate else if (strcmp(scan+1, "code") == 0); 203*7c478bd9Sstevel@tonic-gate /* skip to next argument */ 204*7c478bd9Sstevel@tonic-gate else if (chk_codes(scan+1) || 205*7c478bd9Sstevel@tonic-gate (isdigit(*(scan+1)) && *(scan+2) == '\0')) { 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * valid code or single digit decimal 208*7c478bd9Sstevel@tonic-gate * number 209*7c478bd9Sstevel@tonic-gate */ 210*7c478bd9Sstevel@tonic-gate tabspec = scan; 211*7c478bd9Sstevel@tonic-gate } else { 212*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 213*7c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab spec\n"), scan); 214*7c478bd9Sstevel@tonic-gate usage(); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate } else { 217*7c478bd9Sstevel@tonic-gate /* 218*7c478bd9Sstevel@tonic-gate * only n1[,n2,...] operand can follow 219*7c478bd9Sstevel@tonic-gate * end of options delimiter "--" 220*7c478bd9Sstevel@tonic-gate */ 221*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 222*7c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab stop operand\n"), scan); 223*7c478bd9Sstevel@tonic-gate usage(); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate } else { 226*7c478bd9Sstevel@tonic-gate /* 227*7c478bd9Sstevel@tonic-gate * Tab-stop values separated using either commas 228*7c478bd9Sstevel@tonic-gate * or blanks. If any number (except the first one) 229*7c478bd9Sstevel@tonic-gate * is preceded by a plus sign, it is taken as an 230*7c478bd9Sstevel@tonic-gate * increment to be added to the previous value. 231*7c478bd9Sstevel@tonic-gate */ 232*7c478bd9Sstevel@tonic-gate operand[0] = '\0'; 233*7c478bd9Sstevel@tonic-gate while (argc > 0) { 234*7c478bd9Sstevel@tonic-gate if (strrchr(*argv, '-') == (char *)NULL) { 235*7c478bd9Sstevel@tonic-gate (void) strcat(operand, *argv); 236*7c478bd9Sstevel@tonic-gate if (argc > 1) 237*7c478bd9Sstevel@tonic-gate (void) strcat(operand, ","); 238*7c478bd9Sstevel@tonic-gate --argc; 239*7c478bd9Sstevel@tonic-gate ++argv; 240*7c478bd9Sstevel@tonic-gate } else { 241*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 242*7c478bd9Sstevel@tonic-gate "tabs: %s: tab stop values must be positive integers\n"), 243*7c478bd9Sstevel@tonic-gate *argv); 244*7c478bd9Sstevel@tonic-gate usage(); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate tabspec = operand; /* save tab specification */ 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate if (*terminal == '\0') { 251*7c478bd9Sstevel@tonic-gate if ((terminal = getenv("TERM")) == (char *)NULL || 252*7c478bd9Sstevel@tonic-gate *terminal == '\0') { 253*7c478bd9Sstevel@tonic-gate /* 254*7c478bd9Sstevel@tonic-gate * Use tab setting and clearing sequences specified 255*7c478bd9Sstevel@tonic-gate * by the ANSI standard. 256*7c478bd9Sstevel@tonic-gate */ 257*7c478bd9Sstevel@tonic-gate terminal = "ansi+tabs"; 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate if (setupterm(terminal, 1, &err) == ERR) { 261*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 262*7c478bd9Sstevel@tonic-gate "tabs: %s: terminfo file not found\n"), terminal); 263*7c478bd9Sstevel@tonic-gate usage(); 264*7c478bd9Sstevel@tonic-gate } else if (!tigetstr("hts")) { 265*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 266*7c478bd9Sstevel@tonic-gate "tabs: cannot set tabs on terminal type %s\n"), terminal); 267*7c478bd9Sstevel@tonic-gate usage(); 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate if (err <= 0 || columns <= 0 || set_tab == 0) { 270*7c478bd9Sstevel@tonic-gate tt = termadj(); 271*7c478bd9Sstevel@tonic-gate if (strcmp(terminal, "ibm") == 0) 272*7c478bd9Sstevel@tonic-gate (void) strcpy(settab, tsetibm); 273*7c478bd9Sstevel@tonic-gate else 274*7c478bd9Sstevel@tonic-gate (void) strcpy(settab, tsethp); 275*7c478bd9Sstevel@tonic-gate (void) strcpy(clear_tabs, tt->tclr); 276*7c478bd9Sstevel@tonic-gate maxtab = tt->tmaxtab; 277*7c478bd9Sstevel@tonic-gate } else { 278*7c478bd9Sstevel@tonic-gate maxtab = columns; 279*7c478bd9Sstevel@tonic-gate (void) strcpy(settab, set_tab); 280*7c478bd9Sstevel@tonic-gate (void) strcpy(clear_tabs, clear_all_tabs); 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate scantab(tabspec, tabvect, 0); 283*7c478bd9Sstevel@tonic-gate if (!tabvect[0]) 284*7c478bd9Sstevel@tonic-gate repetab("8", tabvect); 285*7c478bd9Sstevel@tonic-gate settabs(tabvect); 286*7c478bd9Sstevel@tonic-gate endup(); 287*7c478bd9Sstevel@tonic-gate exit(0); 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate /* 291*7c478bd9Sstevel@tonic-gate * return 1 if code option is valid, otherwise return 0 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate int 294*7c478bd9Sstevel@tonic-gate chk_codes(char *code) 295*7c478bd9Sstevel@tonic-gate { 296*7c478bd9Sstevel@tonic-gate if (*(code+1) == '\0' && (*code == 'a' || *code == 'c' || 297*7c478bd9Sstevel@tonic-gate *code == 'f' || *code == 'p' || *code == 's' || *code == 'u')) 298*7c478bd9Sstevel@tonic-gate return (1); 299*7c478bd9Sstevel@tonic-gate else if (*(code+1) == '2' && *(code+2) == '\0' && 300*7c478bd9Sstevel@tonic-gate (*code == 'a' || *code == 'c')) 301*7c478bd9Sstevel@tonic-gate return (1); 302*7c478bd9Sstevel@tonic-gate else if (*code == 'c' && *(code+1) == '3' && *(code+2) == '\0') 303*7c478bd9Sstevel@tonic-gate return (1); 304*7c478bd9Sstevel@tonic-gate return (0); 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* scantab: scan 1 tabspec & return tab list for it */ 308*7c478bd9Sstevel@tonic-gate void 309*7c478bd9Sstevel@tonic-gate scantab(char *scan, int tabvect[NTABS], int level) 310*7c478bd9Sstevel@tonic-gate { 311*7c478bd9Sstevel@tonic-gate register char c; 312*7c478bd9Sstevel@tonic-gate if (*scan == '-') 313*7c478bd9Sstevel@tonic-gate if ((c = *++scan) == '-') 314*7c478bd9Sstevel@tonic-gate filetab(++scan, tabvect, level); 315*7c478bd9Sstevel@tonic-gate else if (c >= '0' && c <= '9') 316*7c478bd9Sstevel@tonic-gate repetab(scan, tabvect); 317*7c478bd9Sstevel@tonic-gate else if (stdtab(scan, tabvect)) { 318*7c478bd9Sstevel@tonic-gate endup(); 319*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 320*7c478bd9Sstevel@tonic-gate "tabs: %s: unknown tab code\n"), scan); 321*7c478bd9Sstevel@tonic-gate usage(); 322*7c478bd9Sstevel@tonic-gate } else; 323*7c478bd9Sstevel@tonic-gate else 324*7c478bd9Sstevel@tonic-gate arbitab(scan, tabvect); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate /* repetab: scan and set repetitve tabs, 1+n, 1+2*n, etc */ 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate void 330*7c478bd9Sstevel@tonic-gate repetab(char *scan, int tabvect[NTABS]) 331*7c478bd9Sstevel@tonic-gate { 332*7c478bd9Sstevel@tonic-gate register incr, i, tabn; 333*7c478bd9Sstevel@tonic-gate int limit; 334*7c478bd9Sstevel@tonic-gate incr = getnum(&scan); 335*7c478bd9Sstevel@tonic-gate tabn = 1; 336*7c478bd9Sstevel@tonic-gate limit = (maxtab-1)/(incr?incr:1)-1; /* # last actual tab */ 337*7c478bd9Sstevel@tonic-gate if (limit > NTABS-2) 338*7c478bd9Sstevel@tonic-gate limit = NTABS-2; 339*7c478bd9Sstevel@tonic-gate for (i = 0; i <= limit; i++) 340*7c478bd9Sstevel@tonic-gate tabvect[i] = tabn += incr; 341*7c478bd9Sstevel@tonic-gate tabvect[i] = 0; 342*7c478bd9Sstevel@tonic-gate } 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate /* arbitab: handle list of arbitrary tabs */ 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate void 347*7c478bd9Sstevel@tonic-gate arbitab(char *scan, int tabvect[NTABS]) 348*7c478bd9Sstevel@tonic-gate { 349*7c478bd9Sstevel@tonic-gate char *scan_save; 350*7c478bd9Sstevel@tonic-gate register i, t, last; 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate scan_save = scan; 353*7c478bd9Sstevel@tonic-gate last = 0; 354*7c478bd9Sstevel@tonic-gate for (i = 0; i < NTABS-1; ) { 355*7c478bd9Sstevel@tonic-gate if (*scan == '+') { 356*7c478bd9Sstevel@tonic-gate scan++; /* +n ==> increment, not absolute */ 357*7c478bd9Sstevel@tonic-gate if (t = getnum(&scan)) 358*7c478bd9Sstevel@tonic-gate tabvect[i++] = last += t; 359*7c478bd9Sstevel@tonic-gate else { 360*7c478bd9Sstevel@tonic-gate endup(); 361*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 362*7c478bd9Sstevel@tonic-gate "tabs: %s: invalid increment\n"), scan_save); 363*7c478bd9Sstevel@tonic-gate usage(); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate } else { 366*7c478bd9Sstevel@tonic-gate if ((t = getnum(&scan)) > last) 367*7c478bd9Sstevel@tonic-gate tabvect[i++] = last = t; 368*7c478bd9Sstevel@tonic-gate else { 369*7c478bd9Sstevel@tonic-gate endup(); 370*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 371*7c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab stop\n"), scan_save); 372*7c478bd9Sstevel@tonic-gate usage(); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate if (*scan++ != ',') break; 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate if (last > NCOLS) { 378*7c478bd9Sstevel@tonic-gate endup(); 379*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 380*7c478bd9Sstevel@tonic-gate "tabs: %s: last tab stop would be set at a column greater than %d\n"), 381*7c478bd9Sstevel@tonic-gate scan_save, NCOLS); 382*7c478bd9Sstevel@tonic-gate usage(); 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate tabvect[i] = 0; 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* filetab: copy tabspec from existing file */ 388*7c478bd9Sstevel@tonic-gate #define CARDSIZ 132 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate void 391*7c478bd9Sstevel@tonic-gate filetab(char *scan, int tabvect[NTABS], int level) 392*7c478bd9Sstevel@tonic-gate { 393*7c478bd9Sstevel@tonic-gate register length, i; 394*7c478bd9Sstevel@tonic-gate register char c; 395*7c478bd9Sstevel@tonic-gate int fildes; 396*7c478bd9Sstevel@tonic-gate char card[CARDSIZ]; /* buffer area for 1st card in file */ 397*7c478bd9Sstevel@tonic-gate char state, found; 398*7c478bd9Sstevel@tonic-gate char *temp; 399*7c478bd9Sstevel@tonic-gate if (level) { 400*7c478bd9Sstevel@tonic-gate endup(); 401*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 402*7c478bd9Sstevel@tonic-gate "tabs: %s points to another file: invalid file indirection\n"), 403*7c478bd9Sstevel@tonic-gate scan); 404*7c478bd9Sstevel@tonic-gate exit(1); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate if ((fildes = open(scan, O_RDONLY)) < 0) { 407*7c478bd9Sstevel@tonic-gate endup(); 408*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("tabs: %s: "), scan); 409*7c478bd9Sstevel@tonic-gate perror(""); 410*7c478bd9Sstevel@tonic-gate exit(1); 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate length = read(fildes, card, CARDSIZ); 413*7c478bd9Sstevel@tonic-gate (void) close(fildes); 414*7c478bd9Sstevel@tonic-gate found = state = 0; 415*7c478bd9Sstevel@tonic-gate scan = 0; 416*7c478bd9Sstevel@tonic-gate for (i = 0; i < length && (c = card[i]) != '\n'; i++) { 417*7c478bd9Sstevel@tonic-gate switch (state) { 418*7c478bd9Sstevel@tonic-gate case 0: 419*7c478bd9Sstevel@tonic-gate state = (c == '<'); break; 420*7c478bd9Sstevel@tonic-gate case 1: 421*7c478bd9Sstevel@tonic-gate state = (c == ':')?2:0; break; 422*7c478bd9Sstevel@tonic-gate case 2: 423*7c478bd9Sstevel@tonic-gate if (c == 't') 424*7c478bd9Sstevel@tonic-gate state = 3; 425*7c478bd9Sstevel@tonic-gate else if (c == ':') 426*7c478bd9Sstevel@tonic-gate state = 6; 427*7c478bd9Sstevel@tonic-gate else if (c != ' ') 428*7c478bd9Sstevel@tonic-gate state = 5; 429*7c478bd9Sstevel@tonic-gate break; 430*7c478bd9Sstevel@tonic-gate case 3: 431*7c478bd9Sstevel@tonic-gate if (c == ' ') 432*7c478bd9Sstevel@tonic-gate state = 2; 433*7c478bd9Sstevel@tonic-gate else { 434*7c478bd9Sstevel@tonic-gate scan = &card[i]; 435*7c478bd9Sstevel@tonic-gate state = 4; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate break; 438*7c478bd9Sstevel@tonic-gate case 4: 439*7c478bd9Sstevel@tonic-gate if (c == ' ') { 440*7c478bd9Sstevel@tonic-gate card[i] = '\0'; 441*7c478bd9Sstevel@tonic-gate state = 5; 442*7c478bd9Sstevel@tonic-gate } else if (c == ':') { 443*7c478bd9Sstevel@tonic-gate card[i] = '\0'; 444*7c478bd9Sstevel@tonic-gate state = 6; 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate break; 447*7c478bd9Sstevel@tonic-gate case 5: 448*7c478bd9Sstevel@tonic-gate if (c == ' ') 449*7c478bd9Sstevel@tonic-gate state = 2; 450*7c478bd9Sstevel@tonic-gate else if (c == ':') 451*7c478bd9Sstevel@tonic-gate state = 6; 452*7c478bd9Sstevel@tonic-gate break; 453*7c478bd9Sstevel@tonic-gate case 6: 454*7c478bd9Sstevel@tonic-gate if (c == '>') { 455*7c478bd9Sstevel@tonic-gate found = 1; 456*7c478bd9Sstevel@tonic-gate goto done; 457*7c478bd9Sstevel@tonic-gate } else state = 5; 458*7c478bd9Sstevel@tonic-gate break; 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate done: 462*7c478bd9Sstevel@tonic-gate if (found && scan != 0) { 463*7c478bd9Sstevel@tonic-gate scantab(scan, tabvect, 1); 464*7c478bd9Sstevel@tonic-gate temp = scan; 465*7c478bd9Sstevel@tonic-gate while (*++temp); 466*7c478bd9Sstevel@tonic-gate *temp = '\n'; 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate else 469*7c478bd9Sstevel@tonic-gate scantab("-8", tabvect, 1); 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate int 473*7c478bd9Sstevel@tonic-gate getmarg(char *term) 474*7c478bd9Sstevel@tonic-gate { 475*7c478bd9Sstevel@tonic-gate if (strncmp(term, "1620", 4) == 0 || 476*7c478bd9Sstevel@tonic-gate strncmp(term, "1700", 4) == 0 || strncmp(term, "450", 3) == 0) 477*7c478bd9Sstevel@tonic-gate return (DMG); 478*7c478bd9Sstevel@tonic-gate else if (strncmp(term, "300s", 4) == 0) 479*7c478bd9Sstevel@tonic-gate return (GMG); 480*7c478bd9Sstevel@tonic-gate else if (strncmp(term, "4000a", 5) == 0) 481*7c478bd9Sstevel@tonic-gate return (TRMG); 482*7c478bd9Sstevel@tonic-gate else if (strcmp(term, "43") == 0) 483*7c478bd9Sstevel@tonic-gate return (FMG); 484*7c478bd9Sstevel@tonic-gate else if (strcmp(term, "tn300") == 0 || strcmp(term, "tn1200") == 0) 485*7c478bd9Sstevel@tonic-gate return (TMG); 486*7c478bd9Sstevel@tonic-gate else 487*7c478bd9Sstevel@tonic-gate return (NMG); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate struct ttab * 493*7c478bd9Sstevel@tonic-gate termadj() 494*7c478bd9Sstevel@tonic-gate { 495*7c478bd9Sstevel@tonic-gate register struct ttab *t; 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate if (strncmp(terminal, "40-2", 4) == 0 || strncmp(terminal, 498*7c478bd9Sstevel@tonic-gate "40/2", 4) == 0 || strncmp(terminal, "4420", 4) == 0) 499*7c478bd9Sstevel@tonic-gate (void) strcpy(terminal, "4424"); 500*7c478bd9Sstevel@tonic-gate else if (strncmp(terminal, "ibm", 3) == 0 || strcmp(terminal, 501*7c478bd9Sstevel@tonic-gate "3101") == 0 || strcmp(terminal, "system1") == 0) 502*7c478bd9Sstevel@tonic-gate (void) strcpy(terminal, "ibm"); 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate for (t = termtab; t->ttype; t++) { 505*7c478bd9Sstevel@tonic-gate if (EQ(terminal, t->ttype)) 506*7c478bd9Sstevel@tonic-gate return (t); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate /* should have message */ 509*7c478bd9Sstevel@tonic-gate return (termtab); 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate char *cleartabs(); 513*7c478bd9Sstevel@tonic-gate /* 514*7c478bd9Sstevel@tonic-gate * settabs: set actual tabs at terminal 515*7c478bd9Sstevel@tonic-gate * note: this code caters to necessities of handling GSI and 516*7c478bd9Sstevel@tonic-gate * other terminals in a consistent way. 517*7c478bd9Sstevel@tonic-gate */ 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate void 520*7c478bd9Sstevel@tonic-gate settabs(int tabvect[NTABS]) 521*7c478bd9Sstevel@tonic-gate { 522*7c478bd9Sstevel@tonic-gate char setbuf[512]; /* 2+3*NTABS+2+NCOLS+NTABS (+ some extra) */ 523*7c478bd9Sstevel@tonic-gate register char *p; /* ptr for assembly in setbuf */ 524*7c478bd9Sstevel@tonic-gate register *curtab; /* ptr to tabvect item */ 525*7c478bd9Sstevel@tonic-gate int i, previous, nblanks; 526*7c478bd9Sstevel@tonic-gate if (istty) { 527*7c478bd9Sstevel@tonic-gate ttyold.c_iflag &= ~ICRNL; 528*7c478bd9Sstevel@tonic-gate ttyold.c_oflag &= ~(ONLCR|OCRNL|ONOCR|ONLRET); 529*7c478bd9Sstevel@tonic-gate (void) ioctl(1, TCSETAW, &ttyold); /* turn off cr-lf map */ 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate p = setbuf; 532*7c478bd9Sstevel@tonic-gate *p++ = CR; 533*7c478bd9Sstevel@tonic-gate p = cleartabs(p, clear_tabs); 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate if (margflg) { 536*7c478bd9Sstevel@tonic-gate tmarg = getmarg(terminal); 537*7c478bd9Sstevel@tonic-gate switch (tmarg) { 538*7c478bd9Sstevel@tonic-gate case GMG: /* GSI300S */ 539*7c478bd9Sstevel@tonic-gate /* 540*7c478bd9Sstevel@tonic-gate * NOTE: the 300S appears somewhat odd, in that there is 541*7c478bd9Sstevel@tonic-gate * a column 0, but there is no way to do a direct tab to it. 542*7c478bd9Sstevel@tonic-gate * The sequence ESC 'T' '\0' jumps to column 27 and prints 543*7c478bd9Sstevel@tonic-gate * a '0', without changing the margin. 544*7c478bd9Sstevel@tonic-gate */ 545*7c478bd9Sstevel@tonic-gate *p++ = ESC; 546*7c478bd9Sstevel@tonic-gate *p++ = 'T'; /* setup for direct tab */ 547*7c478bd9Sstevel@tonic-gate if (margin &= 0177) /* normal case */ 548*7c478bd9Sstevel@tonic-gate *p++ = margin; 549*7c478bd9Sstevel@tonic-gate else { /* +m0 case */ 550*7c478bd9Sstevel@tonic-gate *p++ = 1; /* column 1 */ 551*7c478bd9Sstevel@tonic-gate *p++ = '\b'; /* column 0 */ 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate *p++ = margin; /* direct horizontal tab */ 554*7c478bd9Sstevel@tonic-gate *p++ = ESC; 555*7c478bd9Sstevel@tonic-gate *p++ = '0'; /* actual margin set */ 556*7c478bd9Sstevel@tonic-gate break; 557*7c478bd9Sstevel@tonic-gate case TMG: /* TERMINET 300 & 1200 */ 558*7c478bd9Sstevel@tonic-gate while (margin--) 559*7c478bd9Sstevel@tonic-gate *p++ = ' '; 560*7c478bd9Sstevel@tonic-gate break; 561*7c478bd9Sstevel@tonic-gate case DMG: /* DASI450/DIABLO 1620 */ 562*7c478bd9Sstevel@tonic-gate *p++ = ESC; /* direct tab ignores margin */ 563*7c478bd9Sstevel@tonic-gate *p++ = '\t'; 564*7c478bd9Sstevel@tonic-gate if (margin == 3) { 565*7c478bd9Sstevel@tonic-gate *p++ = (margin & 0177); 566*7c478bd9Sstevel@tonic-gate *p++ = ' '; 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate else 569*7c478bd9Sstevel@tonic-gate *p++ = (margin & 0177) + 1; 570*7c478bd9Sstevel@tonic-gate *p++ = ESC; 571*7c478bd9Sstevel@tonic-gate *p++ = '9'; 572*7c478bd9Sstevel@tonic-gate break; 573*7c478bd9Sstevel@tonic-gate case FMG: /* TTY 43 */ 574*7c478bd9Sstevel@tonic-gate p--; 575*7c478bd9Sstevel@tonic-gate *p++ = ESC; 576*7c478bd9Sstevel@tonic-gate *p++ = 'x'; 577*7c478bd9Sstevel@tonic-gate *p++ = CR; 578*7c478bd9Sstevel@tonic-gate while (margin--) 579*7c478bd9Sstevel@tonic-gate *p++ = ' '; 580*7c478bd9Sstevel@tonic-gate *p++ = ESC; 581*7c478bd9Sstevel@tonic-gate *p++ = 'l'; 582*7c478bd9Sstevel@tonic-gate *p++ = CR; 583*7c478bd9Sstevel@tonic-gate (void) write(1, setbuf, p - setbuf); 584*7c478bd9Sstevel@tonic-gate return; 585*7c478bd9Sstevel@tonic-gate case TRMG: 586*7c478bd9Sstevel@tonic-gate p--; 587*7c478bd9Sstevel@tonic-gate *p++ = ESC; 588*7c478bd9Sstevel@tonic-gate *p++ = 'N'; 589*7c478bd9Sstevel@tonic-gate while (margin--) 590*7c478bd9Sstevel@tonic-gate *p++ = ' '; 591*7c478bd9Sstevel@tonic-gate *p++ = ESC; 592*7c478bd9Sstevel@tonic-gate *p++ = 'F'; 593*7c478bd9Sstevel@tonic-gate break; 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate /* 598*7c478bd9Sstevel@tonic-gate * actual setting: at least terminals do this consistently! 599*7c478bd9Sstevel@tonic-gate */ 600*7c478bd9Sstevel@tonic-gate previous = 1; curtab = tabvect; 601*7c478bd9Sstevel@tonic-gate while ((nblanks = *curtab-previous) >= 0 && 602*7c478bd9Sstevel@tonic-gate previous + nblanks <= maxtab) { 603*7c478bd9Sstevel@tonic-gate for (i = 1; i <= nblanks; i++) *p++ = ' '; 604*7c478bd9Sstevel@tonic-gate previous = *curtab++; 605*7c478bd9Sstevel@tonic-gate (void) strcpy(p, settab); 606*7c478bd9Sstevel@tonic-gate p += strlen(settab); 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate *p++ = CR; 609*7c478bd9Sstevel@tonic-gate if (EQ(terminal, "4424")) 610*7c478bd9Sstevel@tonic-gate *p++ = '\n'; /* TTY40/2 needs LF, not just CR */ 611*7c478bd9Sstevel@tonic-gate (void) write(1, setbuf, p - setbuf); 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate /* 616*7c478bd9Sstevel@tonic-gate * Set software tabs. This only works on UNIX/370 using a series/1 617*7c478bd9Sstevel@tonic-gate * front-end processor. 618*7c478bd9Sstevel@tonic-gate */ 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate /* cleartabs(pointer to buffer, pointer to clear sequence) */ 622*7c478bd9Sstevel@tonic-gate char * 623*7c478bd9Sstevel@tonic-gate cleartabs(register char *p, char *qq) 624*7c478bd9Sstevel@tonic-gate { 625*7c478bd9Sstevel@tonic-gate register i; 626*7c478bd9Sstevel@tonic-gate register char *q; 627*7c478bd9Sstevel@tonic-gate q = qq; 628*7c478bd9Sstevel@tonic-gate if (clear_tabs == 0) { /* if repetitive sequence */ 629*7c478bd9Sstevel@tonic-gate *p++ = CR; 630*7c478bd9Sstevel@tonic-gate for (i = 0; i < NTABSCL - 1; i++) { 631*7c478bd9Sstevel@tonic-gate *p++ = TAB; 632*7c478bd9Sstevel@tonic-gate *p++ = ESC; 633*7c478bd9Sstevel@tonic-gate *p++ = CLEAR; 634*7c478bd9Sstevel@tonic-gate } 635*7c478bd9Sstevel@tonic-gate *p++ = CR; 636*7c478bd9Sstevel@tonic-gate } else { 637*7c478bd9Sstevel@tonic-gate while (*p++ = *q++); /* copy table sequence */ 638*7c478bd9Sstevel@tonic-gate p--; /* adjust for null */ 639*7c478bd9Sstevel@tonic-gate if (EQ(terminal, "4424")) { /* TTY40 extra delays needed */ 640*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 641*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 642*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 643*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate return (p); 647*7c478bd9Sstevel@tonic-gate } 648*7c478bd9Sstevel@tonic-gate /* getnum: scan and convert number, return zero if none found */ 649*7c478bd9Sstevel@tonic-gate /* set scan ptr to addr of ending delimeter */ 650*7c478bd9Sstevel@tonic-gate int 651*7c478bd9Sstevel@tonic-gate getnum(char **scan1) 652*7c478bd9Sstevel@tonic-gate { 653*7c478bd9Sstevel@tonic-gate register n; 654*7c478bd9Sstevel@tonic-gate register char c, *scan; 655*7c478bd9Sstevel@tonic-gate n = 0; 656*7c478bd9Sstevel@tonic-gate scan = *scan1; 657*7c478bd9Sstevel@tonic-gate while ((c = *scan++) >= '0' && c <= '9') n = n * 10 + c -'0'; 658*7c478bd9Sstevel@tonic-gate *scan1 = --scan; 659*7c478bd9Sstevel@tonic-gate return (n); 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate /* usage: terminate processing with usage message */ 663*7c478bd9Sstevel@tonic-gate void 664*7c478bd9Sstevel@tonic-gate usage() 665*7c478bd9Sstevel@tonic-gate { 666*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 667*7c478bd9Sstevel@tonic-gate "usage: tabs [ -n| --file| [[-code] -a| -a2| -c| -c2| -c3| -f| -p| -s| -u]] \ 668*7c478bd9Sstevel@tonic-gate [+m[n]] [-T type]\n")); 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 671*7c478bd9Sstevel@tonic-gate " tabs [-T type][+m[n]] n1[,n2,...]\n")); 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate endup(); 674*7c478bd9Sstevel@tonic-gate exit(1); 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* endup: make sure tty mode reset & exit */ 678*7c478bd9Sstevel@tonic-gate void 679*7c478bd9Sstevel@tonic-gate endup() 680*7c478bd9Sstevel@tonic-gate { 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate if (istty) { 683*7c478bd9Sstevel@tonic-gate ttyold.c_iflag = ttyisave; 684*7c478bd9Sstevel@tonic-gate ttyold.c_oflag = ttyosave; 685*7c478bd9Sstevel@tonic-gate /* reset cr-lf to previous */ 686*7c478bd9Sstevel@tonic-gate (void) ioctl(1, TCSETAW, &ttyold); 687*7c478bd9Sstevel@tonic-gate (void) chmod(devtty, statbuf.st_mode); 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate if (err > 0) { 690*7c478bd9Sstevel@tonic-gate (void) resetterm(); 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate /* 695*7c478bd9Sstevel@tonic-gate * stdtabs: standard tabs table 696*7c478bd9Sstevel@tonic-gate * format: option code letter(s), null, tabs, null 697*7c478bd9Sstevel@tonic-gate */ 698*7c478bd9Sstevel@tonic-gate static char stdtabs[] = { 699*7c478bd9Sstevel@tonic-gate 'a', 0, 1, 10, 16, 36, 72, 0, /* IBM 370 Assembler */ 700*7c478bd9Sstevel@tonic-gate 'a', '2', 0, 1, 10, 16, 40, 72, 0, /* IBM Assembler alternative */ 701*7c478bd9Sstevel@tonic-gate 'c', 0, 1, 8, 12, 16, 20, 55, 0, /* COBOL, normal */ 702*7c478bd9Sstevel@tonic-gate 'c', '2', 0, 1, 6, 10, 14, 49, 0, /* COBOL, crunched */ 703*7c478bd9Sstevel@tonic-gate 'c', '3', 0, 1, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 67, 704*7c478bd9Sstevel@tonic-gate 0, /* crunched COBOL, many tabs */ 705*7c478bd9Sstevel@tonic-gate 'f', 0, 1, 7, 11, 15, 19, 23, 0, /* FORTRAN */ 706*7c478bd9Sstevel@tonic-gate 'p', 0, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 0, 707*7c478bd9Sstevel@tonic-gate /* PL/I */ 708*7c478bd9Sstevel@tonic-gate 's', 0, 1, 10, 55, 0, /* SNOBOL */ 709*7c478bd9Sstevel@tonic-gate 'u', 0, 1, 12, 20, 44, 0, /* UNIVAC ASM */ 710*7c478bd9Sstevel@tonic-gate 0}; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate /* 713*7c478bd9Sstevel@tonic-gate * stdtab: return tab list for any "canned" tab option. 714*7c478bd9Sstevel@tonic-gate * entry: option points to null-terminated option string 715*7c478bd9Sstevel@tonic-gate * tabvect points to vector to be filled in 716*7c478bd9Sstevel@tonic-gate * exit: return (0) if legal, tabvect filled, ending with zero 717*7c478bd9Sstevel@tonic-gate * return (-1) if unknown option 718*7c478bd9Sstevel@tonic-gate */ 719*7c478bd9Sstevel@tonic-gate int 720*7c478bd9Sstevel@tonic-gate stdtab(char option[], int tabvect[]) 721*7c478bd9Sstevel@tonic-gate { 722*7c478bd9Sstevel@tonic-gate register char *sp; 723*7c478bd9Sstevel@tonic-gate tabvect[0] = 0; 724*7c478bd9Sstevel@tonic-gate sp = stdtabs; 725*7c478bd9Sstevel@tonic-gate while (*sp) { 726*7c478bd9Sstevel@tonic-gate if (EQ(option, sp)) { 727*7c478bd9Sstevel@tonic-gate while (*sp++); /* skip to 1st tab value */ 728*7c478bd9Sstevel@tonic-gate while (*tabvect++ = *sp++); /* copy, make int */ 729*7c478bd9Sstevel@tonic-gate return (0); 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate while (*sp++); /* skip to 1st tab value */ 732*7c478bd9Sstevel@tonic-gate while (*sp++); /* skip over tab list */ 733*7c478bd9Sstevel@tonic-gate } 734*7c478bd9Sstevel@tonic-gate return (-1); 735*7c478bd9Sstevel@tonic-gate } 736