4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
33 * University Copyright- Copyright (c) 1982, 1986, 1988
34 * The Regents of the University of California
37 * University Acknowledgment- Portions of this document are derived from
38 * software developed by the University of California, Berkeley, and its
42 #pragma ident "%Z%%M% %I% %E% SMI"
45 * PR command (print files in pages and columns, with headings)
52 #include <sys/types.h>
69 #define STDINNAME() nulls
70 #define PROMPT() (void) putc('\7', stderr) /* BEL */
72 #define ETABS (Inpos % Etabn)
74 #define HEAD gettext("%s %s Page %d\n\n\n"), date, head, Page
75 #define cerror(S) (void) fprintf(stderr, "pr: %s", gettext(S))
76 #define done() if (Ttyout) (void) chmod(Ttyout, Mode)
77 #define ALL_NUMS(s) (strspn(s, "0123456789") == strlen(s))
78 #define REMOVE_ARG(argc, argp) \
88 #define SQUEEZE_ARG(argp, ind, n) \
91 for (i = ind; argp[i]; i++) \
92 argp[i] = argp[i + n]; \
96 * ---date time format---
97 * b -- abbreviated month name
99 * H -- Hour (24 hour version)
101 * Y -- Year in the form ccyy
103 #define FORMAT "%b %e %H:%M %Y"
106 typedef unsigned int UNS
;
107 typedef struct { FILE *f_f
; char *f_name
; wchar_t f_nextc
; } FILS
;
108 typedef struct {int fold
; int skip
; int eof
; } foldinf
;
109 typedef struct { wchar_t *c_ptr
, *c_ptr0
; long c_lno
; int c_skip
; } *COLP
;
110 typedef struct err
{ struct err
*e_nextp
; char *e_mess
; } ERR
;
117 static int Multi
= 0;
118 static int Nfiles
= 0;
119 static int Error
= 0;
120 static char nulls
[] = "";
122 static char obuf
[BUFSIZ
];
123 static char time_buf
[50]; /* array to hold the time and date */
124 static long Lnumb
= 0;
126 static int Dblspace
= 1;
127 static int Fpage
= 1;
128 static int Formfeed
= 0;
129 static int Length
= LENGTH
;
130 static int Linew
= 0;
131 static int Offset
= 0;
132 static int Ncols
= 0;
133 static int Pause
= 0;
134 static wchar_t Sepc
= 0;
137 static int Margin
= MARGIN
;
139 static int Nsepc
= NSEPC
;
140 static int Report
= 1;
141 static int Etabn
= 0;
142 static wchar_t Etabc
= '\t';
143 static int Itabn
= 0;
144 static wchar_t Itabc
= '\t';
146 static int foldcol
= 0;
147 static int alleof
= 0;
148 static char *Head
= NULL
;
149 static wchar_t *Buffer
= NULL
, *Bufend
, *Bufptr
;
152 static foldinf
*Fcol
;
154 static wchar_t C
= '\0';
161 static ERR
*Err
= NULL
;
162 static ERR
*Lasterr
= (ERR
*)&Err
;
163 static int mbcurmax
= 1;
166 * Function prototypes.
168 static void onintr();
169 static ANY
*getspace();
170 static int findopt(int, char **);
171 static void fixtty();
172 static char *GETDATE();
173 static char *ffiler(char *);
174 static int print(char *);
175 static void putpage();
176 static void foldpage();
177 static void nexbuf();
178 static void foldbuf();
179 static void balance(int);
180 static int readbuf(wchar_t **, int, COLP
);
181 static wint_t get(int);
182 static int put(wchar_t);
183 static void putspace();
184 static void unget(int);
185 static FILE *mustopen(char *, FILS
*);
186 static void die(char *);
187 static void errprint();
188 static void usage(int);
189 static wint_t _fgetwc_pr(FILE *, int *);
190 static size_t freadw(wchar_t *, size_t, FILE *);
194 main(int argc
, char **argv
)
201 /* Get locale variables for environment */
202 (void) setlocale(LC_ALL
, "");
204 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
205 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
207 (void) textdomain(TEXT_DOMAIN
);
209 mbcurmax
= MB_CUR_MAX
;
211 for (argc
= findopt(argc
, argv
); argc
> 0; --argc
, ++argv
) {
213 if (Nfiles
>= NFILES
- 1) die("too many files");
214 if (mustopen(*argv
, &Files
[Nfiles
++]) == NULL
)
215 ++nfdone
; /* suppress printing */
218 (void) fclose(Files
->f_f
);
222 if (!nfdone
) /* no files named, use stdin */
223 (void) print(NOFILE
); /* on GCOS, use current file, if any */
226 errprint(); /* print accumulated error reports */
235 * findopt() returns argc modified to be the number of explicitly supplied
236 * filenames, including '-', the explicit request to use stdin.
237 * argc == 0 implies that no filenames were supplied and stdin should be used.
238 * Options are striped from argv and only file names are returned.
242 findopt(int argc
, char **argv
)
256 /* Handle page number option */
257 for (optnum
= 1, end_opt
= 0; optnum
< argc
&& !end_opt
; optnum
++) {
258 switch (*argv
[optnum
]) {
260 /* check for all digits */
261 if (strlen(&argv
[optnum
][1]) !=
262 strspn(&argv
[optnum
][1], "0123456789")) {
263 (void) fprintf(stderr
, gettext(
264 "pr: Badly formed number\n"));
268 if ((Fpage
= (int)strtol(&argv
[optnum
][1],
269 (char **)NULL
, 10)) < 0) {
270 (void) fprintf(stderr
, gettext(
271 "pr: Badly formed number\n"));
274 REMOVE_ARG(argc
, &argv
[optnum
]);
279 /* Check for end of options */
280 if (argv
[optnum
][1] == '-') {
285 if (argv
[optnum
][1] == 'h' || argv
[optnum
][1] == 'l' ||
286 argv
[optnum
][1] == 'o' || argv
[optnum
][1] == 'w')
303 * Handle options with optional arguments.
304 * If optional arguments are present they may not be separated
305 * from the option letter.
308 for (optnum
= 1; optnum
< argc
; optnum
++) {
309 if (argv
[optnum
][0] == '-' && argv
[optnum
][1] == '-')
313 if (argv
[optnum
][0] == '-' && argv
[optnum
][1] == '\0')
314 /* stdin file name */
317 if (argv
[optnum
][0] != '-')
321 for (argv_ind
= 1; argv
[optnum
][argv_ind
] != '\0'; argv_ind
++) {
322 switch (argv
[optnum
][argv_ind
]) {
324 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
325 if ((c
= argv
[optnum
][argv_ind
]) != '\0' &&
329 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
332 (void) fprintf(stderr
, gettext(
333 "pr: Illegal character in -e option\n"));
337 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
339 if (isdigit(argv
[optnum
][argv_ind
])) {
340 Etabn
= (int)strtol(&argv
[optnum
]
341 [argv_ind
], (char **)NULL
, 10);
342 while (isdigit(argv
[optnum
][argv_ind
]))
343 SQUEEZE_ARG(argv
[optnum
],
352 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
353 if ((c
= argv
[optnum
][argv_ind
]) != '\0' &&
357 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
360 (void) fprintf(stderr
, gettext(
361 "pr: Illegal character in -i option\n"));
365 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
367 if (isdigit(argv
[optnum
][argv_ind
])) {
368 Itabn
= (int)strtol(&argv
[optnum
]
369 [argv_ind
], (char **)NULL
, 10);
370 while (isdigit(argv
[optnum
][argv_ind
]))
371 SQUEEZE_ARG(argv
[optnum
],
382 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
383 if ((c
= argv
[optnum
][argv_ind
]) != '\0' &&
387 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
390 (void) fprintf(stderr
, gettext(
391 "pr: Illegal character in -n option\n"));
395 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
397 if (isdigit(argv
[optnum
][argv_ind
])) {
398 Numw
= (int)strtol(&argv
[optnum
]
399 [argv_ind
], (char **)NULL
, 10);
400 while (isdigit(argv
[optnum
][argv_ind
]))
401 SQUEEZE_ARG(argv
[optnum
],
410 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
411 if ((Sepc
= argv
[optnum
][argv_ind
]) == '\0')
416 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
419 (void) fprintf(stderr
, gettext(
420 "pr: Illegal character in -s option\n"));
424 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
433 if (argv
[optnum
][0] == '-' && argv
[optnum
][1] == '\0') {
434 REMOVE_ARG(argc
, &argv
[optnum
]);
439 /* Now get the other options */
440 while ((c
= getopt(argc
, argv
, "0123456789adfFh:l:mo:prtw:"))
477 if (strlen(optarg
) != strspn(optarg
, "0123456789"))
479 Length
= (int)strtol(optarg
, (char **)NULL
, 10);
488 if (strlen(optarg
) != strspn(optarg
, "0123456789"))
490 Offset
= (int)strtol(optarg
, (char **)NULL
, 10);
506 if (strlen(optarg
) != strspn(optarg
, "0123456789"))
508 Linew
= (int)strtol(optarg
, (char **)NULL
, 10);
528 /* Count the file names and strip options */
529 for (i
= 1; i
< argc
; i
++) {
530 /* Check for explicit stdin */
531 if ((argv
[i
][0] == '-') && (argv
[i
][1] == '\0')) {
532 argv
[eargc
++][0] = '\0';
533 REMOVE_ARG(argc
, &argv
[i
]);
538 for (i
= eargc
; optind
< argc
; i
++, optind
++) {
539 argv
[i
] = argv
[optind
];
547 if (mflg
&& (Ncols
> 1)) {
548 (void) fprintf(stderr
,
549 gettext("pr: only one of either -m or -column allowed\n"));
553 if (Ncols
== 1 && fold
)
559 if (Length
<= Margin
)
562 Plength
= Length
- Margin
/2;
576 if (Etabn
== 0) /* respect explicit tab specification */
582 if ((Fcol
= (foldinf
*) malloc(sizeof (foldinf
) * Ncols
)) == NULL
) {
583 (void) fprintf(stderr
, gettext("pr: malloc failed\n"));
586 for (i
= 0; i
< Ncols
; i
++)
587 Fcol
[i
].fold
= Fcol
[i
].skip
= 0;
590 Linew
= Ncols
!= 1 && Sepc
== 0 ? LINEW
: 512;
597 numw
= Numw
+ DEFTAB
- (Numw
% DEFTAB
);
599 numw
= Numw
+ Itabn
- (Numw
% Itabn
);
601 numw
= Numw
+ ((iswprint(Nsepc
)) ? 1 : 0);
603 Linew
-= (Multi
== 'm') ? numw
: numw
* Ncols
;
606 if ((Colw
= (Linew
- Ncols
+ 1)/Ncols
) < 1)
607 die("width too small");
609 if (Ncols
!= 1 && Multi
== 0) {
610 /* Buflen should take the number of wide characters */
611 /* Not the size for Buffer */
612 Buflen
= ((UNS
) (Plength
/ Dblspace
+ 1)) *
614 /* Should allocate Buflen * sizeof (wchar_t) */
615 Buffer
= (wchar_t *)getspace(Buflen
* sizeof (wchar_t));
616 Bufptr
= Bufend
= &Buffer
[Buflen
];
617 Colpts
= (COLP
) getspace((UNS
) ((Ncols
+ 1) *
622 /* is stdin not a tty? */
623 if (Ttyout
&& (Pause
|| Formfeed
) && !ttyname(fileno(stdin
)))
624 Ttyin
= fopen("/dev/tty", "r");
633 static int notfirst
= 0;
638 if (Multi
!= 'm' && mustopen(name
, &Files
[0]) == NULL
)
640 if (Multi
== 'm' && Nfiles
== 0 && mustopen(name
, &Files
[0]) == NULL
)
641 die("cannot open stdin");
643 (void) ungetwc(Files
->f_nextc
, Files
->f_f
);
646 for (Page
= 0; ; putpage()) {
647 if (C
== WEOF
&& !(fold
&& Buffer
))
654 (void) fflush(stdout
);
655 if (++Page
>= Fpage
) {
656 /* Pause if -p and not first page */
657 if (Ttyout
&& Pause
&& !notfirst
++) {
658 PROMPT(); /* prompt with bell and pause */
659 while ((c
= getc(Ttyin
)) != EOF
&& c
!= '\n')
667 head
= Head
!= NULL
? Head
:
668 Nfiles
< 2 ? Files
->f_name
: nulls
;
669 (void) printf("\n\n");
689 for (Line
= Margin
/ 2; ; (void) get(0)) {
690 for (Nspace
= Offset
, colno
= 0, Outpos
= 0; C
!= '\f'; ) {
691 if (Lnumb
&& (C
!= WEOF
) &&
692 (((colno
== 0) && (Multi
== 'm')) ||
696 (void) printf("%*ld%wc", Numw
, Buffer
?
697 Colpts
[colno
].c_lno
++ :
700 /* Move Outpos for number field */
704 DEFTAB
- (Outpos
% DEFTAB
);
710 for (Lcolpos
= 0, Pcolpos
= 0;
711 C
!= '\n' && C
!= '\f' && C
!= WEOF
;
715 if ((C
== WEOF
) || (++colno
== Ncols
) ||
716 ((C
== '\n') && (get(colno
) == WEOF
)))
721 else if ((Nspace
+= Colw
- Lcolpos
+ 1) < 1)
735 if (Dblspace
== 2 && Line
< Plength
)
743 while (Line
< Length
)
757 for (Line
= Margin
/ 2; ; (void) get(0)) {
758 for (Nspace
= Offset
, colno
= 0, Outpos
= 0; C
!= '\f'; ) {
759 if (Lnumb
&& Multi
== 'm' && foldcol
) {
760 if (!Fcol
[colno
].skip
) {
764 for (i
= 0; i
<= Numw
; i
++)
766 (void) printf("%wc", Nsepc
);
768 for (i
= 0; i
<= Colw
; i
++)
771 if (++colno
== Ncols
)
779 if (Lnumb
&& (C
!= WEOF
) &&
780 ((colno
== 0 && Multi
== 'm') || (Multi
!= 'm'))) {
784 Fcol
[colno
].skip
&& Multi
!= 'a') ||
785 (Fcol
[0].fold
&& Multi
== 'a') ||
786 (Buffer
&& Colpts
[colno
].c_skip
)) {
787 for (i
= 0; i
< Numw
; i
++)
789 (void) printf("%wc", Nsepc
);
791 Colpts
[colno
].c_lno
++;
792 Colpts
[colno
].c_skip
=
797 (void) printf("%*ld%wc", Numw
, Buffer
?
798 Colpts
[colno
].c_lno
++ :
804 for (Lcolpos
= 0, Pcolpos
= 0;
805 C
!= '\n' && C
!= '\f' && C
!= WEOF
;
809 Fcol
[(Multi
== 'a') ? 0 : colno
].fold
812 } else if (Multi
== 'a') {
819 for (i
= 0; i
< Ncols
; i
++)
822 if (alleof
|| ++colno
== Ncols
)
824 } else if (C
== EOF
|| ++colno
== Ncols
)
828 if (keep
== '\n' && C
== WEOF
)
832 else if ((Nspace
+= Colw
- pLcolpos
+ 1) < 1)
836 if (Lnumb
&& Multi
!= 'a') {
837 for (i
= 0; i
< Ncols
; i
++) {
838 Fcol
[i
].skip
= Fcol
[i
].fold
;
839 foldcol
+= Fcol
[i
].fold
;
853 (void) fflush(stdout
);
854 if (Dblspace
== 2 && Line
< Plength
)
861 else while (Line
< Length
)
881 p
->c_ptr0
= p
->c_ptr
= s
;
882 if (p
== &Colpts
[Ncols
])
884 (p
++)->c_lno
= Lnumb
+ bline
;
885 for (j
= (Length
- Margin
)/Dblspace
; --j
>= 0; ++bline
) {
886 for (Inpos
= 0; ; ) {
888 wc
= _fgetwc_pr(Files
->f_f
, &c
);
890 /* If there is an illegal character, */
891 /* handle it as a byte sequence. */
892 if (errno
== EILSEQ
) {
893 if (Inpos
< Colw
- 1) {
896 die("page-buffer overflow");
903 for (*s
= WEOF
; p
<= &Colpts
[Ncols
]; ++p
)
904 p
->c_ptr0
= p
->c_ptr
= s
;
913 } else if (iswprint(wc
)) {
914 Inpos
+= wcwidth(wc
);
917 if (Inpos
<= Colw
|| wc
== '\n') {
920 die("page-buffer overflow");
952 for (i
= 0; i
< Ncols
; i
++)
955 if (Bufptr
!= Bufend
) {
959 size
-= (Bufend
- Bufptr
);
962 p
->c_ptr0
= p
->c_ptr
= Buffer
;
967 p
->c_lno
= Colpts
[Ncols
-1].c_lno
;
968 p
->c_skip
= Colpts
[Ncols
].c_skip
;
972 if ((num
= freadw(d
, size
, Files
->f_f
)) != size
) {
973 for (*(d
+num
) = WEOF
; (++p
) <= &Colpts
[Ncols
]; ) {
974 p
->c_ptr0
= p
->c_ptr
= (d
+num
);
979 i
= (Length
- Margin
) / Dblspace
;
981 (void) readbuf(&Bufptr
, i
, p
++);
982 } while (++colno
< Ncols
);
987 balance(int bline
) /* line balancing for last page */
999 l
= (bline
+ Ncols
- 1)/Ncols
;
1002 for (j
= 0; j
< l
; ++j
)
1003 while (*s
++ != '\n')
1005 (++p
)->c_lno
= Lnumb
+ (bline
+= l
);
1006 p
->c_ptr0
= p
->c_ptr
= s
;
1009 } while (colno
< Ncols
- 1);
1011 lines
= readbuf(&s
, 0, 0);
1012 l
= (lines
+ Ncols
- 1)/Ncols
;
1013 if (l
> ((Length
- Margin
) / Dblspace
)) {
1014 l
= (Length
- Margin
) / Dblspace
;
1021 (void) readbuf(&s
, l
, p
++);
1024 } while (colno
< Ncols
);
1031 readbuf(wchar_t **s
, int lincol
, COLP p
)
1041 width
= (Ncols
== 1) ? Linew
: Colw
;
1042 while (**s
!= WEOF
) {
1045 lines
++; nls
++; chars
= 0; skip
= 0;
1054 move
= Itabn
- ((chars
+ Itabn
) % Itabn
);
1055 move
= (move
< width
-chars
) ? move
:
1063 } else if (iswprint(**s
)) {
1064 chars
+= wcwidth(**s
);
1067 if (chars
> width
) {
1073 if (lincol
&& lines
== lincol
) {
1074 (p
+1)->c_lno
= p
->c_lno
+ nls
;
1075 (++p
)->c_skip
= skip
;
1076 if (**s
== '\n') (*s
)++;
1077 p
->c_ptr0
= p
->c_ptr
= (wchar_t *)*s
;
1092 static int peekc
= 0;
1101 } else if (Buffer
) {
1103 if (p
->c_ptr
>= (p
+1)->c_ptr0
)
1105 else if ((wc
= *p
->c_ptr
) != WEOF
)
1107 if (fold
&& wc
== WEOF
)
1108 Fcol
[colno
].eof
= 1;
1110 (q
= &Files
[Multi
== 'a' ? 0 : colno
])->f_nextc
) == WEOF
) {
1111 for (q
= &Files
[Nfiles
]; --q
>= Files
&& q
->f_nextc
== WEOF
; )
1117 w
= _fgetwc_pr(q
->f_f
, &c
);
1118 if (w
== WEOF
&& errno
== EILSEQ
) {
1119 q
->f_nextc
= (wchar_t)c
;
1125 if (Etabn
!= 0 && wc
== Etabc
) {
1140 } else if (iswprint(wc
)) {
1141 Inpos
+= wcwidth(wc
);
1172 if (fold
&& Ncols
== 1)
1177 /* If column not full or this is separator char */
1178 if ((!fold
&& Ncols
< 2) || (Lcolpos
< width
) ||
1179 ((Sepc
== wc
) && (Lcolpos
== width
))) {
1183 if (fold
&& sp
== Lcolpos
)
1184 if (Lcolpos
>= width
)
1193 /* If column not full or this is separator char */
1194 if ((Lcolpos
< width
) ||
1195 ((Sepc
== wc
) && (Lcolpos
== width
))) {
1196 move
= Itabn
- ((Lcolpos
+ Itabn
) % Itabn
);
1197 move
= (move
< width
-Lcolpos
) ? move
: width
-Lcolpos
;
1201 if (fold
&& sp
== Lcolpos
)
1202 if (Lcolpos
>= width
)
1214 if (Lcolpos
> Pcolpos
) {
1243 } else if (iswprint(wc
)) {
1252 if (Lcolpos
> 0 || move
> 0)
1257 /* If column not full or this is separator char */
1258 if ((!fold
&& Ncols
< 2) || (Lcolpos
<= width
) ||
1259 ((Sepc
== wc
) && (Lcolpos
> width
))) {
1260 (void) fputwc(wc
, stdout
);
1265 if (fold
&& Lcolpos
> width
)
1277 for (; Nspace
> 0; Outpos
+= nc
, Nspace
-= nc
) {
1279 /* XPG4: -i: replace multiple SPACE chars with tab chars */
1280 if ((Nspace
>= 2 && Itabn
> 0 &&
1281 Nspace
>= (nc
= Itabn
- Outpos
% Itabn
)) && !fold
) {
1283 /* Solaris: -i: replace white space with tab chars */
1284 if ((Itabn
> 0 && Nspace
>= (nc
= Itabn
- Outpos
% Itabn
)) &&
1287 (void) fputwc(Itabc
, stdout
);
1290 (void) putchar(' ');
1300 if (*(Colpts
[colno
].c_ptr
-1) != '\t')
1301 --(Colpts
[colno
].c_ptr
);
1302 if (Colpts
[colno
].c_lno
)
1303 Colpts
[colno
].c_lno
--;
1305 if ((Multi
== 'm' && colno
== 0) || Multi
!= 'm')
1306 if (Lnumb
&& !foldcol
)
1308 colno
= (Multi
== 'a') ? 0 : colno
;
1309 (void) ungetwc(Files
[colno
].f_nextc
, Files
[colno
].f_f
);
1310 Files
[colno
].f_nextc
= C
;
1316 * Defer message about failure to open file to prevent messing up
1317 * alignment of page with tear perforations or form markers.
1318 * Treat empty file as special case and report as diagnostic.
1322 mustopen(char *s
, FILS
*f
)
1324 char *empty_file_msg
= gettext("%s -- empty file");
1328 f
->f_name
= STDINNAME();
1330 } else if ((f
->f_f
= fopen(f
->f_name
= s
, "r")) == NULL
) {
1331 s
= ffiler(f
->f_name
);
1332 s
= strcpy((char *)getspace((UNS
) strlen(s
) + 1), s
);
1334 if (f
->f_f
!= NULL
) {
1336 f
->f_nextc
= _fgetwc_pr(f
->f_f
, &c
);
1337 if (f
->f_nextc
!= WEOF
) {
1340 if (errno
== EILSEQ
) {
1341 f
->f_nextc
= (wchar_t)c
;
1347 (void) sprintf(s
= (char *)getspace((UNS
) strlen(f
->f_name
)
1348 + 1 + (UNS
) strlen(empty_file_msg
)),
1349 empty_file_msg
, f
->f_name
);
1350 (void) fclose(f
->f_f
);
1354 if (Ttyout
) { /* accumulate error reports */
1355 Lasterr
= Lasterr
->e_nextp
=
1356 (ERR
*) getspace((UNS
) sizeof (ERR
));
1357 Lasterr
->e_nextp
= NULL
;
1358 Lasterr
->e_mess
= s
;
1359 } else { /* ok to print error report now */
1361 (void) putc('\n', stderr
);
1372 if ((t
= (ANY
*) malloc(n
)) == NULL
)
1373 die("out of space");
1384 (void) putc('\n', stderr
);
1392 errprint() /* print accumulated error reports */
1394 (void) fflush(stdout
);
1395 for (; Err
!= NULL
; Err
= Err
->e_nextp
) {
1396 cerror(Err
->e_mess
);
1397 (void) putc('\n', stderr
);
1408 setbuf(stdout
, obuf
);
1409 if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
1410 (void) signal(SIGINT
, onintr
);
1411 if (Ttyout
= ttyname(fileno(stdout
))) { /* is stdout a tty? */
1412 (void) stat(Ttyout
, &sbuf
);
1413 Mode
= sbuf
.st_mode
; /* save permissions */
1414 (void) chmod(Ttyout
, (S_IREAD
|S_IWRITE
));
1429 GETDATE() /* return date file was last modified */
1431 static char *now
= NULL
;
1432 static struct stat sbuf
;
1433 static struct stat nbuf
;
1435 if (Nfiles
> 1 || Files
->f_name
== nulls
) {
1437 (void) time(&nbuf
.st_mtime
);
1438 (void) cftime(time_buf
,
1439 dcgettext(NULL
, FORMAT
, LC_TIME
),
1445 (void) stat(Files
->f_name
, &sbuf
);
1446 (void) cftime(time_buf
, dcgettext(NULL
, FORMAT
, LC_TIME
),
1456 static char buf
[100];
1458 (void) sprintf(buf
, gettext("can't open %s"), s
);
1466 (void) fprintf(stderr
, gettext(
1467 "usage: pr [-# [-w #] [-a]] [-e[c][#]] [-i[c][#]] [-drtfp] [-n[c][#]] \\\n"
1468 " [-o #] [-l #] [-s[char]] [-h header] [-F] [+#] [file ...]\n\n"
1469 " pr [-m [-w #]] [-e[c][#]] [-i[c][#]] [-drtfp] [-n[c][#]] [-0 #] \\\n"
1470 " [-l #] [-s[char]] [-h header] [-F] [+#] file1 file2 ...\n"
1476 _fgetwc_pr(FILE *f
, int *ic
)
1480 char mbuf
[MB_LEN_MAX
];
1488 if (mbcurmax
== 1 || isascii(c
)) {
1492 for (i
= 1; i
< mbcurmax
; i
++) {
1502 len
= mbtowc(&wc
, mbuf
, i
);
1504 /* Illegal character */
1505 /* Set the first byte to *ic */
1507 /* Push back remaining characters */
1508 for (i
--; i
> 0; i
--) {
1509 (void) ungetc(mbuf
[i
], f
);
1514 /* Push back over-read characters */
1515 for (i
--; i
>= len
; i
--) {
1516 (void) ungetc(mbuf
[i
], f
);
1518 return ((wint_t)wc
);
1523 freadw(wchar_t *ptr
, size_t nitems
, FILE *f
)
1537 for (i
= 0; i
< nitems
; i
++) {
1539 wc
= _fgetwc_pr(f
, &c
);
1541 if (errno
== EILSEQ
) {