17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 1996 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * tabs [tabspec] [+mn] [-Ttype] 347c478bd9Sstevel@tonic-gate * set tabs (and margin, if +mn), for terminal type 357c478bd9Sstevel@tonic-gate */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include <stdio.h> 397c478bd9Sstevel@tonic-gate #include <signal.h> 407c478bd9Sstevel@tonic-gate #include <sys/types.h> 417c478bd9Sstevel@tonic-gate #include <stdlib.h> 427c478bd9Sstevel@tonic-gate #include <fcntl.h> 437c478bd9Sstevel@tonic-gate #include <sys/stat.h> 447c478bd9Sstevel@tonic-gate #include <curses.h> 457c478bd9Sstevel@tonic-gate #include <term.h> 467c478bd9Sstevel@tonic-gate #include <locale.h> 477c478bd9Sstevel@tonic-gate #include <unistd.h> 487c478bd9Sstevel@tonic-gate #include <string.h> 497c478bd9Sstevel@tonic-gate #include <ctype.h> 507c478bd9Sstevel@tonic-gate #include <limits.h> 51*8d489c7aSmuffin #include <signal.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #define EQ(a, b) (strcmp(a, b) == 0) 547c478bd9Sstevel@tonic-gate /* max # columns used (needed for GSI) */ 557c478bd9Sstevel@tonic-gate #define NCOLS 256 567c478bd9Sstevel@tonic-gate #define NTABS 65 /* max # tabs +1 (to be set) */ 577c478bd9Sstevel@tonic-gate #define NTABSCL 21 /* max # tabs + 1 that will be cleared */ 587c478bd9Sstevel@tonic-gate #define ESC 033 597c478bd9Sstevel@tonic-gate #define CLEAR '2' 607c478bd9Sstevel@tonic-gate #define SET '1' 617c478bd9Sstevel@tonic-gate #define TAB '\t' 627c478bd9Sstevel@tonic-gate #define CR '\r' 637c478bd9Sstevel@tonic-gate #define NMG 0 /* no margin setting */ 647c478bd9Sstevel@tonic-gate #define GMG 1 /* DTC300s margin */ 657c478bd9Sstevel@tonic-gate #define TMG 2 /* TERMINET margin */ 667c478bd9Sstevel@tonic-gate #define DMG 3 /* DASI450 margin */ 677c478bd9Sstevel@tonic-gate #define FMG 4 /* TTY 43 margin */ 687c478bd9Sstevel@tonic-gate #define TRMG 5 /* Trendata 4000a */ 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #define TCLRLN 0 /* long, repetitive, general tab clear */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate static char tsethp[] = {ESC, '1', 0}; /* (default) */ 737c478bd9Sstevel@tonic-gate static char tsetibm[] = {ESC, '0', 0}; /* ibm */ 747c478bd9Sstevel@tonic-gate static char tclrhp[] = {ESC, '3', CR, 0}; /* hp terminals */ 757c478bd9Sstevel@tonic-gate /* short sequence for many terminals */ 767c478bd9Sstevel@tonic-gate static char tclrsh[] = {ESC, CLEAR, CR, 0}; 777c478bd9Sstevel@tonic-gate static char tclrgs[] = {ESC, TAB, CR, 0}; /* short, for 300s */ 787c478bd9Sstevel@tonic-gate static char tclr40[] = {ESC, 'R', CR, 0}; /* TTY 40/2, 4424 */ 797c478bd9Sstevel@tonic-gate static char tclribm[] = {ESC, '1', CR, 0}; /* ibm */ 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate static struct ttab { 827c478bd9Sstevel@tonic-gate char *ttype; /* -Tttype */ 837c478bd9Sstevel@tonic-gate char *tclr; /* char sequence to clear tabs and return carriage */ 847c478bd9Sstevel@tonic-gate int tmaxtab; /* maximum allowed position */ 857c478bd9Sstevel@tonic-gate } *tt; 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate static struct ttab termtab[] = { 887c478bd9Sstevel@tonic-gate "", tclrsh, 132, 897c478bd9Sstevel@tonic-gate "1620-12", tclrsh, 158, 907c478bd9Sstevel@tonic-gate "1620-12-8", tclrsh, 158, 917c478bd9Sstevel@tonic-gate "1700-12", tclrsh, 132, 927c478bd9Sstevel@tonic-gate "1700-12-8", tclrsh, 158, 937c478bd9Sstevel@tonic-gate "300-12", TCLRLN, 158, 947c478bd9Sstevel@tonic-gate "300s-12", tclrgs, 158, 957c478bd9Sstevel@tonic-gate "4424", tclr40, 80, 967c478bd9Sstevel@tonic-gate "4000a", tclrsh, 132, 977c478bd9Sstevel@tonic-gate "4000a-12", tclrsh, 158, 987c478bd9Sstevel@tonic-gate "450-12", tclrsh, 158, 997c478bd9Sstevel@tonic-gate "450-12-8", tclrsh, 158, 1007c478bd9Sstevel@tonic-gate "2631", tclrhp, 240, 1017c478bd9Sstevel@tonic-gate "2631-c", tclrhp, 240, 1027c478bd9Sstevel@tonic-gate "ibm", tclribm, 80, 1037c478bd9Sstevel@tonic-gate 0 1047c478bd9Sstevel@tonic-gate }; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate static int err; 1077c478bd9Sstevel@tonic-gate static int tmarg; 1087c478bd9Sstevel@tonic-gate static char settab[32], clear_tabs[32]; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate static int maxtab; /* max tab for repetitive spec */ 1117c478bd9Sstevel@tonic-gate static int margin; 1127c478bd9Sstevel@tonic-gate static int margflg; /* >0 ==> +m option used, 0 ==> not */ 1137c478bd9Sstevel@tonic-gate static char *terminal = ""; 1147c478bd9Sstevel@tonic-gate static char *tabspec = "-8"; /* default tab specification */ 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate static struct termio ttyold; /* tty table */ 1177c478bd9Sstevel@tonic-gate static int ttyisave; /* save for input modes */ 1187c478bd9Sstevel@tonic-gate static int ttyosave; /* save for output modes */ 1197c478bd9Sstevel@tonic-gate static int istty; /* 1 ==> is actual tty */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate static struct stat statbuf; 1227c478bd9Sstevel@tonic-gate static char *devtty; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate static void scantab(char *scan, int tabvect[NTABS], int level); 1257c478bd9Sstevel@tonic-gate static void repetab(char *scan, int tabvect[NTABS]); 1267c478bd9Sstevel@tonic-gate static void arbitab(char *scan, int tabvect[NTABS]); 1277c478bd9Sstevel@tonic-gate static void filetab(char *scan, int tabvect[NTABS], int level); 1287c478bd9Sstevel@tonic-gate static int getmarg(char *term); 1297c478bd9Sstevel@tonic-gate static struct ttab *termadj(); 1307c478bd9Sstevel@tonic-gate static void settabs(int tabvect[NTABS]); 1317c478bd9Sstevel@tonic-gate static char *cleartabs(register char *p, char *qq); 1327c478bd9Sstevel@tonic-gate static int getnum(char **scan1); 1337c478bd9Sstevel@tonic-gate static void endup(); 1347c478bd9Sstevel@tonic-gate static int stdtab(char option[], int tabvect[]); 1357c478bd9Sstevel@tonic-gate static void usage(); 1367c478bd9Sstevel@tonic-gate static int chk_codes(char *codes); 1377c478bd9Sstevel@tonic-gate 138*8d489c7aSmuffin int 1397c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1407c478bd9Sstevel@tonic-gate { 1417c478bd9Sstevel@tonic-gate int tabvect[NTABS]; /* build tab list here */ 1427c478bd9Sstevel@tonic-gate char *scan; /* scan pointer to next char */ 1437c478bd9Sstevel@tonic-gate char operand[LINE_MAX]; 1447c478bd9Sstevel@tonic-gate int option_end = 0; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1497c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1507c478bd9Sstevel@tonic-gate #endif 1517c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1527c478bd9Sstevel@tonic-gate 153*8d489c7aSmuffin (void) signal(SIGINT, endup); 1547c478bd9Sstevel@tonic-gate if (ioctl(1, TCGETA, &ttyold) == 0) { 1557c478bd9Sstevel@tonic-gate ttyisave = ttyold.c_iflag; 1567c478bd9Sstevel@tonic-gate ttyosave = ttyold.c_oflag; 1577c478bd9Sstevel@tonic-gate (void) fstat(1, &statbuf); 1587c478bd9Sstevel@tonic-gate devtty = ttyname(1); 1597c478bd9Sstevel@tonic-gate (void) chmod(devtty, 0000); /* nobody, not even us */ 1607c478bd9Sstevel@tonic-gate istty++; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate tabvect[0] = 0; /* mark as not yet filled in */ 1637c478bd9Sstevel@tonic-gate while (--argc > 0) { 1647c478bd9Sstevel@tonic-gate scan = *++argv; 1657c478bd9Sstevel@tonic-gate if (*scan == '+') { 1667c478bd9Sstevel@tonic-gate if (!option_end) { 1677c478bd9Sstevel@tonic-gate if (*++scan == 'm') { 1687c478bd9Sstevel@tonic-gate margflg++; 1697c478bd9Sstevel@tonic-gate if (*++scan) 1707c478bd9Sstevel@tonic-gate margin = getnum(&scan); 1717c478bd9Sstevel@tonic-gate else 1727c478bd9Sstevel@tonic-gate margin = 10; 1737c478bd9Sstevel@tonic-gate } else { 1747c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1757c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab spec\n"), scan-1); 1767c478bd9Sstevel@tonic-gate usage(); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate } else { 1797c478bd9Sstevel@tonic-gate /* 1807c478bd9Sstevel@tonic-gate * only n1[,n2,...] operand can follow 1817c478bd9Sstevel@tonic-gate * end of options delimiter "--" 1827c478bd9Sstevel@tonic-gate */ 1837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1847c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab stop operand\n"), scan); 1857c478bd9Sstevel@tonic-gate usage(); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate } else if (*scan == '-') { 1887c478bd9Sstevel@tonic-gate if (!option_end) { 1897c478bd9Sstevel@tonic-gate if (*(scan+1) == 'T') { 1907c478bd9Sstevel@tonic-gate /* allow space or no space after -T */ 1917c478bd9Sstevel@tonic-gate if (*(scan+2) == '\0') { 1927c478bd9Sstevel@tonic-gate if (--argc > 0) 1937c478bd9Sstevel@tonic-gate terminal = *++argv; 1947c478bd9Sstevel@tonic-gate else 1957c478bd9Sstevel@tonic-gate usage(); 1967c478bd9Sstevel@tonic-gate } else 1977c478bd9Sstevel@tonic-gate terminal = scan+2; 1987c478bd9Sstevel@tonic-gate } else if (*(scan+1) == '-') 1997c478bd9Sstevel@tonic-gate if (*(scan+2) == '\0') 2007c478bd9Sstevel@tonic-gate option_end = 1; 2017c478bd9Sstevel@tonic-gate else 2027c478bd9Sstevel@tonic-gate tabspec = scan; /* --file */ 203*8d489c7aSmuffin else if (strcmp(scan+1, "code") == 0) { 204*8d489c7aSmuffin /* EMPTY */ 2057c478bd9Sstevel@tonic-gate /* skip to next argument */ 206*8d489c7aSmuffin } else if (chk_codes(scan+1) || 2077c478bd9Sstevel@tonic-gate (isdigit(*(scan+1)) && *(scan+2) == '\0')) { 2087c478bd9Sstevel@tonic-gate /* 2097c478bd9Sstevel@tonic-gate * valid code or single digit decimal 2107c478bd9Sstevel@tonic-gate * number 2117c478bd9Sstevel@tonic-gate */ 2127c478bd9Sstevel@tonic-gate tabspec = scan; 2137c478bd9Sstevel@tonic-gate } else { 2147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2157c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab spec\n"), scan); 2167c478bd9Sstevel@tonic-gate usage(); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate } else { 2197c478bd9Sstevel@tonic-gate /* 2207c478bd9Sstevel@tonic-gate * only n1[,n2,...] operand can follow 2217c478bd9Sstevel@tonic-gate * end of options delimiter "--" 2227c478bd9Sstevel@tonic-gate */ 2237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2247c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab stop operand\n"), scan); 2257c478bd9Sstevel@tonic-gate usage(); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate } else { 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * Tab-stop values separated using either commas 2307c478bd9Sstevel@tonic-gate * or blanks. If any number (except the first one) 2317c478bd9Sstevel@tonic-gate * is preceded by a plus sign, it is taken as an 2327c478bd9Sstevel@tonic-gate * increment to be added to the previous value. 2337c478bd9Sstevel@tonic-gate */ 2347c478bd9Sstevel@tonic-gate operand[0] = '\0'; 2357c478bd9Sstevel@tonic-gate while (argc > 0) { 2367c478bd9Sstevel@tonic-gate if (strrchr(*argv, '-') == (char *)NULL) { 2377c478bd9Sstevel@tonic-gate (void) strcat(operand, *argv); 2387c478bd9Sstevel@tonic-gate if (argc > 1) 2397c478bd9Sstevel@tonic-gate (void) strcat(operand, ","); 2407c478bd9Sstevel@tonic-gate --argc; 2417c478bd9Sstevel@tonic-gate ++argv; 2427c478bd9Sstevel@tonic-gate } else { 2437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2447c478bd9Sstevel@tonic-gate "tabs: %s: tab stop values must be positive integers\n"), 2457c478bd9Sstevel@tonic-gate *argv); 2467c478bd9Sstevel@tonic-gate usage(); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate tabspec = operand; /* save tab specification */ 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate if (*terminal == '\0') { 2537c478bd9Sstevel@tonic-gate if ((terminal = getenv("TERM")) == (char *)NULL || 2547c478bd9Sstevel@tonic-gate *terminal == '\0') { 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * Use tab setting and clearing sequences specified 2577c478bd9Sstevel@tonic-gate * by the ANSI standard. 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate terminal = "ansi+tabs"; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate if (setupterm(terminal, 1, &err) == ERR) { 2637c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2647c478bd9Sstevel@tonic-gate "tabs: %s: terminfo file not found\n"), terminal); 2657c478bd9Sstevel@tonic-gate usage(); 2667c478bd9Sstevel@tonic-gate } else if (!tigetstr("hts")) { 2677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2687c478bd9Sstevel@tonic-gate "tabs: cannot set tabs on terminal type %s\n"), terminal); 2697c478bd9Sstevel@tonic-gate usage(); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate if (err <= 0 || columns <= 0 || set_tab == 0) { 2727c478bd9Sstevel@tonic-gate tt = termadj(); 2737c478bd9Sstevel@tonic-gate if (strcmp(terminal, "ibm") == 0) 2747c478bd9Sstevel@tonic-gate (void) strcpy(settab, tsetibm); 2757c478bd9Sstevel@tonic-gate else 2767c478bd9Sstevel@tonic-gate (void) strcpy(settab, tsethp); 2777c478bd9Sstevel@tonic-gate (void) strcpy(clear_tabs, tt->tclr); 2787c478bd9Sstevel@tonic-gate maxtab = tt->tmaxtab; 2797c478bd9Sstevel@tonic-gate } else { 2807c478bd9Sstevel@tonic-gate maxtab = columns; 2817c478bd9Sstevel@tonic-gate (void) strcpy(settab, set_tab); 2827c478bd9Sstevel@tonic-gate (void) strcpy(clear_tabs, clear_all_tabs); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate scantab(tabspec, tabvect, 0); 2857c478bd9Sstevel@tonic-gate if (!tabvect[0]) 2867c478bd9Sstevel@tonic-gate repetab("8", tabvect); 2877c478bd9Sstevel@tonic-gate settabs(tabvect); 2887c478bd9Sstevel@tonic-gate endup(); 289*8d489c7aSmuffin return (0); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * return 1 if code option is valid, otherwise return 0 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate int 2967c478bd9Sstevel@tonic-gate chk_codes(char *code) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate if (*(code+1) == '\0' && (*code == 'a' || *code == 'c' || 2997c478bd9Sstevel@tonic-gate *code == 'f' || *code == 'p' || *code == 's' || *code == 'u')) 3007c478bd9Sstevel@tonic-gate return (1); 3017c478bd9Sstevel@tonic-gate else if (*(code+1) == '2' && *(code+2) == '\0' && 3027c478bd9Sstevel@tonic-gate (*code == 'a' || *code == 'c')) 3037c478bd9Sstevel@tonic-gate return (1); 3047c478bd9Sstevel@tonic-gate else if (*code == 'c' && *(code+1) == '3' && *(code+2) == '\0') 3057c478bd9Sstevel@tonic-gate return (1); 3067c478bd9Sstevel@tonic-gate return (0); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate /* scantab: scan 1 tabspec & return tab list for it */ 3107c478bd9Sstevel@tonic-gate void 3117c478bd9Sstevel@tonic-gate scantab(char *scan, int tabvect[NTABS], int level) 3127c478bd9Sstevel@tonic-gate { 313*8d489c7aSmuffin char c; 314*8d489c7aSmuffin if (*scan == '-') { 3157c478bd9Sstevel@tonic-gate if ((c = *++scan) == '-') 3167c478bd9Sstevel@tonic-gate filetab(++scan, tabvect, level); 3177c478bd9Sstevel@tonic-gate else if (c >= '0' && c <= '9') 3187c478bd9Sstevel@tonic-gate repetab(scan, tabvect); 3197c478bd9Sstevel@tonic-gate else if (stdtab(scan, tabvect)) { 3207c478bd9Sstevel@tonic-gate endup(); 3217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3227c478bd9Sstevel@tonic-gate "tabs: %s: unknown tab code\n"), scan); 3237c478bd9Sstevel@tonic-gate usage(); 324*8d489c7aSmuffin } 325*8d489c7aSmuffin } else { 3267c478bd9Sstevel@tonic-gate arbitab(scan, tabvect); 3277c478bd9Sstevel@tonic-gate } 328*8d489c7aSmuffin } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate /* repetab: scan and set repetitve tabs, 1+n, 1+2*n, etc */ 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate void 3337c478bd9Sstevel@tonic-gate repetab(char *scan, int tabvect[NTABS]) 3347c478bd9Sstevel@tonic-gate { 335*8d489c7aSmuffin int incr, i, tabn; 3367c478bd9Sstevel@tonic-gate int limit; 3377c478bd9Sstevel@tonic-gate incr = getnum(&scan); 3387c478bd9Sstevel@tonic-gate tabn = 1; 3397c478bd9Sstevel@tonic-gate limit = (maxtab-1)/(incr?incr:1)-1; /* # last actual tab */ 3407c478bd9Sstevel@tonic-gate if (limit > NTABS-2) 3417c478bd9Sstevel@tonic-gate limit = NTABS-2; 3427c478bd9Sstevel@tonic-gate for (i = 0; i <= limit; i++) 3437c478bd9Sstevel@tonic-gate tabvect[i] = tabn += incr; 3447c478bd9Sstevel@tonic-gate tabvect[i] = 0; 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* arbitab: handle list of arbitrary tabs */ 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate void 3507c478bd9Sstevel@tonic-gate arbitab(char *scan, int tabvect[NTABS]) 3517c478bd9Sstevel@tonic-gate { 3527c478bd9Sstevel@tonic-gate char *scan_save; 353*8d489c7aSmuffin int i, t, last; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate scan_save = scan; 3567c478bd9Sstevel@tonic-gate last = 0; 3577c478bd9Sstevel@tonic-gate for (i = 0; i < NTABS-1; ) { 3587c478bd9Sstevel@tonic-gate if (*scan == '+') { 3597c478bd9Sstevel@tonic-gate scan++; /* +n ==> increment, not absolute */ 3607c478bd9Sstevel@tonic-gate if (t = getnum(&scan)) 3617c478bd9Sstevel@tonic-gate tabvect[i++] = last += t; 3627c478bd9Sstevel@tonic-gate else { 3637c478bd9Sstevel@tonic-gate endup(); 3647c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3657c478bd9Sstevel@tonic-gate "tabs: %s: invalid increment\n"), scan_save); 3667c478bd9Sstevel@tonic-gate usage(); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate } else { 3697c478bd9Sstevel@tonic-gate if ((t = getnum(&scan)) > last) 3707c478bd9Sstevel@tonic-gate tabvect[i++] = last = t; 3717c478bd9Sstevel@tonic-gate else { 3727c478bd9Sstevel@tonic-gate endup(); 3737c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3747c478bd9Sstevel@tonic-gate "tabs: %s: invalid tab stop\n"), scan_save); 3757c478bd9Sstevel@tonic-gate usage(); 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate if (*scan++ != ',') break; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate if (last > NCOLS) { 3817c478bd9Sstevel@tonic-gate endup(); 3827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3837c478bd9Sstevel@tonic-gate "tabs: %s: last tab stop would be set at a column greater than %d\n"), 3847c478bd9Sstevel@tonic-gate scan_save, NCOLS); 3857c478bd9Sstevel@tonic-gate usage(); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate tabvect[i] = 0; 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate /* filetab: copy tabspec from existing file */ 3917c478bd9Sstevel@tonic-gate #define CARDSIZ 132 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate void 3947c478bd9Sstevel@tonic-gate filetab(char *scan, int tabvect[NTABS], int level) 3957c478bd9Sstevel@tonic-gate { 396*8d489c7aSmuffin int length, i; 397*8d489c7aSmuffin char c; 3987c478bd9Sstevel@tonic-gate int fildes; 3997c478bd9Sstevel@tonic-gate char card[CARDSIZ]; /* buffer area for 1st card in file */ 4007c478bd9Sstevel@tonic-gate char state, found; 4017c478bd9Sstevel@tonic-gate char *temp; 4027c478bd9Sstevel@tonic-gate if (level) { 4037c478bd9Sstevel@tonic-gate endup(); 4047c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 4057c478bd9Sstevel@tonic-gate "tabs: %s points to another file: invalid file indirection\n"), 4067c478bd9Sstevel@tonic-gate scan); 4077c478bd9Sstevel@tonic-gate exit(1); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate if ((fildes = open(scan, O_RDONLY)) < 0) { 4107c478bd9Sstevel@tonic-gate endup(); 4117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("tabs: %s: "), scan); 4127c478bd9Sstevel@tonic-gate perror(""); 4137c478bd9Sstevel@tonic-gate exit(1); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate length = read(fildes, card, CARDSIZ); 4167c478bd9Sstevel@tonic-gate (void) close(fildes); 4177c478bd9Sstevel@tonic-gate found = state = 0; 4187c478bd9Sstevel@tonic-gate scan = 0; 4197c478bd9Sstevel@tonic-gate for (i = 0; i < length && (c = card[i]) != '\n'; i++) { 4207c478bd9Sstevel@tonic-gate switch (state) { 4217c478bd9Sstevel@tonic-gate case 0: 4227c478bd9Sstevel@tonic-gate state = (c == '<'); break; 4237c478bd9Sstevel@tonic-gate case 1: 4247c478bd9Sstevel@tonic-gate state = (c == ':')?2:0; break; 4257c478bd9Sstevel@tonic-gate case 2: 4267c478bd9Sstevel@tonic-gate if (c == 't') 4277c478bd9Sstevel@tonic-gate state = 3; 4287c478bd9Sstevel@tonic-gate else if (c == ':') 4297c478bd9Sstevel@tonic-gate state = 6; 4307c478bd9Sstevel@tonic-gate else if (c != ' ') 4317c478bd9Sstevel@tonic-gate state = 5; 4327c478bd9Sstevel@tonic-gate break; 4337c478bd9Sstevel@tonic-gate case 3: 4347c478bd9Sstevel@tonic-gate if (c == ' ') 4357c478bd9Sstevel@tonic-gate state = 2; 4367c478bd9Sstevel@tonic-gate else { 4377c478bd9Sstevel@tonic-gate scan = &card[i]; 4387c478bd9Sstevel@tonic-gate state = 4; 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate break; 4417c478bd9Sstevel@tonic-gate case 4: 4427c478bd9Sstevel@tonic-gate if (c == ' ') { 4437c478bd9Sstevel@tonic-gate card[i] = '\0'; 4447c478bd9Sstevel@tonic-gate state = 5; 4457c478bd9Sstevel@tonic-gate } else if (c == ':') { 4467c478bd9Sstevel@tonic-gate card[i] = '\0'; 4477c478bd9Sstevel@tonic-gate state = 6; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate break; 4507c478bd9Sstevel@tonic-gate case 5: 4517c478bd9Sstevel@tonic-gate if (c == ' ') 4527c478bd9Sstevel@tonic-gate state = 2; 4537c478bd9Sstevel@tonic-gate else if (c == ':') 4547c478bd9Sstevel@tonic-gate state = 6; 4557c478bd9Sstevel@tonic-gate break; 4567c478bd9Sstevel@tonic-gate case 6: 4577c478bd9Sstevel@tonic-gate if (c == '>') { 4587c478bd9Sstevel@tonic-gate found = 1; 4597c478bd9Sstevel@tonic-gate goto done; 4607c478bd9Sstevel@tonic-gate } else state = 5; 4617c478bd9Sstevel@tonic-gate break; 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate done: 4657c478bd9Sstevel@tonic-gate if (found && scan != 0) { 4667c478bd9Sstevel@tonic-gate scantab(scan, tabvect, 1); 4677c478bd9Sstevel@tonic-gate temp = scan; 468*8d489c7aSmuffin while (*++temp) 469*8d489c7aSmuffin ; 4707c478bd9Sstevel@tonic-gate *temp = '\n'; 4717c478bd9Sstevel@tonic-gate } 4727c478bd9Sstevel@tonic-gate else 4737c478bd9Sstevel@tonic-gate scantab("-8", tabvect, 1); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate int 4777c478bd9Sstevel@tonic-gate getmarg(char *term) 4787c478bd9Sstevel@tonic-gate { 4797c478bd9Sstevel@tonic-gate if (strncmp(term, "1620", 4) == 0 || 4807c478bd9Sstevel@tonic-gate strncmp(term, "1700", 4) == 0 || strncmp(term, "450", 3) == 0) 4817c478bd9Sstevel@tonic-gate return (DMG); 4827c478bd9Sstevel@tonic-gate else if (strncmp(term, "300s", 4) == 0) 4837c478bd9Sstevel@tonic-gate return (GMG); 4847c478bd9Sstevel@tonic-gate else if (strncmp(term, "4000a", 5) == 0) 4857c478bd9Sstevel@tonic-gate return (TRMG); 4867c478bd9Sstevel@tonic-gate else if (strcmp(term, "43") == 0) 4877c478bd9Sstevel@tonic-gate return (FMG); 4887c478bd9Sstevel@tonic-gate else if (strcmp(term, "tn300") == 0 || strcmp(term, "tn1200") == 0) 4897c478bd9Sstevel@tonic-gate return (TMG); 4907c478bd9Sstevel@tonic-gate else 4917c478bd9Sstevel@tonic-gate return (NMG); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate struct ttab * 497*8d489c7aSmuffin termadj(void) 4987c478bd9Sstevel@tonic-gate { 499*8d489c7aSmuffin struct ttab *t; 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate if (strncmp(terminal, "40-2", 4) == 0 || strncmp(terminal, 5027c478bd9Sstevel@tonic-gate "40/2", 4) == 0 || strncmp(terminal, "4420", 4) == 0) 5037c478bd9Sstevel@tonic-gate (void) strcpy(terminal, "4424"); 5047c478bd9Sstevel@tonic-gate else if (strncmp(terminal, "ibm", 3) == 0 || strcmp(terminal, 5057c478bd9Sstevel@tonic-gate "3101") == 0 || strcmp(terminal, "system1") == 0) 5067c478bd9Sstevel@tonic-gate (void) strcpy(terminal, "ibm"); 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate for (t = termtab; t->ttype; t++) { 5097c478bd9Sstevel@tonic-gate if (EQ(terminal, t->ttype)) 5107c478bd9Sstevel@tonic-gate return (t); 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate /* should have message */ 5137c478bd9Sstevel@tonic-gate return (termtab); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate char *cleartabs(); 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * settabs: set actual tabs at terminal 5197c478bd9Sstevel@tonic-gate * note: this code caters to necessities of handling GSI and 5207c478bd9Sstevel@tonic-gate * other terminals in a consistent way. 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate void 5247c478bd9Sstevel@tonic-gate settabs(int tabvect[NTABS]) 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate char setbuf[512]; /* 2+3*NTABS+2+NCOLS+NTABS (+ some extra) */ 527*8d489c7aSmuffin char *p; /* ptr for assembly in setbuf */ 528*8d489c7aSmuffin int *curtab; /* ptr to tabvect item */ 5297c478bd9Sstevel@tonic-gate int i, previous, nblanks; 5307c478bd9Sstevel@tonic-gate if (istty) { 5317c478bd9Sstevel@tonic-gate ttyold.c_iflag &= ~ICRNL; 5327c478bd9Sstevel@tonic-gate ttyold.c_oflag &= ~(ONLCR|OCRNL|ONOCR|ONLRET); 5337c478bd9Sstevel@tonic-gate (void) ioctl(1, TCSETAW, &ttyold); /* turn off cr-lf map */ 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate p = setbuf; 5367c478bd9Sstevel@tonic-gate *p++ = CR; 5377c478bd9Sstevel@tonic-gate p = cleartabs(p, clear_tabs); 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate if (margflg) { 5407c478bd9Sstevel@tonic-gate tmarg = getmarg(terminal); 5417c478bd9Sstevel@tonic-gate switch (tmarg) { 5427c478bd9Sstevel@tonic-gate case GMG: /* GSI300S */ 5437c478bd9Sstevel@tonic-gate /* 5447c478bd9Sstevel@tonic-gate * NOTE: the 300S appears somewhat odd, in that there is 5457c478bd9Sstevel@tonic-gate * a column 0, but there is no way to do a direct tab to it. 5467c478bd9Sstevel@tonic-gate * The sequence ESC 'T' '\0' jumps to column 27 and prints 5477c478bd9Sstevel@tonic-gate * a '0', without changing the margin. 5487c478bd9Sstevel@tonic-gate */ 5497c478bd9Sstevel@tonic-gate *p++ = ESC; 5507c478bd9Sstevel@tonic-gate *p++ = 'T'; /* setup for direct tab */ 5517c478bd9Sstevel@tonic-gate if (margin &= 0177) /* normal case */ 5527c478bd9Sstevel@tonic-gate *p++ = margin; 5537c478bd9Sstevel@tonic-gate else { /* +m0 case */ 5547c478bd9Sstevel@tonic-gate *p++ = 1; /* column 1 */ 5557c478bd9Sstevel@tonic-gate *p++ = '\b'; /* column 0 */ 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate *p++ = margin; /* direct horizontal tab */ 5587c478bd9Sstevel@tonic-gate *p++ = ESC; 5597c478bd9Sstevel@tonic-gate *p++ = '0'; /* actual margin set */ 5607c478bd9Sstevel@tonic-gate break; 5617c478bd9Sstevel@tonic-gate case TMG: /* TERMINET 300 & 1200 */ 5627c478bd9Sstevel@tonic-gate while (margin--) 5637c478bd9Sstevel@tonic-gate *p++ = ' '; 5647c478bd9Sstevel@tonic-gate break; 5657c478bd9Sstevel@tonic-gate case DMG: /* DASI450/DIABLO 1620 */ 5667c478bd9Sstevel@tonic-gate *p++ = ESC; /* direct tab ignores margin */ 5677c478bd9Sstevel@tonic-gate *p++ = '\t'; 5687c478bd9Sstevel@tonic-gate if (margin == 3) { 5697c478bd9Sstevel@tonic-gate *p++ = (margin & 0177); 5707c478bd9Sstevel@tonic-gate *p++ = ' '; 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate else 5737c478bd9Sstevel@tonic-gate *p++ = (margin & 0177) + 1; 5747c478bd9Sstevel@tonic-gate *p++ = ESC; 5757c478bd9Sstevel@tonic-gate *p++ = '9'; 5767c478bd9Sstevel@tonic-gate break; 5777c478bd9Sstevel@tonic-gate case FMG: /* TTY 43 */ 5787c478bd9Sstevel@tonic-gate p--; 5797c478bd9Sstevel@tonic-gate *p++ = ESC; 5807c478bd9Sstevel@tonic-gate *p++ = 'x'; 5817c478bd9Sstevel@tonic-gate *p++ = CR; 5827c478bd9Sstevel@tonic-gate while (margin--) 5837c478bd9Sstevel@tonic-gate *p++ = ' '; 5847c478bd9Sstevel@tonic-gate *p++ = ESC; 5857c478bd9Sstevel@tonic-gate *p++ = 'l'; 5867c478bd9Sstevel@tonic-gate *p++ = CR; 5877c478bd9Sstevel@tonic-gate (void) write(1, setbuf, p - setbuf); 5887c478bd9Sstevel@tonic-gate return; 5897c478bd9Sstevel@tonic-gate case TRMG: 5907c478bd9Sstevel@tonic-gate p--; 5917c478bd9Sstevel@tonic-gate *p++ = ESC; 5927c478bd9Sstevel@tonic-gate *p++ = 'N'; 5937c478bd9Sstevel@tonic-gate while (margin--) 5947c478bd9Sstevel@tonic-gate *p++ = ' '; 5957c478bd9Sstevel@tonic-gate *p++ = ESC; 5967c478bd9Sstevel@tonic-gate *p++ = 'F'; 5977c478bd9Sstevel@tonic-gate break; 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate /* 6027c478bd9Sstevel@tonic-gate * actual setting: at least terminals do this consistently! 6037c478bd9Sstevel@tonic-gate */ 6047c478bd9Sstevel@tonic-gate previous = 1; curtab = tabvect; 6057c478bd9Sstevel@tonic-gate while ((nblanks = *curtab-previous) >= 0 && 6067c478bd9Sstevel@tonic-gate previous + nblanks <= maxtab) { 6077c478bd9Sstevel@tonic-gate for (i = 1; i <= nblanks; i++) *p++ = ' '; 6087c478bd9Sstevel@tonic-gate previous = *curtab++; 6097c478bd9Sstevel@tonic-gate (void) strcpy(p, settab); 6107c478bd9Sstevel@tonic-gate p += strlen(settab); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate *p++ = CR; 6137c478bd9Sstevel@tonic-gate if (EQ(terminal, "4424")) 6147c478bd9Sstevel@tonic-gate *p++ = '\n'; /* TTY40/2 needs LF, not just CR */ 6157c478bd9Sstevel@tonic-gate (void) write(1, setbuf, p - setbuf); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate /* 6207c478bd9Sstevel@tonic-gate * Set software tabs. This only works on UNIX/370 using a series/1 6217c478bd9Sstevel@tonic-gate * front-end processor. 6227c478bd9Sstevel@tonic-gate */ 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate /* cleartabs(pointer to buffer, pointer to clear sequence) */ 6267c478bd9Sstevel@tonic-gate char * 6277c478bd9Sstevel@tonic-gate cleartabs(register char *p, char *qq) 6287c478bd9Sstevel@tonic-gate { 629*8d489c7aSmuffin int i; 630*8d489c7aSmuffin char *q; 6317c478bd9Sstevel@tonic-gate q = qq; 6327c478bd9Sstevel@tonic-gate if (clear_tabs == 0) { /* if repetitive sequence */ 6337c478bd9Sstevel@tonic-gate *p++ = CR; 6347c478bd9Sstevel@tonic-gate for (i = 0; i < NTABSCL - 1; i++) { 6357c478bd9Sstevel@tonic-gate *p++ = TAB; 6367c478bd9Sstevel@tonic-gate *p++ = ESC; 6377c478bd9Sstevel@tonic-gate *p++ = CLEAR; 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate *p++ = CR; 6407c478bd9Sstevel@tonic-gate } else { 641*8d489c7aSmuffin while (*p++ = *q++) /* copy table sequence */ 642*8d489c7aSmuffin ; 6437c478bd9Sstevel@tonic-gate p--; /* adjust for null */ 6447c478bd9Sstevel@tonic-gate if (EQ(terminal, "4424")) { /* TTY40 extra delays needed */ 6457c478bd9Sstevel@tonic-gate *p++ = '\0'; 6467c478bd9Sstevel@tonic-gate *p++ = '\0'; 6477c478bd9Sstevel@tonic-gate *p++ = '\0'; 6487c478bd9Sstevel@tonic-gate *p++ = '\0'; 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate return (p); 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate /* getnum: scan and convert number, return zero if none found */ 6547c478bd9Sstevel@tonic-gate /* set scan ptr to addr of ending delimeter */ 6557c478bd9Sstevel@tonic-gate int 6567c478bd9Sstevel@tonic-gate getnum(char **scan1) 6577c478bd9Sstevel@tonic-gate { 658*8d489c7aSmuffin int n; 659*8d489c7aSmuffin char c, *scan; 6607c478bd9Sstevel@tonic-gate n = 0; 6617c478bd9Sstevel@tonic-gate scan = *scan1; 6627c478bd9Sstevel@tonic-gate while ((c = *scan++) >= '0' && c <= '9') n = n * 10 + c -'0'; 6637c478bd9Sstevel@tonic-gate *scan1 = --scan; 6647c478bd9Sstevel@tonic-gate return (n); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate /* usage: terminate processing with usage message */ 6687c478bd9Sstevel@tonic-gate void 669*8d489c7aSmuffin usage(void) 6707c478bd9Sstevel@tonic-gate { 6717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 6727c478bd9Sstevel@tonic-gate "usage: tabs [ -n| --file| [[-code] -a| -a2| -c| -c2| -c3| -f| -p| -s| -u]] \ 6737c478bd9Sstevel@tonic-gate [+m[n]] [-T type]\n")); 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 6767c478bd9Sstevel@tonic-gate " tabs [-T type][+m[n]] n1[,n2,...]\n")); 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate endup(); 6797c478bd9Sstevel@tonic-gate exit(1); 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate /* endup: make sure tty mode reset & exit */ 6837c478bd9Sstevel@tonic-gate void 684*8d489c7aSmuffin endup(void) 6857c478bd9Sstevel@tonic-gate { 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate if (istty) { 6887c478bd9Sstevel@tonic-gate ttyold.c_iflag = ttyisave; 6897c478bd9Sstevel@tonic-gate ttyold.c_oflag = ttyosave; 6907c478bd9Sstevel@tonic-gate /* reset cr-lf to previous */ 6917c478bd9Sstevel@tonic-gate (void) ioctl(1, TCSETAW, &ttyold); 6927c478bd9Sstevel@tonic-gate (void) chmod(devtty, statbuf.st_mode); 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate if (err > 0) { 6957c478bd9Sstevel@tonic-gate (void) resetterm(); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate /* 7007c478bd9Sstevel@tonic-gate * stdtabs: standard tabs table 7017c478bd9Sstevel@tonic-gate * format: option code letter(s), null, tabs, null 7027c478bd9Sstevel@tonic-gate */ 7037c478bd9Sstevel@tonic-gate static char stdtabs[] = { 7047c478bd9Sstevel@tonic-gate 'a', 0, 1, 10, 16, 36, 72, 0, /* IBM 370 Assembler */ 7057c478bd9Sstevel@tonic-gate 'a', '2', 0, 1, 10, 16, 40, 72, 0, /* IBM Assembler alternative */ 7067c478bd9Sstevel@tonic-gate 'c', 0, 1, 8, 12, 16, 20, 55, 0, /* COBOL, normal */ 7077c478bd9Sstevel@tonic-gate 'c', '2', 0, 1, 6, 10, 14, 49, 0, /* COBOL, crunched */ 7087c478bd9Sstevel@tonic-gate 'c', '3', 0, 1, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 67, 7097c478bd9Sstevel@tonic-gate 0, /* crunched COBOL, many tabs */ 7107c478bd9Sstevel@tonic-gate 'f', 0, 1, 7, 11, 15, 19, 23, 0, /* FORTRAN */ 7117c478bd9Sstevel@tonic-gate 'p', 0, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 0, 7127c478bd9Sstevel@tonic-gate /* PL/I */ 7137c478bd9Sstevel@tonic-gate 's', 0, 1, 10, 55, 0, /* SNOBOL */ 7147c478bd9Sstevel@tonic-gate 'u', 0, 1, 12, 20, 44, 0, /* UNIVAC ASM */ 7157c478bd9Sstevel@tonic-gate 0}; 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate /* 7187c478bd9Sstevel@tonic-gate * stdtab: return tab list for any "canned" tab option. 7197c478bd9Sstevel@tonic-gate * entry: option points to null-terminated option string 7207c478bd9Sstevel@tonic-gate * tabvect points to vector to be filled in 7217c478bd9Sstevel@tonic-gate * exit: return (0) if legal, tabvect filled, ending with zero 7227c478bd9Sstevel@tonic-gate * return (-1) if unknown option 7237c478bd9Sstevel@tonic-gate */ 7247c478bd9Sstevel@tonic-gate int 7257c478bd9Sstevel@tonic-gate stdtab(char option[], int tabvect[]) 7267c478bd9Sstevel@tonic-gate { 727*8d489c7aSmuffin char *sp; 7287c478bd9Sstevel@tonic-gate tabvect[0] = 0; 7297c478bd9Sstevel@tonic-gate sp = stdtabs; 7307c478bd9Sstevel@tonic-gate while (*sp) { 7317c478bd9Sstevel@tonic-gate if (EQ(option, sp)) { 732*8d489c7aSmuffin while (*sp++) /* skip to 1st tab value */ 733*8d489c7aSmuffin ; 734*8d489c7aSmuffin while (*tabvect++ = *sp++) /* copy, make int */ 735*8d489c7aSmuffin ; 7367c478bd9Sstevel@tonic-gate return (0); 7377c478bd9Sstevel@tonic-gate } 738*8d489c7aSmuffin while (*sp++) /* skip to 1st tab value */ 739*8d489c7aSmuffin ; 740*8d489c7aSmuffin while (*sp++) /* skip over tab list */ 741*8d489c7aSmuffin ; 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate return (-1); 7447c478bd9Sstevel@tonic-gate } 745