/* mapstr - List/Set function keys. Same as Xenix SCO version except */
/* this works for 512 function key table */
# include	<stdio.h>
# include	<sys/types.h>
# include	<sys/at_ansi.h>
# include	<sys/kd.h>

# define	TRUE	1
# define	FALSE	0

# define	isdigit(x) (x >= '0' && x <= '9')
# define	isxdigit(x)	(isdigit(x) || (x >= 'A' && x <= 'F') || (x >= 'a' && x <= 'f'))
# define	XDIGIT(x)	(isdigit(x) ? x - '0' : (x >= 'A' && x <= 'F') ? x - 'A' + 10 : (x - 'a' + 10))
char	*titles[NSTRKEYS] = {
	"Function #1",
	"Function #2",
	"Function #3",
	"Function #4",
	"Function #5",
	"Function #6",
	"Function #7",
	"Function #8",
	"Function #9",
	"Function #10",
	"Function #11",
	"Function #12",
	"Shift Function #1",
	"Shift Function #2",
	"Shift Function #3",
	"Shift Function #4",
	"Shift Function #5",
	"Shift Function #6",
	"Shift Function #7",
	"Shift Function #8",
	"Shift Function #9",
	"Shift Function #10",
	"Shift Function #11",
	"Shift Function #12",
	"Control Function #1",
	"Control Function #2",
	"Control Function #3",
	"Control Function #4",
	"Control Function #5",
	"Control Function #6",
	"Control Function #7",
	"Control Function #8",
	"Control Function #9",
	"Control Function #10",
	"Control Function #11",
	"Control Function #12",
	"Ctrl/Shft Function #1",
	"Ctrl/Shft Function #2",
	"Ctrl/Shft Function #3",
	"Ctrl/Shft Function #4",
	"Ctrl/Shft Function #5",
	"Ctrl/Shft Function #6",
	"Ctrl/Shft Function #7",
	"Ctrl/Shft Function #8",
	"Ctrl/Shft Function #9",
	"Ctrl/Shft Function #10",
	"Ctrl/Shft Function #11",
	"Ctrl/Shft Function #12",
	"Home",
	"Up arrow",
	"Page up",
	"-",
	"Left arrow",
	"5",
	"Right arrow",
	"+",
	"End",
	"Down arrow",
	"Page down",
	"Insert",
	"Alt-A",
	"Alt-B",
	"Alt-C",
	"Alt-D",
	"Alt-E",
	"Alt-F",
	"Alt-G",
	"Alt-H",
	"Alt-I",
	"Alt-J",
	"Alt-K",
	"Alt-L",
	"Alt-M",
	"Alt-N",
	"Alt-O",
	"Alt-P",
	"Alt-Q",
	"Alt-R",
	"Alt-S",
	"Alt-T",
	"Alt-U",
	"Alt-V",
	"Alt-W",
	"Alt-X",
	"Alt-Y",
	"Alt-Z",
	"Ctrl-Home",
	"Ctrl-PgUp",
	"Ctrl- <-",
	"Ctrl- ->",
	"Ctrl-End",
	"Ctrl-PgDn",
	};

int	d_flag = 0;
FILE	*fp;

main(argc, argv)
char	**argv;
{	int	arg_index = do_switches(argc, argv);

	if (argc == 1) 
		usage();
	if (d_flag) {
		list_table();
		exit(0);
		}
	if (arg_index >= argc)
		usage();
	if ((fp = fopen(argv[arg_index], "r")) == NULL) {
		perror(argv[arg_index]);
		exit(1);
		}
	set_table();
}
set_table()
{	static strmap_t	buf = {0};
	unsigned char	*cp = buf;
	int	i = 0;
	char	lbuf[BUFSIZ];
	int	n;
	char	*cp1;
	int	base;

	while (!feof(fp)) {
		if (fgets(lbuf, sizeof lbuf, fp) == NULL)
			break;
		if (lbuf[0] != '"')
			continue;
		for (cp1 = lbuf+1; *cp1 != '"'; ) {
			if (*cp1 != '\\') {
				*cp++ = *cp1++;
				continue;
				}
			cp1++;
			if (*cp1 == 'x') {
				cp1++;
				n = XDIGIT(*cp1);
				cp1++;
				if (isxdigit(*cp1)) {
					n = n * 16 + XDIGIT(*cp1);
					cp1++;
					}
				*cp++ = n;
				continue;
				}
			if (!isdigit(*cp1)) {
				*cp++ = *cp1++;
				continue;
				}
			base = 8;
			n = *cp1++ - '0';
			if (isdigit(*cp1)) {
				n = 8 * n + *cp1++ - '0';
				if (isdigit(*cp1))
					n = 8 * n + *cp1++ - '0';
				}
			*cp++ = n;
			}
		*cp++ = NULL;
		}
	if (ioctl(0, PIO_STRMAP, buf) < 0) {
		perror("PIO_STRMAP");
		}

}
list_table()
{	strmap_t	buf;
	unsigned char	*cp = buf;
	int	i;

	ioctl(0, GIO_STRMAP, buf);
	printf("String key values\n");
	for (i = 0, cp = buf; i < NSTRKEYS; i++) {
		putchar('"');
		while (*cp)
			if (*cp == '\\')
				cp++, printf("\\\\");
			else if (*cp == '"')
				cp++, printf("\\\"");
			else if (*cp >= ' ' && *cp <= 0x7e)
				putchar(*cp++);
			else
				printf("\\x%02x", *cp++);
		cp++;
		printf("\"\t\t\t%s\n", titles[i] ? titles[i] : "Undefined");
		}
}
usage()
{
	printf("Usage:  mapstr [-d] [file]...\n");
	exit(1);
}
do_switches(argc, argv)
char	**argv;

{	char	*cp;
	int	c;
	extern char *optarg;
	int	errflag = 0;
	extern int optind;

	while ((c = getopt(argc, argv, "d")) != EOF)
		switch (c) {
			case 'd':
				d_flag = TRUE;
				break;
			default:
				errflag++;
			}
	
	if (errflag)
		usage();
	return optind;
}
