1 /*
2 * CDDL HEADER START
3 *
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
7 * with the License.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <limits.h>
34 #include <locale.h>
35 #include <wctype.h>
36 #include <getwidth.h>
37
38 #define SCRWID 80
39 #define LC_NAMELEN 255
40
41 #if !defined SS2
42 #define SS2 0x8e
43 #endif
44 #if !defined SS3
45 #define SS3 0x8f
46 #endif
47
48 static unsigned int cpl; /* current characters per line */
49 static unsigned int cplmax; /* maximum characters per line */
50 static unsigned char codestr[MB_LEN_MAX + 1];
51 static char linebuf[SCRWID / 2 * (MB_LEN_MAX + 1)];
52 static int pinline; /* any printable to be listed in the line? */
53 static int omitting; /* omitting blank lines under no vflag? */
54 static int vflag = 0;
55 static int wflag = 0;
56 static int csprint();
57 static int prcode();
58
59 int
main(ac,av)60 main(ac, av)
61 int ac;
62 char *av[];
63 {
64 int c;
65 short int eucw[4];
66 short int scrw[4];
67 int csflag[4];
68 int cs;
69 int i;
70 eucwidth_t eucwidth;
71 char *lc_ctype;
72 char titlebar[LC_NAMELEN + 14];
73
74 (void) setlocale(LC_ALL, "");
75 #if !defined(TEXT_DOMAIN)
76 #define TEXT_DOMAIN "SYS_TEST"
77 #endif
78 (void) textdomain(TEXT_DOMAIN);
79 lc_ctype = setlocale(LC_CTYPE, NULL);
80 getwidth(&eucwidth);
81 eucw[0] = 1;
82 eucw[1] = eucwidth._eucw1;
83 eucw[2] = eucwidth._eucw2;
84 eucw[3] = eucwidth._eucw3;
85 scrw[0] = 1;
86 scrw[1] = eucwidth._scrw1;
87 scrw[2] = eucwidth._scrw2;
88 scrw[3] = eucwidth._scrw3;
89 for (i = 0; i <= 3; i++)
90 csflag[i] = 0;
91 for (i = 1; i < ac; i++)
92 if (*av[i] != '-')
93 goto usage;
94 while ((c = getopt(ac, av, "0123vw")) != -1) {
95 switch (c) {
96 case '0':
97 case '1':
98 case '2':
99 case '3':
100 csflag[c - '0'] = 1;
101 break;
102 case 'v':
103 vflag++;
104 break;
105 case 'w':
106 wflag++;
107 break;
108 default:
109 usage:
110 (void) printf(gettext("usage: %s [-0123vw]\n"), av[0]);
111 exit (1);
112 }
113 }
114 if ((csflag[0] + csflag[1] + csflag[2] + csflag[3]) == 0) {
115 for (i = 0; i <= 3; i++)
116 csflag[i]++;
117 }
118 (void) strcpy(titlebar, "");
119 for (i = strlen(lc_ctype) + 14; i; i--)
120 (void) strcat(titlebar, ":");
121 for (cs = 0; cs <= 3; cs++) {
122 if (csflag[cs] && eucw[cs] && scrw[cs]) {
123 (void) printf("%s\n", titlebar);
124 (void) printf("LC_CTYPE:%s", lc_ctype);
125 (void) printf(" CS:%d\n", cs);
126 (void) printf("%s", titlebar);
127 (void) csprint(cs, (int) eucw[cs], (int) scrw[cs]);
128 (void) printf("\n");
129 }
130 }
131 return (0);
132 }
133
134 int
csprint(cs,bytes,columns)135 csprint(cs, bytes, columns)
136 int cs, bytes, columns;
137 {
138 int col, i, position;
139 int bytelen;
140 int minvalue;
141 int maxvalue;
142
143 col = SCRWID - bytes * 2 - 1;
144 cplmax = 1;
145 for (i = columns + 1; i <= col; i *= 2) cplmax *= 2;
146 cplmax /= 2;
147 bytelen = bytes;
148 minvalue = 0x20;
149 maxvalue = 0x7f;
150 position = 0;
151 if (cs > 0) {
152 minvalue = 0xa0;
153 maxvalue = 0xff;
154 }
155 if (cs == 2) {
156 codestr[position++] = SS2;
157 bytelen++;
158 }
159 if (cs == 3) {
160 codestr[position++] = SS3;
161 bytelen++;
162 }
163 codestr[position] = '\0';
164 cpl = 0;
165 (void) strcpy(linebuf, "");
166 (void) prcode(bytelen, position, minvalue, maxvalue, columns);
167 if (pinline || vflag) {
168 (void) printf("\n%s", linebuf);
169 } else if (!omitting) {
170 (void) printf("\n*");
171 }
172 omitting = 0;
173 return (0);
174 }
175
176 /*
177 * prcode() prints series of len-byte codes, of which each byte can
178 * have a code value between min and max, in incremental code order.
179 */
180 int
prcode(len,pos,min,max,col)181 prcode(len, pos, min, max, col)
182 int len, pos, min, max, col;
183 {
184 int byte, i, nextpos;
185 unsigned long widechar; /* limitting wchar_t width - not good */
186 char *prep;
187 wchar_t wc;
188 int mbl;
189
190 if (len - pos > 1) {
191 for (byte = min; byte <= max; byte++) {
192 codestr[pos] = (unsigned char) byte;
193 nextpos = pos + 1;
194 codestr[nextpos] = '\0';
195 (void) prcode(len, nextpos, min, max, col);
196 }
197 } else {
198 for (byte = min; byte <= max; byte++) {
199 codestr[pos] = (unsigned char) byte;
200 nextpos = pos + 1;
201 codestr[nextpos] = '\0';
202 if (!cpl) {
203 widechar = 0;
204 i = 0;
205 while (codestr[i] != '\0') {
206 widechar = (widechar << 8) |
207 (unsigned long) codestr[i++];
208 }
209 if (*linebuf) {
210 if (pinline || vflag) {
211 (void) printf("\n%s", linebuf);
212 omitting = 0;
213 } else if (!omitting) {
214 (void) printf("\n*");
215 omitting++;
216 }
217 }
218 if (!wflag) {
219 (void) sprintf(linebuf, "%lx ",
220 widechar);
221 } else {
222 (void) mbtowc(&wc, (char *) codestr,
223 MB_CUR_MAX);
224 (void) sprintf(linebuf, "%lx ", wc);
225 }
226 pinline = 0;
227 }
228 prep = " ";
229 if ((mbl = mbtowc(&wc, (char *) codestr,
230 MB_CUR_MAX)) < 0)
231 prep = "*";
232 if (mbl == 1) {
233 if (!(isprint(codestr[0]))) prep = "*";
234 } else if (!(iswprint(wc)))
235 prep = "*";
236 if (prep[0] == '*') {
237 (void) strcat(linebuf, prep);
238 for (i = 1; i <= col; i++)
239 (void) strcat(linebuf, " ");
240 } else {
241 (void) strcat(linebuf, prep);
242 (void) strcat(linebuf, (char *) codestr);
243 pinline = 1;
244 }
245 cpl++;
246 cpl = cpl % cplmax;
247 }
248 }
249 return (0);
250 }
251