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 2005 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 /* 28*7c478bd9Sstevel@tonic-gate * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T 29*7c478bd9Sstevel@tonic-gate * All Rights Reserved 30*7c478bd9Sstevel@tonic-gate */ 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 34*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 35*7c478bd9Sstevel@tonic-gate * All Rights Reserved 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 38*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 39*7c478bd9Sstevel@tonic-gate * contributors. 40*7c478bd9Sstevel@tonic-gate */ 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * PR command (print files in pages and columns, with headings) 46*7c478bd9Sstevel@tonic-gate * 2+head+2+page[56]+5 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate #include <stdio.h> 50*7c478bd9Sstevel@tonic-gate #include <signal.h> 51*7c478bd9Sstevel@tonic-gate #include <ctype.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 53*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 54*7c478bd9Sstevel@tonic-gate #include <unistd.h> 55*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 56*7c478bd9Sstevel@tonic-gate #include <locale.h> 57*7c478bd9Sstevel@tonic-gate #include <string.h> 58*7c478bd9Sstevel@tonic-gate #include <limits.h> 59*7c478bd9Sstevel@tonic-gate #include <wchar.h> 60*7c478bd9Sstevel@tonic-gate #include <errno.h> 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate #define ESC '\033' 63*7c478bd9Sstevel@tonic-gate #define LENGTH 66 64*7c478bd9Sstevel@tonic-gate #define LINEW 72 65*7c478bd9Sstevel@tonic-gate #define NUMW 5 66*7c478bd9Sstevel@tonic-gate #define MARGIN 10 67*7c478bd9Sstevel@tonic-gate #define DEFTAB 8 68*7c478bd9Sstevel@tonic-gate #define NFILES 10 69*7c478bd9Sstevel@tonic-gate #define STDINNAME() nulls 70*7c478bd9Sstevel@tonic-gate #define PROMPT() (void) putc('\7', stderr) /* BEL */ 71*7c478bd9Sstevel@tonic-gate #define NOFILE nulls 72*7c478bd9Sstevel@tonic-gate #define ETABS (Inpos % Etabn) 73*7c478bd9Sstevel@tonic-gate #define NSEPC '\t' 74*7c478bd9Sstevel@tonic-gate #define HEAD gettext("%s %s Page %d\n\n\n"), date, head, Page 75*7c478bd9Sstevel@tonic-gate #define cerror(S) (void) fprintf(stderr, "pr: %s", gettext(S)) 76*7c478bd9Sstevel@tonic-gate #define done() if (Ttyout) (void) chmod(Ttyout, Mode) 77*7c478bd9Sstevel@tonic-gate #define ALL_NUMS(s) (strspn(s, "0123456789") == strlen(s)) 78*7c478bd9Sstevel@tonic-gate #define REMOVE_ARG(argc, argp) \ 79*7c478bd9Sstevel@tonic-gate { \ 80*7c478bd9Sstevel@tonic-gate char **p = argp; \ 81*7c478bd9Sstevel@tonic-gate while (*p != NULL) \ 82*7c478bd9Sstevel@tonic-gate { \ 83*7c478bd9Sstevel@tonic-gate *p = *(p + 1); \ 84*7c478bd9Sstevel@tonic-gate p++; \ 85*7c478bd9Sstevel@tonic-gate } \ 86*7c478bd9Sstevel@tonic-gate argc--; \ 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate #define SQUEEZE_ARG(argp, ind, n) \ 89*7c478bd9Sstevel@tonic-gate { \ 90*7c478bd9Sstevel@tonic-gate int i; \ 91*7c478bd9Sstevel@tonic-gate for (i = ind; argp[i]; i++) \ 92*7c478bd9Sstevel@tonic-gate argp[i] = argp[i + n]; \ 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* 96*7c478bd9Sstevel@tonic-gate * ---date time format--- 97*7c478bd9Sstevel@tonic-gate * b -- abbreviated month name 98*7c478bd9Sstevel@tonic-gate * e -- day of month 99*7c478bd9Sstevel@tonic-gate * H -- Hour (24 hour version) 100*7c478bd9Sstevel@tonic-gate * M -- Minute 101*7c478bd9Sstevel@tonic-gate * Y -- Year in the form ccyy 102*7c478bd9Sstevel@tonic-gate */ 103*7c478bd9Sstevel@tonic-gate #define FORMAT "%b %e %H:%M %Y" 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate typedef int ANY; 106*7c478bd9Sstevel@tonic-gate typedef unsigned int UNS; 107*7c478bd9Sstevel@tonic-gate typedef struct { FILE *f_f; char *f_name; wchar_t f_nextc; } FILS; 108*7c478bd9Sstevel@tonic-gate typedef struct {int fold; int skip; int eof; } foldinf; 109*7c478bd9Sstevel@tonic-gate typedef struct { wchar_t *c_ptr, *c_ptr0; long c_lno; int c_skip; } *COLP; 110*7c478bd9Sstevel@tonic-gate typedef struct err { struct err *e_nextp; char *e_mess; } ERR; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* 113*7c478bd9Sstevel@tonic-gate * Global data. 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate static FILS *Files; 116*7c478bd9Sstevel@tonic-gate static mode_t Mode; 117*7c478bd9Sstevel@tonic-gate static int Multi = 0; 118*7c478bd9Sstevel@tonic-gate static int Nfiles = 0; 119*7c478bd9Sstevel@tonic-gate static int Error = 0; 120*7c478bd9Sstevel@tonic-gate static char nulls[] = ""; 121*7c478bd9Sstevel@tonic-gate static char *Ttyout; 122*7c478bd9Sstevel@tonic-gate static char obuf[BUFSIZ]; 123*7c478bd9Sstevel@tonic-gate static char time_buf[50]; /* array to hold the time and date */ 124*7c478bd9Sstevel@tonic-gate static long Lnumb = 0; 125*7c478bd9Sstevel@tonic-gate static FILE *Ttyin = stdin; 126*7c478bd9Sstevel@tonic-gate static int Dblspace = 1; 127*7c478bd9Sstevel@tonic-gate static int Fpage = 1; 128*7c478bd9Sstevel@tonic-gate static int Formfeed = 0; 129*7c478bd9Sstevel@tonic-gate static int Length = LENGTH; 130*7c478bd9Sstevel@tonic-gate static int Linew = 0; 131*7c478bd9Sstevel@tonic-gate static int Offset = 0; 132*7c478bd9Sstevel@tonic-gate static int Ncols = 0; 133*7c478bd9Sstevel@tonic-gate static int Pause = 0; 134*7c478bd9Sstevel@tonic-gate static wchar_t Sepc = 0; 135*7c478bd9Sstevel@tonic-gate static int Colw; 136*7c478bd9Sstevel@tonic-gate static int Plength; 137*7c478bd9Sstevel@tonic-gate static int Margin = MARGIN; 138*7c478bd9Sstevel@tonic-gate static int Numw; 139*7c478bd9Sstevel@tonic-gate static int Nsepc = NSEPC; 140*7c478bd9Sstevel@tonic-gate static int Report = 1; 141*7c478bd9Sstevel@tonic-gate static int Etabn = 0; 142*7c478bd9Sstevel@tonic-gate static wchar_t Etabc = '\t'; 143*7c478bd9Sstevel@tonic-gate static int Itabn = 0; 144*7c478bd9Sstevel@tonic-gate static wchar_t Itabc = '\t'; 145*7c478bd9Sstevel@tonic-gate static int fold = 0; 146*7c478bd9Sstevel@tonic-gate static int foldcol = 0; 147*7c478bd9Sstevel@tonic-gate static int alleof = 0; 148*7c478bd9Sstevel@tonic-gate static char *Head = NULL; 149*7c478bd9Sstevel@tonic-gate static wchar_t *Buffer = NULL, *Bufend, *Bufptr; 150*7c478bd9Sstevel@tonic-gate static UNS Buflen; 151*7c478bd9Sstevel@tonic-gate static COLP Colpts; 152*7c478bd9Sstevel@tonic-gate static foldinf *Fcol; 153*7c478bd9Sstevel@tonic-gate static int Page; 154*7c478bd9Sstevel@tonic-gate static wchar_t C = '\0'; 155*7c478bd9Sstevel@tonic-gate static int Nspace; 156*7c478bd9Sstevel@tonic-gate static int Inpos; 157*7c478bd9Sstevel@tonic-gate static int Outpos; 158*7c478bd9Sstevel@tonic-gate static int Lcolpos; 159*7c478bd9Sstevel@tonic-gate static int Pcolpos; 160*7c478bd9Sstevel@tonic-gate static int Line; 161*7c478bd9Sstevel@tonic-gate static ERR *Err = NULL; 162*7c478bd9Sstevel@tonic-gate static ERR *Lasterr = (ERR *)&Err; 163*7c478bd9Sstevel@tonic-gate static int mbcurmax = 1; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate /* 166*7c478bd9Sstevel@tonic-gate * Function prototypes. 167*7c478bd9Sstevel@tonic-gate */ 168*7c478bd9Sstevel@tonic-gate static void onintr(); 169*7c478bd9Sstevel@tonic-gate static ANY *getspace(); 170*7c478bd9Sstevel@tonic-gate static int findopt(int, char **); 171*7c478bd9Sstevel@tonic-gate static void fixtty(); 172*7c478bd9Sstevel@tonic-gate static char *GETDATE(); 173*7c478bd9Sstevel@tonic-gate static char *ffiler(char *); 174*7c478bd9Sstevel@tonic-gate static int print(char *); 175*7c478bd9Sstevel@tonic-gate static void putpage(); 176*7c478bd9Sstevel@tonic-gate static void foldpage(); 177*7c478bd9Sstevel@tonic-gate static void nexbuf(); 178*7c478bd9Sstevel@tonic-gate static void foldbuf(); 179*7c478bd9Sstevel@tonic-gate static void balance(int); 180*7c478bd9Sstevel@tonic-gate static int readbuf(wchar_t **, int, COLP); 181*7c478bd9Sstevel@tonic-gate static wint_t get(int); 182*7c478bd9Sstevel@tonic-gate static int put(wchar_t); 183*7c478bd9Sstevel@tonic-gate static void putspace(); 184*7c478bd9Sstevel@tonic-gate static void unget(int); 185*7c478bd9Sstevel@tonic-gate static FILE *mustopen(char *, FILS *); 186*7c478bd9Sstevel@tonic-gate static void die(char *); 187*7c478bd9Sstevel@tonic-gate static void errprint(); 188*7c478bd9Sstevel@tonic-gate static void usage(int); 189*7c478bd9Sstevel@tonic-gate static wint_t _fgetwc_pr(FILE *, int *); 190*7c478bd9Sstevel@tonic-gate static size_t freadw(wchar_t *, size_t, FILE *); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 194*7c478bd9Sstevel@tonic-gate { 195*7c478bd9Sstevel@tonic-gate FILS fstr[NFILES]; 196*7c478bd9Sstevel@tonic-gate int nfdone = 0; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* Get locale variables for environment */ 200*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 203*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 204*7c478bd9Sstevel@tonic-gate #endif 205*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate mbcurmax = MB_CUR_MAX; 208*7c478bd9Sstevel@tonic-gate Files = fstr; 209*7c478bd9Sstevel@tonic-gate for (argc = findopt(argc, argv); argc > 0; --argc, ++argv) { 210*7c478bd9Sstevel@tonic-gate if (Multi == 'm') { 211*7c478bd9Sstevel@tonic-gate if (Nfiles >= NFILES - 1) die("too many files"); 212*7c478bd9Sstevel@tonic-gate if (mustopen(*argv, &Files[Nfiles++]) == NULL) 213*7c478bd9Sstevel@tonic-gate ++nfdone; /* suppress printing */ 214*7c478bd9Sstevel@tonic-gate } else { 215*7c478bd9Sstevel@tonic-gate if (print(*argv)) 216*7c478bd9Sstevel@tonic-gate (void) fclose(Files->f_f); 217*7c478bd9Sstevel@tonic-gate ++nfdone; 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate if (!nfdone) /* no files named, use stdin */ 221*7c478bd9Sstevel@tonic-gate (void) print(NOFILE); /* on GCOS, use current file, if any */ 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate if (Report) { 224*7c478bd9Sstevel@tonic-gate errprint(); /* print accumulated error reports */ 225*7c478bd9Sstevel@tonic-gate exit(Error); 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate return (Error); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate /* 233*7c478bd9Sstevel@tonic-gate * findopt() returns argc modified to be the number of explicitly supplied 234*7c478bd9Sstevel@tonic-gate * filenames, including '-', the explicit request to use stdin. 235*7c478bd9Sstevel@tonic-gate * argc == 0 implies that no filenames were supplied and stdin should be used. 236*7c478bd9Sstevel@tonic-gate * Options are striped from argv and only file names are returned. 237*7c478bd9Sstevel@tonic-gate */ 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate static int 240*7c478bd9Sstevel@tonic-gate findopt(int argc, char **argv) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate int eargc = 0; 243*7c478bd9Sstevel@tonic-gate int c; 244*7c478bd9Sstevel@tonic-gate int mflg = 0; 245*7c478bd9Sstevel@tonic-gate int aflg = 0; 246*7c478bd9Sstevel@tonic-gate int optnum; 247*7c478bd9Sstevel@tonic-gate int argv_ind; 248*7c478bd9Sstevel@tonic-gate int end_opt; 249*7c478bd9Sstevel@tonic-gate int i; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate fixtty(); 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate /* Handle page number option */ 254*7c478bd9Sstevel@tonic-gate for (optnum = 1, end_opt = 0; optnum < argc && !end_opt; optnum++) { 255*7c478bd9Sstevel@tonic-gate switch (*argv[optnum]) { 256*7c478bd9Sstevel@tonic-gate case '+': 257*7c478bd9Sstevel@tonic-gate /* check for all digits */ 258*7c478bd9Sstevel@tonic-gate if (strlen(&argv[optnum][1]) != 259*7c478bd9Sstevel@tonic-gate strspn(&argv[optnum][1], "0123456789")) { 260*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 261*7c478bd9Sstevel@tonic-gate "pr: Badly formed number\n")); 262*7c478bd9Sstevel@tonic-gate exit(1); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if ((Fpage = (int)strtol(&argv[optnum][1], 266*7c478bd9Sstevel@tonic-gate (char **)NULL, 10)) < 0) { 267*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 268*7c478bd9Sstevel@tonic-gate "pr: Badly formed number\n")); 269*7c478bd9Sstevel@tonic-gate exit(1); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate REMOVE_ARG(argc, &argv[optnum]); 272*7c478bd9Sstevel@tonic-gate optnum--; 273*7c478bd9Sstevel@tonic-gate break; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate case '-': 276*7c478bd9Sstevel@tonic-gate /* Check for end of options */ 277*7c478bd9Sstevel@tonic-gate if (argv[optnum][1] == '-') { 278*7c478bd9Sstevel@tonic-gate end_opt++; 279*7c478bd9Sstevel@tonic-gate break; 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate break; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate default: 284*7c478bd9Sstevel@tonic-gate end_opt++; 285*7c478bd9Sstevel@tonic-gate break; 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate /* 290*7c478bd9Sstevel@tonic-gate * Handle options with optional arguments. 291*7c478bd9Sstevel@tonic-gate * If optional arguments are present they may not be separated 292*7c478bd9Sstevel@tonic-gate * from the option letter. 293*7c478bd9Sstevel@tonic-gate */ 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate for (optnum = 1; optnum < argc; optnum++) { 296*7c478bd9Sstevel@tonic-gate if (argv[optnum][0] == '-' && argv[optnum][1] == '-') 297*7c478bd9Sstevel@tonic-gate /* End of options */ 298*7c478bd9Sstevel@tonic-gate break; 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate if (argv[optnum][0] == '-' && argv[optnum][1] == '\0') 301*7c478bd9Sstevel@tonic-gate /* stdin file name */ 302*7c478bd9Sstevel@tonic-gate continue; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate if (argv[optnum][0] != '-') 305*7c478bd9Sstevel@tonic-gate /* not option */ 306*7c478bd9Sstevel@tonic-gate continue; 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate for (argv_ind = 1; argv[optnum][argv_ind] != '\0'; argv_ind++) { 309*7c478bd9Sstevel@tonic-gate switch (argv[optnum][argv_ind]) { 310*7c478bd9Sstevel@tonic-gate case 'e': 311*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, 1); 312*7c478bd9Sstevel@tonic-gate if ((c = argv[optnum][argv_ind]) != '\0' && 313*7c478bd9Sstevel@tonic-gate !isdigit(c)) { 314*7c478bd9Sstevel@tonic-gate int r; 315*7c478bd9Sstevel@tonic-gate wchar_t wc; 316*7c478bd9Sstevel@tonic-gate r = mbtowc(&wc, &argv[optnum][argv_ind], 317*7c478bd9Sstevel@tonic-gate mbcurmax); 318*7c478bd9Sstevel@tonic-gate if (r == -1) { 319*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 320*7c478bd9Sstevel@tonic-gate "pr: Illegal character in -e option\n")); 321*7c478bd9Sstevel@tonic-gate exit(1); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate Etabc = wc; 324*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, r); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate if (isdigit(argv[optnum][argv_ind])) { 327*7c478bd9Sstevel@tonic-gate Etabn = (int)strtol(&argv[optnum] 328*7c478bd9Sstevel@tonic-gate [argv_ind], (char **)NULL, 10); 329*7c478bd9Sstevel@tonic-gate while (isdigit(argv[optnum][argv_ind])) 330*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], 331*7c478bd9Sstevel@tonic-gate argv_ind, 1); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate if (Etabn <= 0) 334*7c478bd9Sstevel@tonic-gate Etabn = DEFTAB; 335*7c478bd9Sstevel@tonic-gate argv_ind--; 336*7c478bd9Sstevel@tonic-gate break; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate case 'i': 339*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, 1); 340*7c478bd9Sstevel@tonic-gate if ((c = argv[optnum][argv_ind]) != '\0' && 341*7c478bd9Sstevel@tonic-gate !isdigit(c)) { 342*7c478bd9Sstevel@tonic-gate int r; 343*7c478bd9Sstevel@tonic-gate wchar_t wc; 344*7c478bd9Sstevel@tonic-gate r = mbtowc(&wc, &argv[optnum][argv_ind], 345*7c478bd9Sstevel@tonic-gate mbcurmax); 346*7c478bd9Sstevel@tonic-gate if (r == -1) { 347*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 348*7c478bd9Sstevel@tonic-gate "pr: Illegal character in -i option\n")); 349*7c478bd9Sstevel@tonic-gate exit(1); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate Itabc = wc; 352*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, r); 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate if (isdigit(argv[optnum][argv_ind])) { 355*7c478bd9Sstevel@tonic-gate Itabn = (int)strtol(&argv[optnum] 356*7c478bd9Sstevel@tonic-gate [argv_ind], (char **)NULL, 10); 357*7c478bd9Sstevel@tonic-gate while (isdigit(argv[optnum][argv_ind])) 358*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], 359*7c478bd9Sstevel@tonic-gate argv_ind, 1); 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate if (Itabn <= 0) 362*7c478bd9Sstevel@tonic-gate Itabn = DEFTAB; 363*7c478bd9Sstevel@tonic-gate argv_ind--; 364*7c478bd9Sstevel@tonic-gate break; 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate case 'n': 368*7c478bd9Sstevel@tonic-gate ++Lnumb; 369*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, 1); 370*7c478bd9Sstevel@tonic-gate if ((c = argv[optnum][argv_ind]) != '\0' && 371*7c478bd9Sstevel@tonic-gate !isdigit(c)) { 372*7c478bd9Sstevel@tonic-gate int r; 373*7c478bd9Sstevel@tonic-gate wchar_t wc; 374*7c478bd9Sstevel@tonic-gate r = mbtowc(&wc, &argv[optnum][argv_ind], 375*7c478bd9Sstevel@tonic-gate mbcurmax); 376*7c478bd9Sstevel@tonic-gate if (r == -1) { 377*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 378*7c478bd9Sstevel@tonic-gate "pr: Illegal character in -n option\n")); 379*7c478bd9Sstevel@tonic-gate exit(1); 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate Nsepc = wc; 382*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, r); 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate if (isdigit(argv[optnum][argv_ind])) { 385*7c478bd9Sstevel@tonic-gate Numw = (int)strtol(&argv[optnum] 386*7c478bd9Sstevel@tonic-gate [argv_ind], (char **)NULL, 10); 387*7c478bd9Sstevel@tonic-gate while (isdigit(argv[optnum][argv_ind])) 388*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], 389*7c478bd9Sstevel@tonic-gate argv_ind, 1); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate argv_ind--; 392*7c478bd9Sstevel@tonic-gate if (!Numw) 393*7c478bd9Sstevel@tonic-gate Numw = NUMW; 394*7c478bd9Sstevel@tonic-gate break; 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate case 's': 397*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, 1); 398*7c478bd9Sstevel@tonic-gate if ((Sepc = argv[optnum][argv_ind]) == '\0') 399*7c478bd9Sstevel@tonic-gate Sepc = '\t'; 400*7c478bd9Sstevel@tonic-gate else { 401*7c478bd9Sstevel@tonic-gate int r; 402*7c478bd9Sstevel@tonic-gate wchar_t wc; 403*7c478bd9Sstevel@tonic-gate r = mbtowc(&wc, &argv[optnum][argv_ind], 404*7c478bd9Sstevel@tonic-gate mbcurmax); 405*7c478bd9Sstevel@tonic-gate if (r == -1) { 406*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 407*7c478bd9Sstevel@tonic-gate "pr: Illegal character in -s option\n")); 408*7c478bd9Sstevel@tonic-gate exit(1); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate Sepc = wc; 411*7c478bd9Sstevel@tonic-gate SQUEEZE_ARG(argv[optnum], argv_ind, r); 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate argv_ind--; 414*7c478bd9Sstevel@tonic-gate break; 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate default: 417*7c478bd9Sstevel@tonic-gate break; 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate if (argv[optnum][0] == '-' && argv[optnum][1] == '\0') { 421*7c478bd9Sstevel@tonic-gate REMOVE_ARG(argc, &argv[optnum]); 422*7c478bd9Sstevel@tonic-gate optnum--; 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate /* Now get the other options */ 427*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "0123456789adfFh:l:mo:prtw:")) 428*7c478bd9Sstevel@tonic-gate != EOF) { 429*7c478bd9Sstevel@tonic-gate switch (c) { 430*7c478bd9Sstevel@tonic-gate case '0': 431*7c478bd9Sstevel@tonic-gate case '1': 432*7c478bd9Sstevel@tonic-gate case '2': 433*7c478bd9Sstevel@tonic-gate case '3': 434*7c478bd9Sstevel@tonic-gate case '4': 435*7c478bd9Sstevel@tonic-gate case '5': 436*7c478bd9Sstevel@tonic-gate case '6': 437*7c478bd9Sstevel@tonic-gate case '7': 438*7c478bd9Sstevel@tonic-gate case '8': 439*7c478bd9Sstevel@tonic-gate case '9': 440*7c478bd9Sstevel@tonic-gate Ncols *= 10; 441*7c478bd9Sstevel@tonic-gate Ncols += c - '0'; 442*7c478bd9Sstevel@tonic-gate break; 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate case 'a': 445*7c478bd9Sstevel@tonic-gate aflg++; 446*7c478bd9Sstevel@tonic-gate if (!Multi) 447*7c478bd9Sstevel@tonic-gate Multi = c; 448*7c478bd9Sstevel@tonic-gate break; 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate case 'd': 451*7c478bd9Sstevel@tonic-gate Dblspace = 2; 452*7c478bd9Sstevel@tonic-gate break; 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate case 'f': 455*7c478bd9Sstevel@tonic-gate ++Formfeed; 456*7c478bd9Sstevel@tonic-gate ++Pause; 457*7c478bd9Sstevel@tonic-gate break; 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate case 'h': 460*7c478bd9Sstevel@tonic-gate Head = optarg; 461*7c478bd9Sstevel@tonic-gate break; 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate case 'l': 464*7c478bd9Sstevel@tonic-gate if (strlen(optarg) != strspn(optarg, "0123456789")) 465*7c478bd9Sstevel@tonic-gate usage(1); 466*7c478bd9Sstevel@tonic-gate Length = (int)strtol(optarg, (char **)NULL, 10); 467*7c478bd9Sstevel@tonic-gate break; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate case 'm': 470*7c478bd9Sstevel@tonic-gate mflg++; 471*7c478bd9Sstevel@tonic-gate Multi = c; 472*7c478bd9Sstevel@tonic-gate break; 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate case 'o': 475*7c478bd9Sstevel@tonic-gate if (strlen(optarg) != strspn(optarg, "0123456789")) 476*7c478bd9Sstevel@tonic-gate usage(1); 477*7c478bd9Sstevel@tonic-gate Offset = (int)strtol(optarg, (char **)NULL, 10); 478*7c478bd9Sstevel@tonic-gate break; 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate case 'p': 481*7c478bd9Sstevel@tonic-gate ++Pause; 482*7c478bd9Sstevel@tonic-gate break; 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate case 'r': 485*7c478bd9Sstevel@tonic-gate Report = 0; 486*7c478bd9Sstevel@tonic-gate break; 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate case 't': 489*7c478bd9Sstevel@tonic-gate Margin = 0; 490*7c478bd9Sstevel@tonic-gate break; 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate case 'w': 493*7c478bd9Sstevel@tonic-gate if (strlen(optarg) != strspn(optarg, "0123456789")) 494*7c478bd9Sstevel@tonic-gate usage(1); 495*7c478bd9Sstevel@tonic-gate Linew = (int)strtol(optarg, (char **)NULL, 10); 496*7c478bd9Sstevel@tonic-gate break; 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate case 'F': 499*7c478bd9Sstevel@tonic-gate #ifdef XPG4 500*7c478bd9Sstevel@tonic-gate ++Formfeed; 501*7c478bd9Sstevel@tonic-gate #else 502*7c478bd9Sstevel@tonic-gate fold++; 503*7c478bd9Sstevel@tonic-gate #endif 504*7c478bd9Sstevel@tonic-gate break; 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate case '?': 507*7c478bd9Sstevel@tonic-gate usage(2); 508*7c478bd9Sstevel@tonic-gate break; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate default : 511*7c478bd9Sstevel@tonic-gate usage(2); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate /* Count the file names and strip options */ 516*7c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i++) { 517*7c478bd9Sstevel@tonic-gate /* Check for explicit stdin */ 518*7c478bd9Sstevel@tonic-gate if ((argv[i][0] == '-') && (argv[i][1] == '\0')) { 519*7c478bd9Sstevel@tonic-gate argv[eargc++][0] = '\0'; 520*7c478bd9Sstevel@tonic-gate REMOVE_ARG(argc, &argv[i]); 521*7c478bd9Sstevel@tonic-gate if (i < optind) 522*7c478bd9Sstevel@tonic-gate optind--; 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate for (i = eargc; optind < argc; i++, optind++) { 526*7c478bd9Sstevel@tonic-gate argv[i] = argv[optind]; 527*7c478bd9Sstevel@tonic-gate eargc++; 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate /* Check options */ 531*7c478bd9Sstevel@tonic-gate if (Ncols == 0) 532*7c478bd9Sstevel@tonic-gate Ncols = 1; 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate if (mflg && (Ncols > 1)) { 535*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 536*7c478bd9Sstevel@tonic-gate gettext("pr: only one of either -m or -column allowed\n")); 537*7c478bd9Sstevel@tonic-gate usage(1); 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate if (Ncols == 1 && fold) 541*7c478bd9Sstevel@tonic-gate Multi = 'm'; 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate if (Length <= 0) 544*7c478bd9Sstevel@tonic-gate Length = LENGTH; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate if (Length <= Margin) 547*7c478bd9Sstevel@tonic-gate Margin = 0; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate Plength = Length - Margin/2; 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate if (Multi == 'm') 552*7c478bd9Sstevel@tonic-gate Ncols = eargc; 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate switch (Ncols) { 555*7c478bd9Sstevel@tonic-gate case 0: 556*7c478bd9Sstevel@tonic-gate Ncols = 1; 557*7c478bd9Sstevel@tonic-gate break; 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate case 1: 560*7c478bd9Sstevel@tonic-gate break; 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate default: 563*7c478bd9Sstevel@tonic-gate if (Etabn == 0) /* respect explicit tab specification */ 564*7c478bd9Sstevel@tonic-gate Etabn = DEFTAB; 565*7c478bd9Sstevel@tonic-gate if (Itabn == 0) 566*7c478bd9Sstevel@tonic-gate Itabn = DEFTAB; 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate if ((Fcol = (foldinf *) malloc(sizeof (foldinf) * Ncols)) == NULL) { 570*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("pr: malloc failed\n")); 571*7c478bd9Sstevel@tonic-gate exit(1); 572*7c478bd9Sstevel@tonic-gate } 573*7c478bd9Sstevel@tonic-gate for (i = 0; i < Ncols; i++) 574*7c478bd9Sstevel@tonic-gate Fcol[i].fold = Fcol[i].skip = 0; 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate if (Linew == 0) 577*7c478bd9Sstevel@tonic-gate Linew = Ncols != 1 && Sepc == 0 ? LINEW : 512; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate if (Lnumb) { 580*7c478bd9Sstevel@tonic-gate int numw; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate if (Nsepc == '\t') { 583*7c478bd9Sstevel@tonic-gate if (Itabn == 0) 584*7c478bd9Sstevel@tonic-gate numw = Numw + DEFTAB - (Numw % DEFTAB); 585*7c478bd9Sstevel@tonic-gate else 586*7c478bd9Sstevel@tonic-gate numw = Numw + Itabn - (Numw % Itabn); 587*7c478bd9Sstevel@tonic-gate } else { 588*7c478bd9Sstevel@tonic-gate numw = Numw + ((iswprint(Nsepc)) ? 1 : 0); 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate Linew -= (Multi == 'm') ? numw : numw * Ncols; 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate if ((Colw = (Linew - Ncols + 1)/Ncols) < 1) 594*7c478bd9Sstevel@tonic-gate die("width too small"); 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate if (Ncols != 1 && Multi == 0) { 597*7c478bd9Sstevel@tonic-gate /* Buflen should take the number of wide characters */ 598*7c478bd9Sstevel@tonic-gate /* Not the size for Buffer */ 599*7c478bd9Sstevel@tonic-gate Buflen = ((UNS) (Plength / Dblspace + 1)) * 600*7c478bd9Sstevel@tonic-gate 2 * (Linew + 1); 601*7c478bd9Sstevel@tonic-gate /* Should allocate Buflen * sizeof (wchar_t) */ 602*7c478bd9Sstevel@tonic-gate Buffer = (wchar_t *)getspace(Buflen * sizeof (wchar_t)); 603*7c478bd9Sstevel@tonic-gate Bufptr = Bufend = &Buffer[Buflen]; 604*7c478bd9Sstevel@tonic-gate Colpts = (COLP) getspace((UNS) ((Ncols + 1) * 605*7c478bd9Sstevel@tonic-gate sizeof (*Colpts))); 606*7c478bd9Sstevel@tonic-gate Colpts[0].c_lno = 0; 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate /* is stdin not a tty? */ 610*7c478bd9Sstevel@tonic-gate if (Ttyout && (Pause || Formfeed) && !ttyname(fileno(stdin))) 611*7c478bd9Sstevel@tonic-gate Ttyin = fopen("/dev/tty", "r"); 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate return (eargc); 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate static int 618*7c478bd9Sstevel@tonic-gate print(char *name) 619*7c478bd9Sstevel@tonic-gate { 620*7c478bd9Sstevel@tonic-gate static int notfirst = 0; 621*7c478bd9Sstevel@tonic-gate char *date = NULL; 622*7c478bd9Sstevel@tonic-gate char *head = NULL; 623*7c478bd9Sstevel@tonic-gate int c; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate if (Multi != 'm' && mustopen(name, &Files[0]) == NULL) 626*7c478bd9Sstevel@tonic-gate return (0); 627*7c478bd9Sstevel@tonic-gate if (Multi == 'm' && Nfiles == 0 && mustopen(name, &Files[0]) == NULL) 628*7c478bd9Sstevel@tonic-gate die("cannot open stdin"); 629*7c478bd9Sstevel@tonic-gate if (Buffer) 630*7c478bd9Sstevel@tonic-gate (void) ungetwc(Files->f_nextc, Files->f_f); 631*7c478bd9Sstevel@tonic-gate if (Lnumb) 632*7c478bd9Sstevel@tonic-gate Lnumb = 1; 633*7c478bd9Sstevel@tonic-gate for (Page = 0; ; putpage()) { 634*7c478bd9Sstevel@tonic-gate if (C == WEOF && !(fold && Buffer)) 635*7c478bd9Sstevel@tonic-gate break; 636*7c478bd9Sstevel@tonic-gate if (Buffer) 637*7c478bd9Sstevel@tonic-gate nexbuf(); 638*7c478bd9Sstevel@tonic-gate Inpos = 0; 639*7c478bd9Sstevel@tonic-gate if (get(0) == WEOF) 640*7c478bd9Sstevel@tonic-gate break; 641*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 642*7c478bd9Sstevel@tonic-gate if (++Page >= Fpage) { 643*7c478bd9Sstevel@tonic-gate /* Pause if -p and not first page */ 644*7c478bd9Sstevel@tonic-gate if (Ttyout && Pause && !notfirst++) { 645*7c478bd9Sstevel@tonic-gate PROMPT(); /* prompt with bell and pause */ 646*7c478bd9Sstevel@tonic-gate while ((c = getc(Ttyin)) != EOF && c != '\n') 647*7c478bd9Sstevel@tonic-gate ; 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate if (Margin == 0) 650*7c478bd9Sstevel@tonic-gate continue; 651*7c478bd9Sstevel@tonic-gate if (date == NULL) 652*7c478bd9Sstevel@tonic-gate date = GETDATE(); 653*7c478bd9Sstevel@tonic-gate if (head == NULL) 654*7c478bd9Sstevel@tonic-gate head = Head != NULL ? Head : 655*7c478bd9Sstevel@tonic-gate Nfiles < 2 ? Files->f_name : nulls; 656*7c478bd9Sstevel@tonic-gate (void) printf("\n\n"); 657*7c478bd9Sstevel@tonic-gate Nspace = Offset; 658*7c478bd9Sstevel@tonic-gate putspace(); 659*7c478bd9Sstevel@tonic-gate (void) printf(HEAD); 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate C = '\0'; 663*7c478bd9Sstevel@tonic-gate return (1); 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate static void 668*7c478bd9Sstevel@tonic-gate putpage() 669*7c478bd9Sstevel@tonic-gate { 670*7c478bd9Sstevel@tonic-gate int colno; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate if (fold) { 673*7c478bd9Sstevel@tonic-gate foldpage(); 674*7c478bd9Sstevel@tonic-gate return; 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate for (Line = Margin / 2; ; (void) get(0)) { 677*7c478bd9Sstevel@tonic-gate for (Nspace = Offset, colno = 0, Outpos = 0; C != '\f'; ) { 678*7c478bd9Sstevel@tonic-gate if (Lnumb && (C != WEOF) && 679*7c478bd9Sstevel@tonic-gate (((colno == 0) && (Multi == 'm')) || 680*7c478bd9Sstevel@tonic-gate (Multi != 'm'))) { 681*7c478bd9Sstevel@tonic-gate if (Page >= Fpage) { 682*7c478bd9Sstevel@tonic-gate putspace(); 683*7c478bd9Sstevel@tonic-gate (void) printf("%*ld%wc", Numw, Buffer ? 684*7c478bd9Sstevel@tonic-gate Colpts[colno].c_lno++ : 685*7c478bd9Sstevel@tonic-gate Lnumb, Nsepc); 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate /* Move Outpos for number field */ 688*7c478bd9Sstevel@tonic-gate Outpos += Numw; 689*7c478bd9Sstevel@tonic-gate if (Nsepc == '\t') 690*7c478bd9Sstevel@tonic-gate Outpos += 691*7c478bd9Sstevel@tonic-gate DEFTAB - (Outpos % DEFTAB); 692*7c478bd9Sstevel@tonic-gate else 693*7c478bd9Sstevel@tonic-gate Outpos++; 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate ++Lnumb; 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate for (Lcolpos = 0, Pcolpos = 0; 698*7c478bd9Sstevel@tonic-gate C != '\n' && C != '\f' && C != WEOF; 699*7c478bd9Sstevel@tonic-gate (void) get(colno)) 700*7c478bd9Sstevel@tonic-gate (void) put(C); 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate if ((C == WEOF) || (++colno == Ncols) || 703*7c478bd9Sstevel@tonic-gate ((C == '\n') && (get(colno) == WEOF))) 704*7c478bd9Sstevel@tonic-gate break; 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate if (Sepc) 707*7c478bd9Sstevel@tonic-gate (void) put(Sepc); 708*7c478bd9Sstevel@tonic-gate else if ((Nspace += Colw - Lcolpos + 1) < 1) 709*7c478bd9Sstevel@tonic-gate Nspace = 1; 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate if (C == WEOF) { 713*7c478bd9Sstevel@tonic-gate if (Margin != 0) 714*7c478bd9Sstevel@tonic-gate break; 715*7c478bd9Sstevel@tonic-gate if (colno != 0) 716*7c478bd9Sstevel@tonic-gate (void) put('\n'); 717*7c478bd9Sstevel@tonic-gate return; 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate if (C == '\f') 720*7c478bd9Sstevel@tonic-gate break; 721*7c478bd9Sstevel@tonic-gate (void) put('\n'); 722*7c478bd9Sstevel@tonic-gate if (Dblspace == 2 && Line < Plength) 723*7c478bd9Sstevel@tonic-gate (void) put('\n'); 724*7c478bd9Sstevel@tonic-gate if (Line >= Plength) 725*7c478bd9Sstevel@tonic-gate break; 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate if (Formfeed) 728*7c478bd9Sstevel@tonic-gate (void) put('\f'); 729*7c478bd9Sstevel@tonic-gate else 730*7c478bd9Sstevel@tonic-gate while (Line < Length) 731*7c478bd9Sstevel@tonic-gate (void) put('\n'); 732*7c478bd9Sstevel@tonic-gate } 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate static void 736*7c478bd9Sstevel@tonic-gate foldpage() 737*7c478bd9Sstevel@tonic-gate { 738*7c478bd9Sstevel@tonic-gate int colno; 739*7c478bd9Sstevel@tonic-gate int keep; 740*7c478bd9Sstevel@tonic-gate int i; 741*7c478bd9Sstevel@tonic-gate int pLcolpos; 742*7c478bd9Sstevel@tonic-gate static int sl; 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate for (Line = Margin / 2; ; (void) get(0)) { 745*7c478bd9Sstevel@tonic-gate for (Nspace = Offset, colno = 0, Outpos = 0; C != '\f'; ) { 746*7c478bd9Sstevel@tonic-gate if (Lnumb && Multi == 'm' && foldcol) { 747*7c478bd9Sstevel@tonic-gate if (!Fcol[colno].skip) { 748*7c478bd9Sstevel@tonic-gate unget(colno); 749*7c478bd9Sstevel@tonic-gate putspace(); 750*7c478bd9Sstevel@tonic-gate if (!colno) { 751*7c478bd9Sstevel@tonic-gate for (i = 0; i <= Numw; i++) 752*7c478bd9Sstevel@tonic-gate (void) printf(" "); 753*7c478bd9Sstevel@tonic-gate (void) printf("%wc", Nsepc); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate for (i = 0; i <= Colw; i++) 756*7c478bd9Sstevel@tonic-gate (void) printf(" "); 757*7c478bd9Sstevel@tonic-gate (void) put(Sepc); 758*7c478bd9Sstevel@tonic-gate if (++colno == Ncols) 759*7c478bd9Sstevel@tonic-gate break; 760*7c478bd9Sstevel@tonic-gate (void) get(colno); 761*7c478bd9Sstevel@tonic-gate continue; 762*7c478bd9Sstevel@tonic-gate } else if (!colno) 763*7c478bd9Sstevel@tonic-gate Lnumb = sl; 764*7c478bd9Sstevel@tonic-gate } 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate if (Lnumb && (C != WEOF) && 767*7c478bd9Sstevel@tonic-gate ((colno == 0 && Multi == 'm') || (Multi != 'm'))) { 768*7c478bd9Sstevel@tonic-gate if (Page >= Fpage) { 769*7c478bd9Sstevel@tonic-gate putspace(); 770*7c478bd9Sstevel@tonic-gate if ((foldcol && 771*7c478bd9Sstevel@tonic-gate Fcol[colno].skip && Multi != 'a') || 772*7c478bd9Sstevel@tonic-gate (Fcol[0].fold && Multi == 'a') || 773*7c478bd9Sstevel@tonic-gate (Buffer && Colpts[colno].c_skip)) { 774*7c478bd9Sstevel@tonic-gate for (i = 0; i < Numw; i++) 775*7c478bd9Sstevel@tonic-gate (void) printf(" "); 776*7c478bd9Sstevel@tonic-gate (void) printf("%wc", Nsepc); 777*7c478bd9Sstevel@tonic-gate if (Buffer) { 778*7c478bd9Sstevel@tonic-gate Colpts[colno].c_lno++; 779*7c478bd9Sstevel@tonic-gate Colpts[colno].c_skip = 780*7c478bd9Sstevel@tonic-gate 0; 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate } 783*7c478bd9Sstevel@tonic-gate else 784*7c478bd9Sstevel@tonic-gate (void) printf("%*ld%wc", Numw, Buffer ? 785*7c478bd9Sstevel@tonic-gate Colpts[colno].c_lno++ : 786*7c478bd9Sstevel@tonic-gate Lnumb, Nsepc); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate sl = Lnumb++; 789*7c478bd9Sstevel@tonic-gate } 790*7c478bd9Sstevel@tonic-gate pLcolpos = 0; 791*7c478bd9Sstevel@tonic-gate for (Lcolpos = 0, Pcolpos = 0; 792*7c478bd9Sstevel@tonic-gate C != '\n' && C != '\f' && C != WEOF; 793*7c478bd9Sstevel@tonic-gate (void) get(colno)) { 794*7c478bd9Sstevel@tonic-gate if (put(C)) { 795*7c478bd9Sstevel@tonic-gate unget(colno); 796*7c478bd9Sstevel@tonic-gate Fcol[(Multi == 'a') ? 0 : colno].fold 797*7c478bd9Sstevel@tonic-gate = 1; 798*7c478bd9Sstevel@tonic-gate break; 799*7c478bd9Sstevel@tonic-gate } else if (Multi == 'a') { 800*7c478bd9Sstevel@tonic-gate Fcol[0].fold = 0; 801*7c478bd9Sstevel@tonic-gate } 802*7c478bd9Sstevel@tonic-gate pLcolpos = Lcolpos; 803*7c478bd9Sstevel@tonic-gate } 804*7c478bd9Sstevel@tonic-gate if (Buffer) { 805*7c478bd9Sstevel@tonic-gate alleof = 1; 806*7c478bd9Sstevel@tonic-gate for (i = 0; i < Ncols; i++) 807*7c478bd9Sstevel@tonic-gate if (!Fcol[i].eof) 808*7c478bd9Sstevel@tonic-gate alleof = 0; 809*7c478bd9Sstevel@tonic-gate if (alleof || ++colno == Ncols) 810*7c478bd9Sstevel@tonic-gate break; 811*7c478bd9Sstevel@tonic-gate } else if (C == EOF || ++colno == Ncols) 812*7c478bd9Sstevel@tonic-gate break; 813*7c478bd9Sstevel@tonic-gate keep = C; 814*7c478bd9Sstevel@tonic-gate (void) get(colno); 815*7c478bd9Sstevel@tonic-gate if (keep == '\n' && C == WEOF) 816*7c478bd9Sstevel@tonic-gate break; 817*7c478bd9Sstevel@tonic-gate if (Sepc) 818*7c478bd9Sstevel@tonic-gate (void) put(Sepc); 819*7c478bd9Sstevel@tonic-gate else if ((Nspace += Colw - pLcolpos + 1) < 1) 820*7c478bd9Sstevel@tonic-gate Nspace = 1; 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate foldcol = 0; 823*7c478bd9Sstevel@tonic-gate if (Lnumb && Multi != 'a') { 824*7c478bd9Sstevel@tonic-gate for (i = 0; i < Ncols; i++) { 825*7c478bd9Sstevel@tonic-gate Fcol[i].skip = Fcol[i].fold; 826*7c478bd9Sstevel@tonic-gate foldcol += Fcol[i].fold; 827*7c478bd9Sstevel@tonic-gate Fcol[i].fold = 0; 828*7c478bd9Sstevel@tonic-gate } 829*7c478bd9Sstevel@tonic-gate } 830*7c478bd9Sstevel@tonic-gate if (C == WEOF) { 831*7c478bd9Sstevel@tonic-gate if (Margin != 0) 832*7c478bd9Sstevel@tonic-gate break; 833*7c478bd9Sstevel@tonic-gate if (colno != 0) 834*7c478bd9Sstevel@tonic-gate (void) put('\n'); 835*7c478bd9Sstevel@tonic-gate return; 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate if (C == '\f') 838*7c478bd9Sstevel@tonic-gate break; 839*7c478bd9Sstevel@tonic-gate (void) put('\n'); 840*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 841*7c478bd9Sstevel@tonic-gate if (Dblspace == 2 && Line < Plength) 842*7c478bd9Sstevel@tonic-gate (void) put('\n'); 843*7c478bd9Sstevel@tonic-gate if (Line >= Plength) 844*7c478bd9Sstevel@tonic-gate break; 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate if (Formfeed) 847*7c478bd9Sstevel@tonic-gate (void) put('\f'); 848*7c478bd9Sstevel@tonic-gate else while (Line < Length) 849*7c478bd9Sstevel@tonic-gate (void) put('\n'); 850*7c478bd9Sstevel@tonic-gate } 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate static void 854*7c478bd9Sstevel@tonic-gate nexbuf() 855*7c478bd9Sstevel@tonic-gate { 856*7c478bd9Sstevel@tonic-gate wchar_t *s = Buffer; 857*7c478bd9Sstevel@tonic-gate COLP p = Colpts; 858*7c478bd9Sstevel@tonic-gate int j; 859*7c478bd9Sstevel@tonic-gate int c; 860*7c478bd9Sstevel@tonic-gate int bline = 0; 861*7c478bd9Sstevel@tonic-gate wchar_t wc; 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate if (fold) { 864*7c478bd9Sstevel@tonic-gate foldbuf(); 865*7c478bd9Sstevel@tonic-gate return; 866*7c478bd9Sstevel@tonic-gate } 867*7c478bd9Sstevel@tonic-gate for (; ; ) { 868*7c478bd9Sstevel@tonic-gate p->c_ptr0 = p->c_ptr = s; 869*7c478bd9Sstevel@tonic-gate if (p == &Colpts[Ncols]) 870*7c478bd9Sstevel@tonic-gate return; 871*7c478bd9Sstevel@tonic-gate (p++)->c_lno = Lnumb + bline; 872*7c478bd9Sstevel@tonic-gate for (j = (Length - Margin)/Dblspace; --j >= 0; ++bline) { 873*7c478bd9Sstevel@tonic-gate for (Inpos = 0; ; ) { 874*7c478bd9Sstevel@tonic-gate errno = 0; 875*7c478bd9Sstevel@tonic-gate wc = _fgetwc_pr(Files->f_f, &c); 876*7c478bd9Sstevel@tonic-gate if (wc == WEOF) { 877*7c478bd9Sstevel@tonic-gate /* If there is an illegal character, */ 878*7c478bd9Sstevel@tonic-gate /* handle it as a byte sequence. */ 879*7c478bd9Sstevel@tonic-gate if (errno == EILSEQ) { 880*7c478bd9Sstevel@tonic-gate if (Inpos < Colw - 1) { 881*7c478bd9Sstevel@tonic-gate *s = c; 882*7c478bd9Sstevel@tonic-gate if (++s >= Bufend) 883*7c478bd9Sstevel@tonic-gate die("page-buffer overflow"); 884*7c478bd9Sstevel@tonic-gate } 885*7c478bd9Sstevel@tonic-gate Inpos++; 886*7c478bd9Sstevel@tonic-gate Error++; 887*7c478bd9Sstevel@tonic-gate return; 888*7c478bd9Sstevel@tonic-gate } else { 889*7c478bd9Sstevel@tonic-gate /* Real EOF */ 890*7c478bd9Sstevel@tonic-gate for (*s = WEOF; p <= &Colpts[Ncols]; ++p) 891*7c478bd9Sstevel@tonic-gate p->c_ptr0 = p->c_ptr = s; 892*7c478bd9Sstevel@tonic-gate balance(bline); 893*7c478bd9Sstevel@tonic-gate return; 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate if (isascii(wc)) { 898*7c478bd9Sstevel@tonic-gate if (isprint(wc)) 899*7c478bd9Sstevel@tonic-gate Inpos++; 900*7c478bd9Sstevel@tonic-gate } else if (iswprint(wc)) { 901*7c478bd9Sstevel@tonic-gate Inpos += wcwidth(wc); 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate 904*7c478bd9Sstevel@tonic-gate if (Inpos <= Colw || wc == '\n') { 905*7c478bd9Sstevel@tonic-gate *s = wc; 906*7c478bd9Sstevel@tonic-gate if (++s >= Bufend) 907*7c478bd9Sstevel@tonic-gate die("page-buffer overflow"); 908*7c478bd9Sstevel@tonic-gate } 909*7c478bd9Sstevel@tonic-gate if (wc == '\n') 910*7c478bd9Sstevel@tonic-gate break; 911*7c478bd9Sstevel@tonic-gate switch (wc) { 912*7c478bd9Sstevel@tonic-gate case '\b': 913*7c478bd9Sstevel@tonic-gate if (Inpos == 0) 914*7c478bd9Sstevel@tonic-gate --s; 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate case ESC: 919*7c478bd9Sstevel@tonic-gate if (Inpos > 0) 920*7c478bd9Sstevel@tonic-gate --Inpos; 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate } 923*7c478bd9Sstevel@tonic-gate } 924*7c478bd9Sstevel@tonic-gate } 925*7c478bd9Sstevel@tonic-gate } 926*7c478bd9Sstevel@tonic-gate 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate static void 929*7c478bd9Sstevel@tonic-gate foldbuf() 930*7c478bd9Sstevel@tonic-gate { 931*7c478bd9Sstevel@tonic-gate int num; 932*7c478bd9Sstevel@tonic-gate int i; 933*7c478bd9Sstevel@tonic-gate int colno = 0; 934*7c478bd9Sstevel@tonic-gate int size = Buflen; 935*7c478bd9Sstevel@tonic-gate wchar_t *s; 936*7c478bd9Sstevel@tonic-gate wchar_t *d; 937*7c478bd9Sstevel@tonic-gate COLP p = Colpts; 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate for (i = 0; i < Ncols; i++) 940*7c478bd9Sstevel@tonic-gate Fcol[i].eof = 0; 941*7c478bd9Sstevel@tonic-gate d = Buffer; 942*7c478bd9Sstevel@tonic-gate if (Bufptr != Bufend) { 943*7c478bd9Sstevel@tonic-gate s = Bufptr; 944*7c478bd9Sstevel@tonic-gate while (s < Bufend) 945*7c478bd9Sstevel@tonic-gate *d++ = *s++; 946*7c478bd9Sstevel@tonic-gate size -= (Bufend - Bufptr); 947*7c478bd9Sstevel@tonic-gate } 948*7c478bd9Sstevel@tonic-gate Bufptr = Buffer; 949*7c478bd9Sstevel@tonic-gate p->c_ptr0 = p->c_ptr = Buffer; 950*7c478bd9Sstevel@tonic-gate if (p->c_lno == 0) { 951*7c478bd9Sstevel@tonic-gate p->c_lno = Lnumb; 952*7c478bd9Sstevel@tonic-gate p->c_skip = 0; 953*7c478bd9Sstevel@tonic-gate } else { 954*7c478bd9Sstevel@tonic-gate p->c_lno = Colpts[Ncols-1].c_lno; 955*7c478bd9Sstevel@tonic-gate p->c_skip = Colpts[Ncols].c_skip; 956*7c478bd9Sstevel@tonic-gate if (p->c_skip) 957*7c478bd9Sstevel@tonic-gate p->c_lno--; 958*7c478bd9Sstevel@tonic-gate } 959*7c478bd9Sstevel@tonic-gate if ((num = freadw(d, size, Files->f_f)) != size) { 960*7c478bd9Sstevel@tonic-gate for (*(d+num) = WEOF; (++p) <= &Colpts[Ncols]; ) { 961*7c478bd9Sstevel@tonic-gate p->c_ptr0 = p->c_ptr = (d+num); 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate balance(0); 964*7c478bd9Sstevel@tonic-gate return; 965*7c478bd9Sstevel@tonic-gate } 966*7c478bd9Sstevel@tonic-gate i = (Length - Margin) / Dblspace; 967*7c478bd9Sstevel@tonic-gate do { 968*7c478bd9Sstevel@tonic-gate (void) readbuf(&Bufptr, i, p++); 969*7c478bd9Sstevel@tonic-gate } while (++colno < Ncols); 970*7c478bd9Sstevel@tonic-gate } 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate static void 974*7c478bd9Sstevel@tonic-gate balance(int bline) /* line balancing for last page */ 975*7c478bd9Sstevel@tonic-gate { 976*7c478bd9Sstevel@tonic-gate wchar_t *s = Buffer; 977*7c478bd9Sstevel@tonic-gate COLP p = Colpts; 978*7c478bd9Sstevel@tonic-gate int colno = 0; 979*7c478bd9Sstevel@tonic-gate int j; 980*7c478bd9Sstevel@tonic-gate int c; 981*7c478bd9Sstevel@tonic-gate int l; 982*7c478bd9Sstevel@tonic-gate int lines; 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate if (!fold) { 985*7c478bd9Sstevel@tonic-gate c = bline % Ncols; 986*7c478bd9Sstevel@tonic-gate l = (bline + Ncols - 1)/Ncols; 987*7c478bd9Sstevel@tonic-gate bline = 0; 988*7c478bd9Sstevel@tonic-gate do { 989*7c478bd9Sstevel@tonic-gate for (j = 0; j < l; ++j) 990*7c478bd9Sstevel@tonic-gate while (*s++ != '\n') 991*7c478bd9Sstevel@tonic-gate ; 992*7c478bd9Sstevel@tonic-gate (++p)->c_lno = Lnumb + (bline += l); 993*7c478bd9Sstevel@tonic-gate p->c_ptr0 = p->c_ptr = s; 994*7c478bd9Sstevel@tonic-gate if (++colno == c) 995*7c478bd9Sstevel@tonic-gate --l; 996*7c478bd9Sstevel@tonic-gate } while (colno < Ncols - 1); 997*7c478bd9Sstevel@tonic-gate } else { 998*7c478bd9Sstevel@tonic-gate lines = readbuf(&s, 0, 0); 999*7c478bd9Sstevel@tonic-gate l = (lines + Ncols - 1)/Ncols; 1000*7c478bd9Sstevel@tonic-gate if (l > ((Length - Margin) / Dblspace)) { 1001*7c478bd9Sstevel@tonic-gate l = (Length - Margin) / Dblspace; 1002*7c478bd9Sstevel@tonic-gate c = Ncols; 1003*7c478bd9Sstevel@tonic-gate } else { 1004*7c478bd9Sstevel@tonic-gate c = lines % Ncols; 1005*7c478bd9Sstevel@tonic-gate } 1006*7c478bd9Sstevel@tonic-gate s = Buffer; 1007*7c478bd9Sstevel@tonic-gate do { 1008*7c478bd9Sstevel@tonic-gate (void) readbuf(&s, l, p++); 1009*7c478bd9Sstevel@tonic-gate if (++colno == c) 1010*7c478bd9Sstevel@tonic-gate --l; 1011*7c478bd9Sstevel@tonic-gate } while (colno < Ncols); 1012*7c478bd9Sstevel@tonic-gate Bufptr = s; 1013*7c478bd9Sstevel@tonic-gate } 1014*7c478bd9Sstevel@tonic-gate } 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate 1017*7c478bd9Sstevel@tonic-gate static int 1018*7c478bd9Sstevel@tonic-gate readbuf(wchar_t **s, int lincol, COLP p) 1019*7c478bd9Sstevel@tonic-gate { 1020*7c478bd9Sstevel@tonic-gate int lines = 0; 1021*7c478bd9Sstevel@tonic-gate int chars = 0; 1022*7c478bd9Sstevel@tonic-gate int width; 1023*7c478bd9Sstevel@tonic-gate int nls = 0; 1024*7c478bd9Sstevel@tonic-gate int move; 1025*7c478bd9Sstevel@tonic-gate int skip = 0; 1026*7c478bd9Sstevel@tonic-gate int decr = 0; 1027*7c478bd9Sstevel@tonic-gate 1028*7c478bd9Sstevel@tonic-gate width = (Ncols == 1) ? Linew : Colw; 1029*7c478bd9Sstevel@tonic-gate while (**s != WEOF) { 1030*7c478bd9Sstevel@tonic-gate switch (**s) { 1031*7c478bd9Sstevel@tonic-gate case '\n': 1032*7c478bd9Sstevel@tonic-gate lines++; nls++; chars = 0; skip = 0; 1033*7c478bd9Sstevel@tonic-gate break; 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate case '\b': 1036*7c478bd9Sstevel@tonic-gate case ESC: 1037*7c478bd9Sstevel@tonic-gate if (chars) chars--; 1038*7c478bd9Sstevel@tonic-gate break; 1039*7c478bd9Sstevel@tonic-gate 1040*7c478bd9Sstevel@tonic-gate case '\t': 1041*7c478bd9Sstevel@tonic-gate move = Itabn - ((chars + Itabn) % Itabn); 1042*7c478bd9Sstevel@tonic-gate move = (move < width-chars) ? move : 1043*7c478bd9Sstevel@tonic-gate width-chars; 1044*7c478bd9Sstevel@tonic-gate chars += move; 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate default: 1047*7c478bd9Sstevel@tonic-gate if (isascii(**s)) { 1048*7c478bd9Sstevel@tonic-gate if (isprint(**s)) 1049*7c478bd9Sstevel@tonic-gate chars++; 1050*7c478bd9Sstevel@tonic-gate } else if (iswprint(**s)) { 1051*7c478bd9Sstevel@tonic-gate chars += wcwidth(**s); 1052*7c478bd9Sstevel@tonic-gate } 1053*7c478bd9Sstevel@tonic-gate } 1054*7c478bd9Sstevel@tonic-gate if (chars > width) { 1055*7c478bd9Sstevel@tonic-gate lines++; 1056*7c478bd9Sstevel@tonic-gate skip++; 1057*7c478bd9Sstevel@tonic-gate decr++; 1058*7c478bd9Sstevel@tonic-gate chars = 0; 1059*7c478bd9Sstevel@tonic-gate } 1060*7c478bd9Sstevel@tonic-gate if (lincol && lines == lincol) { 1061*7c478bd9Sstevel@tonic-gate (p+1)->c_lno = p->c_lno + nls; 1062*7c478bd9Sstevel@tonic-gate (++p)->c_skip = skip; 1063*7c478bd9Sstevel@tonic-gate if (**s == '\n') (*s)++; 1064*7c478bd9Sstevel@tonic-gate p->c_ptr0 = p->c_ptr = (wchar_t *)*s; 1065*7c478bd9Sstevel@tonic-gate return (0); 1066*7c478bd9Sstevel@tonic-gate } 1067*7c478bd9Sstevel@tonic-gate if (decr) 1068*7c478bd9Sstevel@tonic-gate decr = 0; 1069*7c478bd9Sstevel@tonic-gate else 1070*7c478bd9Sstevel@tonic-gate (*s)++; 1071*7c478bd9Sstevel@tonic-gate } 1072*7c478bd9Sstevel@tonic-gate return (lines); 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate static wint_t 1077*7c478bd9Sstevel@tonic-gate get(int colno) 1078*7c478bd9Sstevel@tonic-gate { 1079*7c478bd9Sstevel@tonic-gate static int peekc = 0; 1080*7c478bd9Sstevel@tonic-gate COLP p; 1081*7c478bd9Sstevel@tonic-gate FILS *q; 1082*7c478bd9Sstevel@tonic-gate int c; 1083*7c478bd9Sstevel@tonic-gate wchar_t wc, w; 1084*7c478bd9Sstevel@tonic-gate 1085*7c478bd9Sstevel@tonic-gate if (peekc) { 1086*7c478bd9Sstevel@tonic-gate peekc = 0; 1087*7c478bd9Sstevel@tonic-gate wc = Etabc; 1088*7c478bd9Sstevel@tonic-gate } else if (Buffer) { 1089*7c478bd9Sstevel@tonic-gate p = &Colpts[colno]; 1090*7c478bd9Sstevel@tonic-gate if (p->c_ptr >= (p+1)->c_ptr0) 1091*7c478bd9Sstevel@tonic-gate wc = WEOF; 1092*7c478bd9Sstevel@tonic-gate else if ((wc = *p->c_ptr) != WEOF) 1093*7c478bd9Sstevel@tonic-gate ++p->c_ptr; 1094*7c478bd9Sstevel@tonic-gate if (fold && wc == WEOF) 1095*7c478bd9Sstevel@tonic-gate Fcol[colno].eof = 1; 1096*7c478bd9Sstevel@tonic-gate } else if ((wc = 1097*7c478bd9Sstevel@tonic-gate (q = &Files[Multi == 'a' ? 0 : colno])->f_nextc) == WEOF) { 1098*7c478bd9Sstevel@tonic-gate for (q = &Files[Nfiles]; --q >= Files && q->f_nextc == WEOF; ) 1099*7c478bd9Sstevel@tonic-gate ; 1100*7c478bd9Sstevel@tonic-gate if (q >= Files) 1101*7c478bd9Sstevel@tonic-gate wc = '\n'; 1102*7c478bd9Sstevel@tonic-gate } else { 1103*7c478bd9Sstevel@tonic-gate errno = 0; 1104*7c478bd9Sstevel@tonic-gate w = _fgetwc_pr(q->f_f, &c); 1105*7c478bd9Sstevel@tonic-gate if (w == WEOF && errno == EILSEQ) { 1106*7c478bd9Sstevel@tonic-gate q->f_nextc = (wchar_t)c; 1107*7c478bd9Sstevel@tonic-gate } else { 1108*7c478bd9Sstevel@tonic-gate q->f_nextc = w; 1109*7c478bd9Sstevel@tonic-gate } 1110*7c478bd9Sstevel@tonic-gate } 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate if (Etabn != 0 && wc == Etabc) { 1113*7c478bd9Sstevel@tonic-gate ++Inpos; 1114*7c478bd9Sstevel@tonic-gate peekc = ETABS; 1115*7c478bd9Sstevel@tonic-gate wc = ' '; 1116*7c478bd9Sstevel@tonic-gate return (C = wc); 1117*7c478bd9Sstevel@tonic-gate } 1118*7c478bd9Sstevel@tonic-gate 1119*7c478bd9Sstevel@tonic-gate if (wc == WEOF) 1120*7c478bd9Sstevel@tonic-gate return (C = wc); 1121*7c478bd9Sstevel@tonic-gate 1122*7c478bd9Sstevel@tonic-gate if (isascii(wc)) { 1123*7c478bd9Sstevel@tonic-gate if (isprint(wc)) { 1124*7c478bd9Sstevel@tonic-gate Inpos++; 1125*7c478bd9Sstevel@tonic-gate return (C = wc); 1126*7c478bd9Sstevel@tonic-gate } 1127*7c478bd9Sstevel@tonic-gate } else if (iswprint(wc)) { 1128*7c478bd9Sstevel@tonic-gate Inpos += wcwidth(wc); 1129*7c478bd9Sstevel@tonic-gate return (C = wc); 1130*7c478bd9Sstevel@tonic-gate } 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate switch (wc) { 1133*7c478bd9Sstevel@tonic-gate case '\b': 1134*7c478bd9Sstevel@tonic-gate case ESC: 1135*7c478bd9Sstevel@tonic-gate if (Inpos > 0) 1136*7c478bd9Sstevel@tonic-gate --Inpos; 1137*7c478bd9Sstevel@tonic-gate break; 1138*7c478bd9Sstevel@tonic-gate case '\f': 1139*7c478bd9Sstevel@tonic-gate if (Ncols == 1) 1140*7c478bd9Sstevel@tonic-gate break; 1141*7c478bd9Sstevel@tonic-gate wc = '\n'; 1142*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 1143*7c478bd9Sstevel@tonic-gate case '\n': 1144*7c478bd9Sstevel@tonic-gate case '\r': 1145*7c478bd9Sstevel@tonic-gate Inpos = 0; 1146*7c478bd9Sstevel@tonic-gate break; 1147*7c478bd9Sstevel@tonic-gate } 1148*7c478bd9Sstevel@tonic-gate return (C = wc); 1149*7c478bd9Sstevel@tonic-gate } 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate 1152*7c478bd9Sstevel@tonic-gate static int 1153*7c478bd9Sstevel@tonic-gate put(wchar_t wc) 1154*7c478bd9Sstevel@tonic-gate { 1155*7c478bd9Sstevel@tonic-gate int move = 0; 1156*7c478bd9Sstevel@tonic-gate int width = Colw; 1157*7c478bd9Sstevel@tonic-gate int sp = Lcolpos; 1158*7c478bd9Sstevel@tonic-gate 1159*7c478bd9Sstevel@tonic-gate if (fold && Ncols == 1) 1160*7c478bd9Sstevel@tonic-gate width = Linew; 1161*7c478bd9Sstevel@tonic-gate 1162*7c478bd9Sstevel@tonic-gate switch (wc) { 1163*7c478bd9Sstevel@tonic-gate case ' ': 1164*7c478bd9Sstevel@tonic-gate /* If column not full or this is separator char */ 1165*7c478bd9Sstevel@tonic-gate if ((!fold && Ncols < 2) || (Lcolpos < width) || 1166*7c478bd9Sstevel@tonic-gate ((Sepc == wc) && (Lcolpos == width))) { 1167*7c478bd9Sstevel@tonic-gate ++Nspace; 1168*7c478bd9Sstevel@tonic-gate ++Lcolpos; 1169*7c478bd9Sstevel@tonic-gate } 1170*7c478bd9Sstevel@tonic-gate if (fold && sp == Lcolpos) 1171*7c478bd9Sstevel@tonic-gate if (Lcolpos >= width) 1172*7c478bd9Sstevel@tonic-gate return (1); 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate return (0); 1175*7c478bd9Sstevel@tonic-gate 1176*7c478bd9Sstevel@tonic-gate case '\t': 1177*7c478bd9Sstevel@tonic-gate if (Itabn == 0) 1178*7c478bd9Sstevel@tonic-gate break; 1179*7c478bd9Sstevel@tonic-gate 1180*7c478bd9Sstevel@tonic-gate /* If column not full or this is separator char */ 1181*7c478bd9Sstevel@tonic-gate if ((Lcolpos < width) || 1182*7c478bd9Sstevel@tonic-gate ((Sepc == wc) && (Lcolpos == width))) { 1183*7c478bd9Sstevel@tonic-gate move = Itabn - ((Lcolpos + Itabn) % Itabn); 1184*7c478bd9Sstevel@tonic-gate move = (move < width-Lcolpos) ? move : width-Lcolpos; 1185*7c478bd9Sstevel@tonic-gate Nspace += move; 1186*7c478bd9Sstevel@tonic-gate Lcolpos += move; 1187*7c478bd9Sstevel@tonic-gate } 1188*7c478bd9Sstevel@tonic-gate if (fold && sp == Lcolpos) 1189*7c478bd9Sstevel@tonic-gate if (Lcolpos >= width) 1190*7c478bd9Sstevel@tonic-gate return (1); 1191*7c478bd9Sstevel@tonic-gate return (0); 1192*7c478bd9Sstevel@tonic-gate 1193*7c478bd9Sstevel@tonic-gate case '\b': 1194*7c478bd9Sstevel@tonic-gate if (Lcolpos == 0) 1195*7c478bd9Sstevel@tonic-gate return (0); 1196*7c478bd9Sstevel@tonic-gate if (Nspace > 0) { 1197*7c478bd9Sstevel@tonic-gate --Nspace; 1198*7c478bd9Sstevel@tonic-gate --Lcolpos; 1199*7c478bd9Sstevel@tonic-gate return (0); 1200*7c478bd9Sstevel@tonic-gate } 1201*7c478bd9Sstevel@tonic-gate if (Lcolpos > Pcolpos) { 1202*7c478bd9Sstevel@tonic-gate --Lcolpos; 1203*7c478bd9Sstevel@tonic-gate return (0); 1204*7c478bd9Sstevel@tonic-gate } 1205*7c478bd9Sstevel@tonic-gate 1206*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 1207*7c478bd9Sstevel@tonic-gate 1208*7c478bd9Sstevel@tonic-gate case ESC: 1209*7c478bd9Sstevel@tonic-gate move = -1; 1210*7c478bd9Sstevel@tonic-gate break; 1211*7c478bd9Sstevel@tonic-gate 1212*7c478bd9Sstevel@tonic-gate case '\n': 1213*7c478bd9Sstevel@tonic-gate ++Line; 1214*7c478bd9Sstevel@tonic-gate 1215*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 1216*7c478bd9Sstevel@tonic-gate 1217*7c478bd9Sstevel@tonic-gate case '\r': 1218*7c478bd9Sstevel@tonic-gate case '\f': 1219*7c478bd9Sstevel@tonic-gate Pcolpos = 0; 1220*7c478bd9Sstevel@tonic-gate Lcolpos = 0; 1221*7c478bd9Sstevel@tonic-gate Nspace = 0; 1222*7c478bd9Sstevel@tonic-gate Outpos = 0; 1223*7c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 1224*7c478bd9Sstevel@tonic-gate default: 1225*7c478bd9Sstevel@tonic-gate if (isascii(wc)) { 1226*7c478bd9Sstevel@tonic-gate if (isprint(wc)) 1227*7c478bd9Sstevel@tonic-gate move = 1; 1228*7c478bd9Sstevel@tonic-gate else 1229*7c478bd9Sstevel@tonic-gate move = 0; 1230*7c478bd9Sstevel@tonic-gate } else if (iswprint(wc)) { 1231*7c478bd9Sstevel@tonic-gate move = wcwidth(wc); 1232*7c478bd9Sstevel@tonic-gate } else { 1233*7c478bd9Sstevel@tonic-gate move = 0; 1234*7c478bd9Sstevel@tonic-gate } 1235*7c478bd9Sstevel@tonic-gate break; 1236*7c478bd9Sstevel@tonic-gate } 1237*7c478bd9Sstevel@tonic-gate if (Page < Fpage) 1238*7c478bd9Sstevel@tonic-gate return (0); 1239*7c478bd9Sstevel@tonic-gate if (Lcolpos > 0 || move > 0) 1240*7c478bd9Sstevel@tonic-gate Lcolpos += move; 1241*7c478bd9Sstevel@tonic-gate 1242*7c478bd9Sstevel@tonic-gate putspace(); 1243*7c478bd9Sstevel@tonic-gate 1244*7c478bd9Sstevel@tonic-gate /* If column not full or this is separator char */ 1245*7c478bd9Sstevel@tonic-gate if ((!fold && Ncols < 2) || (Lcolpos <= width) || 1246*7c478bd9Sstevel@tonic-gate ((Sepc == wc) && (Lcolpos > width))) { 1247*7c478bd9Sstevel@tonic-gate (void) fputwc(wc, stdout); 1248*7c478bd9Sstevel@tonic-gate Outpos += move; 1249*7c478bd9Sstevel@tonic-gate Pcolpos = Lcolpos; 1250*7c478bd9Sstevel@tonic-gate } 1251*7c478bd9Sstevel@tonic-gate 1252*7c478bd9Sstevel@tonic-gate if (fold && Lcolpos > width) 1253*7c478bd9Sstevel@tonic-gate return (1); 1254*7c478bd9Sstevel@tonic-gate 1255*7c478bd9Sstevel@tonic-gate return (0); 1256*7c478bd9Sstevel@tonic-gate } 1257*7c478bd9Sstevel@tonic-gate 1258*7c478bd9Sstevel@tonic-gate 1259*7c478bd9Sstevel@tonic-gate static void 1260*7c478bd9Sstevel@tonic-gate putspace(void) 1261*7c478bd9Sstevel@tonic-gate { 1262*7c478bd9Sstevel@tonic-gate int nc = 0; 1263*7c478bd9Sstevel@tonic-gate 1264*7c478bd9Sstevel@tonic-gate for (; Nspace > 0; Outpos += nc, Nspace -= nc) { 1265*7c478bd9Sstevel@tonic-gate #ifdef XPG4 1266*7c478bd9Sstevel@tonic-gate /* XPG4: -i: replace multiple SPACE chars with tab chars */ 1267*7c478bd9Sstevel@tonic-gate if ((Nspace >= 2 && Itabn > 0 && 1268*7c478bd9Sstevel@tonic-gate Nspace >= (nc = Itabn - Outpos % Itabn)) && !fold) { 1269*7c478bd9Sstevel@tonic-gate #else 1270*7c478bd9Sstevel@tonic-gate /* Solaris: -i: replace white space with tab chars */ 1271*7c478bd9Sstevel@tonic-gate if ((Itabn > 0 && Nspace >= (nc = Itabn - Outpos % Itabn)) && 1272*7c478bd9Sstevel@tonic-gate !fold) { 1273*7c478bd9Sstevel@tonic-gate #endif 1274*7c478bd9Sstevel@tonic-gate (void) fputwc(Itabc, stdout); 1275*7c478bd9Sstevel@tonic-gate } else { 1276*7c478bd9Sstevel@tonic-gate nc = 1; 1277*7c478bd9Sstevel@tonic-gate (void) putchar(' '); 1278*7c478bd9Sstevel@tonic-gate } 1279*7c478bd9Sstevel@tonic-gate } 1280*7c478bd9Sstevel@tonic-gate } 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate 1283*7c478bd9Sstevel@tonic-gate static void 1284*7c478bd9Sstevel@tonic-gate unget(int colno) 1285*7c478bd9Sstevel@tonic-gate { 1286*7c478bd9Sstevel@tonic-gate if (Buffer) { 1287*7c478bd9Sstevel@tonic-gate if (*(Colpts[colno].c_ptr-1) != '\t') 1288*7c478bd9Sstevel@tonic-gate --(Colpts[colno].c_ptr); 1289*7c478bd9Sstevel@tonic-gate if (Colpts[colno].c_lno) 1290*7c478bd9Sstevel@tonic-gate Colpts[colno].c_lno--; 1291*7c478bd9Sstevel@tonic-gate } else { 1292*7c478bd9Sstevel@tonic-gate if ((Multi == 'm' && colno == 0) || Multi != 'm') 1293*7c478bd9Sstevel@tonic-gate if (Lnumb && !foldcol) 1294*7c478bd9Sstevel@tonic-gate Lnumb--; 1295*7c478bd9Sstevel@tonic-gate colno = (Multi == 'a') ? 0 : colno; 1296*7c478bd9Sstevel@tonic-gate (void) ungetwc(Files[colno].f_nextc, Files[colno].f_f); 1297*7c478bd9Sstevel@tonic-gate Files[colno].f_nextc = C; 1298*7c478bd9Sstevel@tonic-gate } 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate 1301*7c478bd9Sstevel@tonic-gate 1302*7c478bd9Sstevel@tonic-gate /* 1303*7c478bd9Sstevel@tonic-gate * Defer message about failure to open file to prevent messing up 1304*7c478bd9Sstevel@tonic-gate * alignment of page with tear perforations or form markers. 1305*7c478bd9Sstevel@tonic-gate * Treat empty file as special case and report as diagnostic. 1306*7c478bd9Sstevel@tonic-gate */ 1307*7c478bd9Sstevel@tonic-gate 1308*7c478bd9Sstevel@tonic-gate static FILE * 1309*7c478bd9Sstevel@tonic-gate mustopen(char *s, FILS *f) 1310*7c478bd9Sstevel@tonic-gate { 1311*7c478bd9Sstevel@tonic-gate char *empty_file_msg = gettext("%s -- empty file"); 1312*7c478bd9Sstevel@tonic-gate int c; 1313*7c478bd9Sstevel@tonic-gate 1314*7c478bd9Sstevel@tonic-gate if (*s == '\0') { 1315*7c478bd9Sstevel@tonic-gate f->f_name = STDINNAME(); 1316*7c478bd9Sstevel@tonic-gate f->f_f = stdin; 1317*7c478bd9Sstevel@tonic-gate } else if ((f->f_f = fopen(f->f_name = s, "r")) == NULL) { 1318*7c478bd9Sstevel@tonic-gate s = ffiler(f->f_name); 1319*7c478bd9Sstevel@tonic-gate s = strcpy((char *)getspace((UNS) strlen(s) + 1), s); 1320*7c478bd9Sstevel@tonic-gate } 1321*7c478bd9Sstevel@tonic-gate if (f->f_f != NULL) { 1322*7c478bd9Sstevel@tonic-gate errno = 0; 1323*7c478bd9Sstevel@tonic-gate f->f_nextc = _fgetwc_pr(f->f_f, &c); 1324*7c478bd9Sstevel@tonic-gate if (f->f_nextc != WEOF) { 1325*7c478bd9Sstevel@tonic-gate return (f->f_f); 1326*7c478bd9Sstevel@tonic-gate } else { /* WEOF */ 1327*7c478bd9Sstevel@tonic-gate if (errno == EILSEQ) { 1328*7c478bd9Sstevel@tonic-gate f->f_nextc = (wchar_t)c; 1329*7c478bd9Sstevel@tonic-gate return (f->f_f); 1330*7c478bd9Sstevel@tonic-gate } 1331*7c478bd9Sstevel@tonic-gate if (Multi == 'm') 1332*7c478bd9Sstevel@tonic-gate return (f->f_f); 1333*7c478bd9Sstevel@tonic-gate } 1334*7c478bd9Sstevel@tonic-gate (void) sprintf(s = (char *)getspace((UNS) strlen(f->f_name) 1335*7c478bd9Sstevel@tonic-gate + 1 + (UNS) strlen(empty_file_msg)), 1336*7c478bd9Sstevel@tonic-gate empty_file_msg, f->f_name); 1337*7c478bd9Sstevel@tonic-gate (void) fclose(f->f_f); 1338*7c478bd9Sstevel@tonic-gate } 1339*7c478bd9Sstevel@tonic-gate Error = 1; 1340*7c478bd9Sstevel@tonic-gate if (Report) 1341*7c478bd9Sstevel@tonic-gate if (Ttyout) { /* accumulate error reports */ 1342*7c478bd9Sstevel@tonic-gate Lasterr = Lasterr->e_nextp = 1343*7c478bd9Sstevel@tonic-gate (ERR *) getspace((UNS) sizeof (ERR)); 1344*7c478bd9Sstevel@tonic-gate Lasterr->e_nextp = NULL; 1345*7c478bd9Sstevel@tonic-gate Lasterr->e_mess = s; 1346*7c478bd9Sstevel@tonic-gate } else { /* ok to print error report now */ 1347*7c478bd9Sstevel@tonic-gate cerror(s); 1348*7c478bd9Sstevel@tonic-gate (void) putc('\n', stderr); 1349*7c478bd9Sstevel@tonic-gate } 1350*7c478bd9Sstevel@tonic-gate return ((FILE *)NULL); 1351*7c478bd9Sstevel@tonic-gate } 1352*7c478bd9Sstevel@tonic-gate 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate static ANY * 1355*7c478bd9Sstevel@tonic-gate getspace(UNS n) 1356*7c478bd9Sstevel@tonic-gate { 1357*7c478bd9Sstevel@tonic-gate ANY *t; 1358*7c478bd9Sstevel@tonic-gate 1359*7c478bd9Sstevel@tonic-gate if ((t = (ANY *) malloc(n)) == NULL) 1360*7c478bd9Sstevel@tonic-gate die("out of space"); 1361*7c478bd9Sstevel@tonic-gate return (t); 1362*7c478bd9Sstevel@tonic-gate } 1363*7c478bd9Sstevel@tonic-gate 1364*7c478bd9Sstevel@tonic-gate 1365*7c478bd9Sstevel@tonic-gate static void 1366*7c478bd9Sstevel@tonic-gate die(char *s) 1367*7c478bd9Sstevel@tonic-gate { 1368*7c478bd9Sstevel@tonic-gate ++Error; 1369*7c478bd9Sstevel@tonic-gate errprint(); 1370*7c478bd9Sstevel@tonic-gate cerror(s); 1371*7c478bd9Sstevel@tonic-gate (void) putc('\n', stderr); 1372*7c478bd9Sstevel@tonic-gate exit(1); 1373*7c478bd9Sstevel@tonic-gate 1374*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 1375*7c478bd9Sstevel@tonic-gate } 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate 1378*7c478bd9Sstevel@tonic-gate static void 1379*7c478bd9Sstevel@tonic-gate errprint() /* print accumulated error reports */ 1380*7c478bd9Sstevel@tonic-gate { 1381*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1382*7c478bd9Sstevel@tonic-gate for (; Err != NULL; Err = Err->e_nextp) { 1383*7c478bd9Sstevel@tonic-gate cerror(Err->e_mess); 1384*7c478bd9Sstevel@tonic-gate (void) putc('\n', stderr); 1385*7c478bd9Sstevel@tonic-gate } 1386*7c478bd9Sstevel@tonic-gate done(); 1387*7c478bd9Sstevel@tonic-gate } 1388*7c478bd9Sstevel@tonic-gate 1389*7c478bd9Sstevel@tonic-gate 1390*7c478bd9Sstevel@tonic-gate static void 1391*7c478bd9Sstevel@tonic-gate fixtty() 1392*7c478bd9Sstevel@tonic-gate { 1393*7c478bd9Sstevel@tonic-gate struct stat sbuf; 1394*7c478bd9Sstevel@tonic-gate 1395*7c478bd9Sstevel@tonic-gate setbuf(stdout, obuf); 1396*7c478bd9Sstevel@tonic-gate if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1397*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, onintr); 1398*7c478bd9Sstevel@tonic-gate if (Ttyout = ttyname(fileno(stdout))) { /* is stdout a tty? */ 1399*7c478bd9Sstevel@tonic-gate (void) stat(Ttyout, &sbuf); 1400*7c478bd9Sstevel@tonic-gate Mode = sbuf.st_mode; /* save permissions */ 1401*7c478bd9Sstevel@tonic-gate (void) chmod(Ttyout, (S_IREAD|S_IWRITE)); 1402*7c478bd9Sstevel@tonic-gate } 1403*7c478bd9Sstevel@tonic-gate } 1404*7c478bd9Sstevel@tonic-gate 1405*7c478bd9Sstevel@tonic-gate 1406*7c478bd9Sstevel@tonic-gate static void 1407*7c478bd9Sstevel@tonic-gate onintr() 1408*7c478bd9Sstevel@tonic-gate { 1409*7c478bd9Sstevel@tonic-gate ++Error; 1410*7c478bd9Sstevel@tonic-gate errprint(); 1411*7c478bd9Sstevel@tonic-gate _exit(1); 1412*7c478bd9Sstevel@tonic-gate } 1413*7c478bd9Sstevel@tonic-gate 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate static char * 1416*7c478bd9Sstevel@tonic-gate GETDATE() /* return date file was last modified */ 1417*7c478bd9Sstevel@tonic-gate { 1418*7c478bd9Sstevel@tonic-gate static char *now = NULL; 1419*7c478bd9Sstevel@tonic-gate static struct stat sbuf; 1420*7c478bd9Sstevel@tonic-gate static struct stat nbuf; 1421*7c478bd9Sstevel@tonic-gate 1422*7c478bd9Sstevel@tonic-gate if (Nfiles > 1 || Files->f_name == nulls) { 1423*7c478bd9Sstevel@tonic-gate if (now == NULL) { 1424*7c478bd9Sstevel@tonic-gate (void) time(&nbuf.st_mtime); 1425*7c478bd9Sstevel@tonic-gate (void) cftime(time_buf, 1426*7c478bd9Sstevel@tonic-gate dcgettext(NULL, FORMAT, LC_TIME), 1427*7c478bd9Sstevel@tonic-gate &nbuf.st_mtime); 1428*7c478bd9Sstevel@tonic-gate now = time_buf; 1429*7c478bd9Sstevel@tonic-gate } 1430*7c478bd9Sstevel@tonic-gate return (now); 1431*7c478bd9Sstevel@tonic-gate } else { 1432*7c478bd9Sstevel@tonic-gate (void) stat(Files->f_name, &sbuf); 1433*7c478bd9Sstevel@tonic-gate (void) cftime(time_buf, dcgettext(NULL, FORMAT, LC_TIME), 1434*7c478bd9Sstevel@tonic-gate &sbuf.st_mtime); 1435*7c478bd9Sstevel@tonic-gate return (time_buf); 1436*7c478bd9Sstevel@tonic-gate } 1437*7c478bd9Sstevel@tonic-gate } 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate 1440*7c478bd9Sstevel@tonic-gate static char * 1441*7c478bd9Sstevel@tonic-gate ffiler(char *s) 1442*7c478bd9Sstevel@tonic-gate { 1443*7c478bd9Sstevel@tonic-gate static char buf[100]; 1444*7c478bd9Sstevel@tonic-gate 1445*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, gettext("can't open %s"), s); 1446*7c478bd9Sstevel@tonic-gate return (buf); 1447*7c478bd9Sstevel@tonic-gate } 1448*7c478bd9Sstevel@tonic-gate 1449*7c478bd9Sstevel@tonic-gate 1450*7c478bd9Sstevel@tonic-gate static void 1451*7c478bd9Sstevel@tonic-gate usage(int rc) 1452*7c478bd9Sstevel@tonic-gate { 1453*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1454*7c478bd9Sstevel@tonic-gate "usage: pr [-# [-w #] [-a]] [-e[c][#]] [-i[c][#]] [-drtfp] [-n[c][#]] \\\n" 1455*7c478bd9Sstevel@tonic-gate " [-o #] [-l #] [-s[char]] [-h header] [-F] [+#] [file ...]\n\n" 1456*7c478bd9Sstevel@tonic-gate " pr [-m [-w #]] [-e[c][#]] [-i[c][#]] [-drtfp] [-n[c][#]] [-0 #] \\\n" 1457*7c478bd9Sstevel@tonic-gate " [-l #] [-s[char]] [-h header] [-F] [+#] file1 file2 ...\n" 1458*7c478bd9Sstevel@tonic-gate )); 1459*7c478bd9Sstevel@tonic-gate exit(rc); 1460*7c478bd9Sstevel@tonic-gate } 1461*7c478bd9Sstevel@tonic-gate 1462*7c478bd9Sstevel@tonic-gate static wint_t 1463*7c478bd9Sstevel@tonic-gate _fgetwc_pr(FILE *f, int *ic) 1464*7c478bd9Sstevel@tonic-gate { 1465*7c478bd9Sstevel@tonic-gate int i; 1466*7c478bd9Sstevel@tonic-gate int len; 1467*7c478bd9Sstevel@tonic-gate char mbuf[MB_LEN_MAX]; 1468*7c478bd9Sstevel@tonic-gate int c; 1469*7c478bd9Sstevel@tonic-gate wchar_t wc; 1470*7c478bd9Sstevel@tonic-gate 1471*7c478bd9Sstevel@tonic-gate c = getc(f); 1472*7c478bd9Sstevel@tonic-gate 1473*7c478bd9Sstevel@tonic-gate if (c == EOF) 1474*7c478bd9Sstevel@tonic-gate return (WEOF); 1475*7c478bd9Sstevel@tonic-gate if (mbcurmax == 1 || isascii(c)) { 1476*7c478bd9Sstevel@tonic-gate return ((wint_t)c); 1477*7c478bd9Sstevel@tonic-gate } 1478*7c478bd9Sstevel@tonic-gate mbuf[0] = (char)c; 1479*7c478bd9Sstevel@tonic-gate for (i = 1; i < mbcurmax; i++) { 1480*7c478bd9Sstevel@tonic-gate c = getc(f); 1481*7c478bd9Sstevel@tonic-gate if (c == EOF) { 1482*7c478bd9Sstevel@tonic-gate break; 1483*7c478bd9Sstevel@tonic-gate } else { 1484*7c478bd9Sstevel@tonic-gate mbuf[i] = (char)c; 1485*7c478bd9Sstevel@tonic-gate } 1486*7c478bd9Sstevel@tonic-gate } 1487*7c478bd9Sstevel@tonic-gate mbuf[i] = 0; 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate len = mbtowc(&wc, mbuf, i); 1490*7c478bd9Sstevel@tonic-gate if (len == -1) { 1491*7c478bd9Sstevel@tonic-gate /* Illegal character */ 1492*7c478bd9Sstevel@tonic-gate /* Set the first byte to *ic */ 1493*7c478bd9Sstevel@tonic-gate *ic = mbuf[0]; 1494*7c478bd9Sstevel@tonic-gate /* Push back remaining characters */ 1495*7c478bd9Sstevel@tonic-gate for (i--; i > 0; i--) { 1496*7c478bd9Sstevel@tonic-gate (void) ungetc(mbuf[i], f); 1497*7c478bd9Sstevel@tonic-gate } 1498*7c478bd9Sstevel@tonic-gate errno = EILSEQ; 1499*7c478bd9Sstevel@tonic-gate return (WEOF); 1500*7c478bd9Sstevel@tonic-gate } else { 1501*7c478bd9Sstevel@tonic-gate /* Push back over-read characters */ 1502*7c478bd9Sstevel@tonic-gate for (i--; i >= len; i--) { 1503*7c478bd9Sstevel@tonic-gate (void) ungetc(mbuf[i], f); 1504*7c478bd9Sstevel@tonic-gate } 1505*7c478bd9Sstevel@tonic-gate return ((wint_t)wc); 1506*7c478bd9Sstevel@tonic-gate } 1507*7c478bd9Sstevel@tonic-gate } 1508*7c478bd9Sstevel@tonic-gate 1509*7c478bd9Sstevel@tonic-gate static size_t 1510*7c478bd9Sstevel@tonic-gate freadw(wchar_t *ptr, size_t nitems, FILE *f) 1511*7c478bd9Sstevel@tonic-gate { 1512*7c478bd9Sstevel@tonic-gate size_t i; 1513*7c478bd9Sstevel@tonic-gate size_t ret; 1514*7c478bd9Sstevel@tonic-gate int c; 1515*7c478bd9Sstevel@tonic-gate wchar_t *p; 1516*7c478bd9Sstevel@tonic-gate wint_t wc; 1517*7c478bd9Sstevel@tonic-gate 1518*7c478bd9Sstevel@tonic-gate if (feof(f)) { 1519*7c478bd9Sstevel@tonic-gate return (0); 1520*7c478bd9Sstevel@tonic-gate } 1521*7c478bd9Sstevel@tonic-gate 1522*7c478bd9Sstevel@tonic-gate p = ptr; 1523*7c478bd9Sstevel@tonic-gate ret = 0; 1524*7c478bd9Sstevel@tonic-gate for (i = 0; i < nitems; i++) { 1525*7c478bd9Sstevel@tonic-gate errno = 0; 1526*7c478bd9Sstevel@tonic-gate wc = _fgetwc_pr(f, &c); 1527*7c478bd9Sstevel@tonic-gate if (wc == WEOF) { 1528*7c478bd9Sstevel@tonic-gate if (errno == EILSEQ) { 1529*7c478bd9Sstevel@tonic-gate *p++ = (wchar_t)c; 1530*7c478bd9Sstevel@tonic-gate ret++; 1531*7c478bd9Sstevel@tonic-gate } else { 1532*7c478bd9Sstevel@tonic-gate return (ret); 1533*7c478bd9Sstevel@tonic-gate } 1534*7c478bd9Sstevel@tonic-gate } else { 1535*7c478bd9Sstevel@tonic-gate *p++ = (wchar_t)wc; 1536*7c478bd9Sstevel@tonic-gate ret++; 1537*7c478bd9Sstevel@tonic-gate } 1538*7c478bd9Sstevel@tonic-gate } 1539*7c478bd9Sstevel@tonic-gate return (ret); 1540*7c478bd9Sstevel@tonic-gate } 1541