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;
125 static FILE *Ttyin
= stdin
;
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
)
200 /* Get locale variables for environment */
201 (void) setlocale(LC_ALL
, "");
203 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
204 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
206 (void) textdomain(TEXT_DOMAIN
);
208 mbcurmax
= MB_CUR_MAX
;
210 for (argc
= findopt(argc
, argv
); argc
> 0; --argc
, ++argv
) {
212 if (Nfiles
>= NFILES
- 1) die("too many files");
213 if (mustopen(*argv
, &Files
[Nfiles
++]) == NULL
)
214 ++nfdone
; /* suppress printing */
217 (void) fclose(Files
->f_f
);
221 if (!nfdone
) /* no files named, use stdin */
222 (void) print(NOFILE
); /* on GCOS, use current file, if any */
225 errprint(); /* print accumulated error reports */
234 * findopt() returns argc modified to be the number of explicitly supplied
235 * filenames, including '-', the explicit request to use stdin.
236 * argc == 0 implies that no filenames were supplied and stdin should be used.
237 * Options are striped from argv and only file names are returned.
241 findopt(int argc
, char **argv
)
255 /* Handle page number option */
256 for (optnum
= 1, end_opt
= 0; optnum
< argc
&& !end_opt
; optnum
++) {
257 switch (*argv
[optnum
]) {
259 /* check for all digits */
260 if (strlen(&argv
[optnum
][1]) !=
261 strspn(&argv
[optnum
][1], "0123456789")) {
262 (void) fprintf(stderr
, gettext(
263 "pr: Badly formed number\n"));
267 if ((Fpage
= (int)strtol(&argv
[optnum
][1],
268 (char **)NULL
, 10)) < 0) {
269 (void) fprintf(stderr
, gettext(
270 "pr: Badly formed number\n"));
273 REMOVE_ARG(argc
, &argv
[optnum
]);
278 /* Check for end of options */
279 if (argv
[optnum
][1] == '-') {
284 if (argv
[optnum
][1] == 'h' || argv
[optnum
][1] == 'l' ||
285 argv
[optnum
][1] == 'o' || argv
[optnum
][1] == 'w')
302 * Handle options with optional arguments.
303 * If optional arguments are present they may not be separated
304 * from the option letter.
307 for (optnum
= 1; optnum
< argc
; optnum
++) {
308 if (argv
[optnum
][0] == '-' && argv
[optnum
][1] == '-')
312 if (argv
[optnum
][0] == '-' && argv
[optnum
][1] == '\0')
313 /* stdin file name */
316 if (argv
[optnum
][0] != '-')
320 for (argv_ind
= 1; argv
[optnum
][argv_ind
] != '\0'; argv_ind
++) {
321 switch (argv
[optnum
][argv_ind
]) {
323 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
324 if ((c
= argv
[optnum
][argv_ind
]) != '\0' &&
328 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
331 (void) fprintf(stderr
, gettext(
332 "pr: Illegal character in -e option\n"));
336 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
338 if (isdigit(argv
[optnum
][argv_ind
])) {
339 Etabn
= (int)strtol(&argv
[optnum
]
340 [argv_ind
], (char **)NULL
, 10);
341 while (isdigit(argv
[optnum
][argv_ind
]))
342 SQUEEZE_ARG(argv
[optnum
],
351 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
352 if ((c
= argv
[optnum
][argv_ind
]) != '\0' &&
356 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
359 (void) fprintf(stderr
, gettext(
360 "pr: Illegal character in -i option\n"));
364 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
366 if (isdigit(argv
[optnum
][argv_ind
])) {
367 Itabn
= (int)strtol(&argv
[optnum
]
368 [argv_ind
], (char **)NULL
, 10);
369 while (isdigit(argv
[optnum
][argv_ind
]))
370 SQUEEZE_ARG(argv
[optnum
],
381 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
382 if ((c
= argv
[optnum
][argv_ind
]) != '\0' &&
386 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
389 (void) fprintf(stderr
, gettext(
390 "pr: Illegal character in -n option\n"));
394 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
396 if (isdigit(argv
[optnum
][argv_ind
])) {
397 Numw
= (int)strtol(&argv
[optnum
]
398 [argv_ind
], (char **)NULL
, 10);
399 while (isdigit(argv
[optnum
][argv_ind
]))
400 SQUEEZE_ARG(argv
[optnum
],
409 SQUEEZE_ARG(argv
[optnum
], argv_ind
, 1);
410 if ((Sepc
= argv
[optnum
][argv_ind
]) == '\0')
415 r
= mbtowc(&wc
, &argv
[optnum
][argv_ind
],
418 (void) fprintf(stderr
, gettext(
419 "pr: Illegal character in -s option\n"));
423 SQUEEZE_ARG(argv
[optnum
], argv_ind
, r
);
432 if (argv
[optnum
][0] == '-' && argv
[optnum
][1] == '\0') {
433 REMOVE_ARG(argc
, &argv
[optnum
]);
438 /* Now get the other options */
439 while ((c
= getopt(argc
, argv
, "0123456789adfFh:l:mo:prtw:"))
476 if (strlen(optarg
) != strspn(optarg
, "0123456789"))
478 Length
= (int)strtol(optarg
, (char **)NULL
, 10);
487 if (strlen(optarg
) != strspn(optarg
, "0123456789"))
489 Offset
= (int)strtol(optarg
, (char **)NULL
, 10);
505 if (strlen(optarg
) != strspn(optarg
, "0123456789"))
507 Linew
= (int)strtol(optarg
, (char **)NULL
, 10);
527 /* Count the file names and strip options */
528 for (i
= 1; i
< argc
; i
++) {
529 /* Check for explicit stdin */
530 if ((argv
[i
][0] == '-') && (argv
[i
][1] == '\0')) {
531 argv
[eargc
++][0] = '\0';
532 REMOVE_ARG(argc
, &argv
[i
]);
537 for (i
= eargc
; optind
< argc
; i
++, optind
++) {
538 argv
[i
] = argv
[optind
];
546 if (mflg
&& (Ncols
> 1)) {
547 (void) fprintf(stderr
,
548 gettext("pr: only one of either -m or -column allowed\n"));
552 if (Ncols
== 1 && fold
)
558 if (Length
<= Margin
)
561 Plength
= Length
- Margin
/2;
575 if (Etabn
== 0) /* respect explicit tab specification */
581 if ((Fcol
= (foldinf
*) malloc(sizeof (foldinf
) * Ncols
)) == NULL
) {
582 (void) fprintf(stderr
, gettext("pr: malloc failed\n"));
585 for (i
= 0; i
< Ncols
; i
++)
586 Fcol
[i
].fold
= Fcol
[i
].skip
= 0;
589 Linew
= Ncols
!= 1 && Sepc
== 0 ? LINEW
: 512;
596 numw
= Numw
+ DEFTAB
- (Numw
% DEFTAB
);
598 numw
= Numw
+ Itabn
- (Numw
% Itabn
);
600 numw
= Numw
+ ((iswprint(Nsepc
)) ? 1 : 0);
602 Linew
-= (Multi
== 'm') ? numw
: numw
* Ncols
;
605 if ((Colw
= (Linew
- Ncols
+ 1)/Ncols
) < 1)
606 die("width too small");
608 if (Ncols
!= 1 && Multi
== 0) {
609 /* Buflen should take the number of wide characters */
610 /* Not the size for Buffer */
611 Buflen
= ((UNS
) (Plength
/ Dblspace
+ 1)) *
613 /* Should allocate Buflen * sizeof (wchar_t) */
614 Buffer
= (wchar_t *)getspace(Buflen
* sizeof (wchar_t));
615 Bufptr
= Bufend
= &Buffer
[Buflen
];
616 Colpts
= (COLP
) getspace((UNS
) ((Ncols
+ 1) *
621 /* is stdin not a tty? */
622 if (Ttyout
&& (Pause
|| Formfeed
) && !ttyname(fileno(stdin
)))
623 Ttyin
= fopen("/dev/tty", "r");
632 static int notfirst
= 0;
637 if (Multi
!= 'm' && mustopen(name
, &Files
[0]) == NULL
)
639 if (Multi
== 'm' && Nfiles
== 0 && mustopen(name
, &Files
[0]) == NULL
)
640 die("cannot open stdin");
642 (void) ungetwc(Files
->f_nextc
, Files
->f_f
);
645 for (Page
= 0; ; putpage()) {
646 if (C
== WEOF
&& !(fold
&& Buffer
))
653 (void) fflush(stdout
);
654 if (++Page
>= Fpage
) {
655 /* Pause if -p and not first page */
656 if (Ttyout
&& Pause
&& !notfirst
++) {
657 PROMPT(); /* prompt with bell and pause */
658 while ((c
= getc(Ttyin
)) != EOF
&& c
!= '\n')
666 head
= Head
!= NULL
? Head
:
667 Nfiles
< 2 ? Files
->f_name
: nulls
;
668 (void) printf("\n\n");
688 for (Line
= Margin
/ 2; ; (void) get(0)) {
689 for (Nspace
= Offset
, colno
= 0, Outpos
= 0; C
!= '\f'; ) {
690 if (Lnumb
&& (C
!= WEOF
) &&
691 (((colno
== 0) && (Multi
== 'm')) ||
695 (void) printf("%*ld%wc", Numw
, Buffer
?
696 Colpts
[colno
].c_lno
++ :
699 /* Move Outpos for number field */
703 DEFTAB
- (Outpos
% DEFTAB
);
709 for (Lcolpos
= 0, Pcolpos
= 0;
710 C
!= '\n' && C
!= '\f' && C
!= WEOF
;
714 if ((C
== WEOF
) || (++colno
== Ncols
) ||
715 ((C
== '\n') && (get(colno
) == WEOF
)))
720 else if ((Nspace
+= Colw
- Lcolpos
+ 1) < 1)
734 if (Dblspace
== 2 && Line
< Plength
)
742 while (Line
< Length
)
756 for (Line
= Margin
/ 2; ; (void) get(0)) {
757 for (Nspace
= Offset
, colno
= 0, Outpos
= 0; C
!= '\f'; ) {
758 if (Lnumb
&& Multi
== 'm' && foldcol
) {
759 if (!Fcol
[colno
].skip
) {
763 for (i
= 0; i
<= Numw
; i
++)
765 (void) printf("%wc", Nsepc
);
767 for (i
= 0; i
<= Colw
; i
++)
770 if (++colno
== Ncols
)
778 if (Lnumb
&& (C
!= WEOF
) &&
779 ((colno
== 0 && Multi
== 'm') || (Multi
!= 'm'))) {
783 Fcol
[colno
].skip
&& Multi
!= 'a') ||
784 (Fcol
[0].fold
&& Multi
== 'a') ||
785 (Buffer
&& Colpts
[colno
].c_skip
)) {
786 for (i
= 0; i
< Numw
; i
++)
788 (void) printf("%wc", Nsepc
);
790 Colpts
[colno
].c_lno
++;
791 Colpts
[colno
].c_skip
=
796 (void) printf("%*ld%wc", Numw
, Buffer
?
797 Colpts
[colno
].c_lno
++ :
803 for (Lcolpos
= 0, Pcolpos
= 0;
804 C
!= '\n' && C
!= '\f' && C
!= WEOF
;
808 Fcol
[(Multi
== 'a') ? 0 : colno
].fold
811 } else if (Multi
== 'a') {
818 for (i
= 0; i
< Ncols
; i
++)
821 if (alleof
|| ++colno
== Ncols
)
823 } else if (C
== EOF
|| ++colno
== Ncols
)
827 if (keep
== '\n' && C
== WEOF
)
831 else if ((Nspace
+= Colw
- pLcolpos
+ 1) < 1)
835 if (Lnumb
&& Multi
!= 'a') {
836 for (i
= 0; i
< Ncols
; i
++) {
837 Fcol
[i
].skip
= Fcol
[i
].fold
;
838 foldcol
+= Fcol
[i
].fold
;
852 (void) fflush(stdout
);
853 if (Dblspace
== 2 && Line
< Plength
)
860 else while (Line
< Length
)
880 p
->c_ptr0
= p
->c_ptr
= s
;
881 if (p
== &Colpts
[Ncols
])
883 (p
++)->c_lno
= Lnumb
+ bline
;
884 for (j
= (Length
- Margin
)/Dblspace
; --j
>= 0; ++bline
) {
885 for (Inpos
= 0; ; ) {
887 wc
= _fgetwc_pr(Files
->f_f
, &c
);
889 /* If there is an illegal character, */
890 /* handle it as a byte sequence. */
891 if (errno
== EILSEQ
) {
892 if (Inpos
< Colw
- 1) {
895 die("page-buffer overflow");
902 for (*s
= WEOF
; p
<= &Colpts
[Ncols
]; ++p
)
903 p
->c_ptr0
= p
->c_ptr
= s
;
912 } else if (iswprint(wc
)) {
913 Inpos
+= wcwidth(wc
);
916 if (Inpos
<= Colw
|| wc
== '\n') {
919 die("page-buffer overflow");
951 for (i
= 0; i
< Ncols
; i
++)
954 if (Bufptr
!= Bufend
) {
958 size
-= (Bufend
- Bufptr
);
961 p
->c_ptr0
= p
->c_ptr
= Buffer
;
966 p
->c_lno
= Colpts
[Ncols
-1].c_lno
;
967 p
->c_skip
= Colpts
[Ncols
].c_skip
;
971 if ((num
= freadw(d
, size
, Files
->f_f
)) != size
) {
972 for (*(d
+num
) = WEOF
; (++p
) <= &Colpts
[Ncols
]; ) {
973 p
->c_ptr0
= p
->c_ptr
= (d
+num
);
978 i
= (Length
- Margin
) / Dblspace
;
980 (void) readbuf(&Bufptr
, i
, p
++);
981 } while (++colno
< Ncols
);
986 balance(int bline
) /* line balancing for last page */
998 l
= (bline
+ Ncols
- 1)/Ncols
;
1001 for (j
= 0; j
< l
; ++j
)
1002 while (*s
++ != '\n')
1004 (++p
)->c_lno
= Lnumb
+ (bline
+= l
);
1005 p
->c_ptr0
= p
->c_ptr
= s
;
1008 } while (colno
< Ncols
- 1);
1010 lines
= readbuf(&s
, 0, 0);
1011 l
= (lines
+ Ncols
- 1)/Ncols
;
1012 if (l
> ((Length
- Margin
) / Dblspace
)) {
1013 l
= (Length
- Margin
) / Dblspace
;
1020 (void) readbuf(&s
, l
, p
++);
1023 } while (colno
< Ncols
);
1030 readbuf(wchar_t **s
, int lincol
, COLP p
)
1040 width
= (Ncols
== 1) ? Linew
: Colw
;
1041 while (**s
!= WEOF
) {
1044 lines
++; nls
++; chars
= 0; skip
= 0;
1053 move
= Itabn
- ((chars
+ Itabn
) % Itabn
);
1054 move
= (move
< width
-chars
) ? move
:
1062 } else if (iswprint(**s
)) {
1063 chars
+= wcwidth(**s
);
1066 if (chars
> width
) {
1072 if (lincol
&& lines
== lincol
) {
1073 (p
+1)->c_lno
= p
->c_lno
+ nls
;
1074 (++p
)->c_skip
= skip
;
1075 if (**s
== '\n') (*s
)++;
1076 p
->c_ptr0
= p
->c_ptr
= (wchar_t *)*s
;
1091 static int peekc
= 0;
1100 } else if (Buffer
) {
1102 if (p
->c_ptr
>= (p
+1)->c_ptr0
)
1104 else if ((wc
= *p
->c_ptr
) != WEOF
)
1106 if (fold
&& wc
== WEOF
)
1107 Fcol
[colno
].eof
= 1;
1109 (q
= &Files
[Multi
== 'a' ? 0 : colno
])->f_nextc
) == WEOF
) {
1110 for (q
= &Files
[Nfiles
]; --q
>= Files
&& q
->f_nextc
== WEOF
; )
1116 w
= _fgetwc_pr(q
->f_f
, &c
);
1117 if (w
== WEOF
&& errno
== EILSEQ
) {
1118 q
->f_nextc
= (wchar_t)c
;
1124 if (Etabn
!= 0 && wc
== Etabc
) {
1139 } else if (iswprint(wc
)) {
1140 Inpos
+= wcwidth(wc
);
1171 if (fold
&& Ncols
== 1)
1176 /* If column not full or this is separator char */
1177 if ((!fold
&& Ncols
< 2) || (Lcolpos
< width
) ||
1178 ((Sepc
== wc
) && (Lcolpos
== width
))) {
1182 if (fold
&& sp
== Lcolpos
)
1183 if (Lcolpos
>= width
)
1192 /* If column not full or this is separator char */
1193 if ((Lcolpos
< width
) ||
1194 ((Sepc
== wc
) && (Lcolpos
== width
))) {
1195 move
= Itabn
- ((Lcolpos
+ Itabn
) % Itabn
);
1196 move
= (move
< width
-Lcolpos
) ? move
: width
-Lcolpos
;
1200 if (fold
&& sp
== Lcolpos
)
1201 if (Lcolpos
>= width
)
1213 if (Lcolpos
> Pcolpos
) {
1242 } else if (iswprint(wc
)) {
1251 if (Lcolpos
> 0 || move
> 0)
1256 /* If column not full or this is separator char */
1257 if ((!fold
&& Ncols
< 2) || (Lcolpos
<= width
) ||
1258 ((Sepc
== wc
) && (Lcolpos
> width
))) {
1259 (void) fputwc(wc
, stdout
);
1264 if (fold
&& Lcolpos
> width
)
1276 for (; Nspace
> 0; Outpos
+= nc
, Nspace
-= nc
) {
1278 /* XPG4: -i: replace multiple SPACE chars with tab chars */
1279 if ((Nspace
>= 2 && Itabn
> 0 &&
1280 Nspace
>= (nc
= Itabn
- Outpos
% Itabn
)) && !fold
) {
1282 /* Solaris: -i: replace white space with tab chars */
1283 if ((Itabn
> 0 && Nspace
>= (nc
= Itabn
- Outpos
% Itabn
)) &&
1286 (void) fputwc(Itabc
, stdout
);
1289 (void) putchar(' ');
1299 if (*(Colpts
[colno
].c_ptr
-1) != '\t')
1300 --(Colpts
[colno
].c_ptr
);
1301 if (Colpts
[colno
].c_lno
)
1302 Colpts
[colno
].c_lno
--;
1304 if ((Multi
== 'm' && colno
== 0) || Multi
!= 'm')
1305 if (Lnumb
&& !foldcol
)
1307 colno
= (Multi
== 'a') ? 0 : colno
;
1308 (void) ungetwc(Files
[colno
].f_nextc
, Files
[colno
].f_f
);
1309 Files
[colno
].f_nextc
= C
;
1315 * Defer message about failure to open file to prevent messing up
1316 * alignment of page with tear perforations or form markers.
1317 * Treat empty file as special case and report as diagnostic.
1321 mustopen(char *s
, FILS
*f
)
1323 char *empty_file_msg
= gettext("%s -- empty file");
1327 f
->f_name
= STDINNAME();
1329 } else if ((f
->f_f
= fopen(f
->f_name
= s
, "r")) == NULL
) {
1330 s
= ffiler(f
->f_name
);
1331 s
= strcpy((char *)getspace((UNS
) strlen(s
) + 1), s
);
1333 if (f
->f_f
!= NULL
) {
1335 f
->f_nextc
= _fgetwc_pr(f
->f_f
, &c
);
1336 if (f
->f_nextc
!= WEOF
) {
1339 if (errno
== EILSEQ
) {
1340 f
->f_nextc
= (wchar_t)c
;
1346 (void) sprintf(s
= (char *)getspace((UNS
) strlen(f
->f_name
)
1347 + 1 + (UNS
) strlen(empty_file_msg
)),
1348 empty_file_msg
, f
->f_name
);
1349 (void) fclose(f
->f_f
);
1353 if (Ttyout
) { /* accumulate error reports */
1354 Lasterr
= Lasterr
->e_nextp
=
1355 (ERR
*) getspace((UNS
) sizeof (ERR
));
1356 Lasterr
->e_nextp
= NULL
;
1357 Lasterr
->e_mess
= s
;
1358 } else { /* ok to print error report now */
1360 (void) putc('\n', stderr
);
1362 return ((FILE *)NULL
);
1371 if ((t
= (ANY
*) malloc(n
)) == NULL
)
1372 die("out of space");
1383 (void) putc('\n', stderr
);
1391 errprint() /* print accumulated error reports */
1393 (void) fflush(stdout
);
1394 for (; Err
!= NULL
; Err
= Err
->e_nextp
) {
1395 cerror(Err
->e_mess
);
1396 (void) putc('\n', stderr
);
1407 setbuf(stdout
, obuf
);
1408 if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
1409 (void) signal(SIGINT
, onintr
);
1410 if (Ttyout
= ttyname(fileno(stdout
))) { /* is stdout a tty? */
1411 (void) stat(Ttyout
, &sbuf
);
1412 Mode
= sbuf
.st_mode
; /* save permissions */
1413 (void) chmod(Ttyout
, (S_IREAD
|S_IWRITE
));
1428 GETDATE() /* return date file was last modified */
1430 static char *now
= NULL
;
1431 static struct stat sbuf
;
1432 static struct stat nbuf
;
1434 if (Nfiles
> 1 || Files
->f_name
== nulls
) {
1436 (void) time(&nbuf
.st_mtime
);
1437 (void) cftime(time_buf
,
1438 dcgettext(NULL
, FORMAT
, LC_TIME
),
1444 (void) stat(Files
->f_name
, &sbuf
);
1445 (void) cftime(time_buf
, dcgettext(NULL
, FORMAT
, LC_TIME
),
1455 static char buf
[100];
1457 (void) sprintf(buf
, gettext("can't open %s"), s
);
1465 (void) fprintf(stderr
, gettext(
1466 "usage: pr [-# [-w #] [-a]] [-e[c][#]] [-i[c][#]] [-drtfp] [-n[c][#]] \\\n"
1467 " [-o #] [-l #] [-s[char]] [-h header] [-F] [+#] [file ...]\n\n"
1468 " pr [-m [-w #]] [-e[c][#]] [-i[c][#]] [-drtfp] [-n[c][#]] [-0 #] \\\n"
1469 " [-l #] [-s[char]] [-h header] [-F] [+#] file1 file2 ...\n"
1475 _fgetwc_pr(FILE *f
, int *ic
)
1479 char mbuf
[MB_LEN_MAX
];
1487 if (mbcurmax
== 1 || isascii(c
)) {
1491 for (i
= 1; i
< mbcurmax
; i
++) {
1501 len
= mbtowc(&wc
, mbuf
, i
);
1503 /* Illegal character */
1504 /* Set the first byte to *ic */
1506 /* Push back remaining characters */
1507 for (i
--; i
> 0; i
--) {
1508 (void) ungetc(mbuf
[i
], f
);
1513 /* Push back over-read characters */
1514 for (i
--; i
>= len
; i
--) {
1515 (void) ungetc(mbuf
[i
], f
);
1517 return ((wint_t)wc
);
1522 freadw(wchar_t *ptr
, size_t nitems
, FILE *f
)
1536 for (i
= 0; i
< nitems
; i
++) {
1538 wc
= _fgetwc_pr(f
, &c
);
1540 if (errno
== EILSEQ
) {