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 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 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 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