4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * col - filter reverse carraige motions
52 wchar_t lbuff
[LINELN
], *line
;
53 wchar_t *lbuffend
= lbuff
+ LINELN
- 1;
54 wchar_t ws_blank
[2] = {' ', 0};
55 char esc_chars
, underline
, temp_off
, smart
;
56 int bflag
, xflag
, fflag
, pflag
;
64 #define USAGEMSG "usage:\tcol [-bfxp]\n"
66 static void outc(wchar_t);
67 static void store(int);
68 static void fetch(int);
69 static void emit(wchar_t *, int);
70 static void incr(void);
71 static void decr(void);
72 static void wsinsert(wchar_t *, int);
73 static void incr_line(int);
74 static int wcscrwidth(wchar_t);
77 main(int argc
, char **argv
)
85 static char fbuff
[BUFSIZ
];
87 setbuf(stdout
, fbuff
);
88 (void) setlocale(LC_ALL
, "");
89 #if !defined(TEXT_DOMAIN)
90 #define TEXT_DOMAIN "SYS_TEST"
92 (void) textdomain(TEXT_DOMAIN
);
95 while ((opt
= getopt(argc
, argv
, "bfxp")) != EOF
)
111 (void) fprintf(stderr
, gettext(USAGEMSG
));
117 (void) fprintf(stderr
, gettext(USAGEMSG
));
121 for (ll
= 0; ll
< PL
; ll
++)
124 smart
= temp_off
= underline
= esc_chars
= '\0';
131 while ((c
= getwchar()) != EOF
) {
132 if (underline
&& temp_off
&& c
> ' ') {
139 *line
= temp_off
= '\0';
146 if (underline
&& !temp_off
) {
167 case '7': /* reverse full line feed */
172 case '8': /* reverse half line feed */
184 case '9': /* forward half line feed */
197 if (pflag
) { /* pass through esc */
206 if (c
== 'Y' && underline
)
207 underline
= temp_off
= '\0';
253 if (iswprint(c
)) { /* if printable */
259 * EUC (apply SO only when there can
260 * be corresponding character in CS1)
262 else if (iswascii(c
)) {
264 n
= mbtowc(&wc
, &byte
, 1);
265 if (!iswcntrl(c
) && !iswspace(c
) &&
268 cp
+= wcscrwidth(wc
);
278 if ((cp
+ 1) > LINELN
) {
279 (void) fprintf(stderr
,
280 gettext("col: Line too long\n"));
288 for (i
= 0; i
< PL
; i
++)
289 if (page
[(mustwr
+i
)%PL
] != 0)
290 emit(page
[(mustwr
+i
) % PL
], mustwr
+i
-PL
);
291 emit(ws_blank
, (llh
+ 1) & -2);
299 int width
, widthl
, widthc
;
302 char esc_chars
= '\0';
322 /* if ( ! esc_chars ) */
326 lp
+= wcscrwidth(*line
);
330 while (*line
== '\b') {
332 * EUC (For a multi-column character, backspace characters
333 * are assumed to be used like "__^H^HXX", where "XX"
334 * represents a two-column character, and a backspace
335 * always goes back by one column.)
337 for (n
= 0; *line
== '\b'; incr_line(1)) {
341 while (n
> 0 && lp
< cp
) {
351 widthc
= wcscrwidth(c
);
352 widthl
= wcscrwidth(*line
);
353 if (bflag
|| (*line
== '\0') || *line
== ' ') {
354 if (*line
== '\0' || widthl
== widthc
) {
356 } else if (widthl
> widthc
) {
361 for (i
= 0; i
< n
; i
++) {
369 if (line
< lbuffend
) {
370 for (p1
= line
+1; n
> 0 && p1
< lbuffend
;
371 n
-= wcscrwidth(i
)) {
376 (void) wcscpy(line
+1, p1
);
378 (void) fprintf(stderr
,
379 gettext("col: Line too long.\n"));
383 (void) fprintf(stderr
,
384 gettext("col: Line too long.\n"));
389 if (smart
&& (widthl
== 1) && (widthc
== 1)) {
390 wchar_t c1
, c2
, c3
, c4
, c5
, c6
, c7
;
422 if ((widthl
== 1) && (widthc
== 1)) {
439 width
= (widthc
> widthl
) ? widthc
: widthl
;
440 for (i
= 0; i
< width
; i
+= wcscrwidth(c1
)) {
444 wsinsert(line
, width
+ (width
- widthc
+ 1));
445 for (i
= 0; i
< width
; i
++) {
451 for (i
= widthc
; i
< width
; i
++) {
467 free((char *)page
[lno
]);
468 page
[lno
] = (wchar_t *)malloc((unsigned)(wcslen(lbuff
) + 2)
470 if (page
[lno
] == 0) {
471 /* fprintf(stderr, "%s: no storage\n", pgmname); */
474 (void) wcscpy(page
[lno
], lbuff
);
489 (void) wcscpy(line
, page
[lno
]);
493 emit(wchar_t *s
, int lineno
)
495 static int cline
= 0;
499 char chr
[MB_LEN_MAX
+ 1];
502 static int gflag
= 0;
509 while (cline
< lineno
- 1) {
510 (void) putchar('\n');
514 if (cline
!= lineno
) {
520 (void) putchar('\r');
525 while (*p
++ == ' ') {
526 if ((++ncp
& 7) == 0 && !xflag
) {
528 (void) putchar('\t');
538 if (wctomb(chr
, *p
) == 1) {
539 if (gflag
!= (*chr
& GREEK
) &&
541 isascii(*chr
^ (gflag
^ GREEK
)) &&
542 !iscntrl(*chr
^ (gflag
^ GREEK
)) &&
543 !isspace(*chr
^ (gflag
^ GREEK
))) {
554 if (wctomb(chr
, (wchar_t)c
) == 1) {
555 cshifted
= (*chr
^ GREEK
);
556 if (isascii(cshifted
) &&
557 !iscntrl(cshifted
) &&
559 (void) putchar(*chr
& ~GREEK
);
565 if (*(p
-2) && *(p
-2) == ESC
) {
570 pcp
+= wcscrwidth(c
);
583 if (ll
>= mustwr
&& page
[ll
%PL
]) {
584 emit(page
[ll
%PL
], ll
- PL
);
586 free((char *)page
[ll
%PL
]);
595 if (ll
> mustwr
- PL
) {
602 wsinsert(wchar_t *s
, int n
)
614 * incr_line - increments line pointer and checks for array out of bounds
615 * amt: assumed to be >= 1
616 * exit on error to avoid line pointer accessing out of the array
621 if (line
< lbuffend
- amt
+ 1) {
624 (void) fprintf(stderr
, gettext("col: Line too long.\n"));
631 wcscrwidth(wchar_t wc
)
637 * if wc is a null character, needs to
638 * return 1 instead of 0.