OpenSolaris_b135/cmd/dumpcs/dumpcs.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <locale.h>
#include <wctype.h>
#include <getwidth.h>

#define	SCRWID 80
#define	LC_NAMELEN 255

#if !defined SS2
#define	SS2 0x8e
#endif
#if !defined SS3
#define	SS3 0x8f
#endif

static unsigned int cpl;	/* current characters per line */
static unsigned int cplmax;	/* maximum characters per line */
static unsigned char codestr[MB_LEN_MAX + 1];
static char linebuf[SCRWID / 2 * (MB_LEN_MAX + 1)];
static int pinline;		/* any printable to be listed in the line? */
static int omitting;		/* omitting blank lines under no vflag? */
static int vflag = 0;
static int wflag = 0;
static int csprint();
static int prcode();

int
main(ac, av)
int ac;
char *av[];
{
	int c;
	short int eucw[4];
	short int scrw[4];
	int csflag[4];
	int cs;
	int i;
	eucwidth_t eucwidth;
	char *lc_ctype;
	char titlebar[LC_NAMELEN + 14];

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);
	lc_ctype = setlocale(LC_CTYPE, NULL);
	getwidth(&eucwidth);
	eucw[0] = 1;
	eucw[1] = eucwidth._eucw1;
	eucw[2] = eucwidth._eucw2;
	eucw[3] = eucwidth._eucw3;
	scrw[0] = 1;
	scrw[1] = eucwidth._scrw1;
	scrw[2] = eucwidth._scrw2;
	scrw[3] = eucwidth._scrw3;
	for (i = 0; i <= 3; i++)
		csflag[i] = 0;
	for (i = 1; i < ac; i++)
		if (*av[i] != '-')
			goto usage;
	while ((c = getopt(ac, av, "0123vw")) != -1) {
		switch (c) {
			case '0':
			case '1':
			case '2':
			case '3':
				csflag[c - '0'] = 1;
				break;
			case 'v':
				vflag++;
				break;
			case 'w':
				wflag++;
				break;
			default:
			usage:
				(void) printf(gettext("usage: %s [-0123vw]\n"), av[0]);
				exit (1);
		}
	}
	if ((csflag[0] + csflag[1] + csflag[2] + csflag[3]) == 0) {
		for (i = 0; i <= 3; i++)
			csflag[i]++;
	}
	(void) strcpy(titlebar, "");
	for (i = strlen(lc_ctype) + 14; i; i--)
		(void) strcat(titlebar, ":");
	for (cs = 0; cs <= 3; cs++) {
		if (csflag[cs] && eucw[cs] && scrw[cs]) {
			(void) printf("%s\n", titlebar);
			(void) printf("LC_CTYPE:%s", lc_ctype);
			(void) printf(" CS:%d\n", cs);
			(void) printf("%s", titlebar);
			(void) csprint(cs, (int) eucw[cs], (int) scrw[cs]);
			(void) printf("\n");
		}
	}
	return (0);
}

int
csprint(cs, bytes, columns)
int cs, bytes, columns;
{
	int col, i, position;
	int bytelen;
	int minvalue;
	int maxvalue;

	col = SCRWID - bytes * 2 - 1;
	cplmax = 1;
	for (i = columns + 1; i <= col; i *= 2) cplmax *= 2;
	cplmax /= 2;
	bytelen = bytes;
	minvalue = 0x20;
	maxvalue = 0x7f;
	position = 0;
	if (cs > 0) {
		minvalue = 0xa0;
		maxvalue = 0xff;
	}
	if (cs == 2) {
		codestr[position++] = SS2;
		bytelen++;
	}
	if (cs == 3) {
		codestr[position++] = SS3;
		bytelen++;
	}
	codestr[position] = '\0';
	cpl = 0;
	(void) strcpy(linebuf, "");
	(void) prcode(bytelen, position, minvalue, maxvalue, columns);
	if (pinline || vflag) {
		(void) printf("\n%s", linebuf);
	} else if (!omitting) {
		(void) printf("\n*");
	}
	omitting = 0;
	return (0);
}

/*
 * prcode() prints series of len-byte codes, of which each byte can
 * have a code value between min and max, in incremental code order.
 */
int
prcode(len, pos, min, max, col)
int len, pos, min, max, col;
{
	int byte, i, nextpos;
	unsigned long widechar;	/* limitting wchar_t width - not good */
	char *prep;
	wchar_t wc;
	int	mbl;

	if (len - pos > 1) {
		for (byte = min; byte <= max; byte++) {
			codestr[pos] = (unsigned char) byte;
			nextpos = pos + 1;
			codestr[nextpos] = '\0';
			(void) prcode(len, nextpos, min, max, col);
		}
	} else {
		for (byte = min; byte <= max; byte++) {
			codestr[pos] = (unsigned char) byte;
			nextpos = pos + 1;
			codestr[nextpos] = '\0';
			if (!cpl) {
				widechar = 0;
				i = 0;
				while (codestr[i] != '\0') {
					widechar = (widechar << 8) |
						(unsigned long) codestr[i++];
				}
				if (*linebuf) {
					if (pinline || vflag) {
						(void) printf("\n%s", linebuf);
						omitting = 0;
					} else if (!omitting) {
						(void) printf("\n*");
						omitting++;
					}
				}
				if (!wflag) {
					(void) sprintf(linebuf, "%lx ",
					    widechar);
				} else {
					(void) mbtowc(&wc, (char *) codestr,
					    MB_CUR_MAX);
					(void) sprintf(linebuf, "%lx ", wc);
				}
				pinline = 0;
			}
			prep = " ";
			if ((mbl = mbtowc(&wc, (char *) codestr,
			    MB_CUR_MAX)) < 0)
				prep = "*";
			if (mbl == 1) {
				if (!(isprint(codestr[0]))) prep = "*";
			} else if (!(iswprint(wc)))
				prep = "*";
			if (prep[0] == '*') {
				(void) strcat(linebuf, prep);
				for (i = 1; i <= col; i++)
					(void) strcat(linebuf, " ");
			} else {
				(void) strcat(linebuf, prep);
				(void) strcat(linebuf, (char *) codestr);
				pinline = 1;
			}
			cpl++;
			cpl = cpl % cplmax;
		}
	}
	return (0);
}