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