xref: /csrg-svn/usr.bin/tset/map.c (revision 63080)
152052Sbostic /*-
2*63080Sbostic  * Copyright (c) 1991, 1993
3*63080Sbostic  *	The Regents of the University of California.  All rights reserved.
452052Sbostic  *
552052Sbostic  * %sccs.include.redist.c%
652052Sbostic  */
752052Sbostic 
852052Sbostic #ifndef lint
9*63080Sbostic static char sccsid[] = "@(#)map.c	8.1 (Berkeley) 06/09/93";
1052052Sbostic #endif /* not lint */
1152052Sbostic 
1252052Sbostic #include <sys/types.h>
1352052Sbostic #include <termios.h>
1452052Sbostic #include <errno.h>
1552052Sbostic #include <stdlib.h>
1652052Sbostic #include <string.h>
1752052Sbostic #include "extern.h"
1852052Sbostic 
1952052Sbostic int	baudrate __P((char *));
2052052Sbostic 
2152052Sbostic /* Baud rate conditionals for mapping. */
2252052Sbostic #define	GT		0x01
2352052Sbostic #define	EQ		0x02
2452052Sbostic #define	LT		0x04
2552052Sbostic #define	NOT		0x08
2652052Sbostic #define	GE		(GT | EQ)
2752052Sbostic #define	LE		(LT | EQ)
2852052Sbostic 
2952052Sbostic typedef struct map {
3052052Sbostic 	struct map *next;	/* Linked list of maps. */
3152052Sbostic 	char *porttype;		/* Port type, or "" for any. */
3252052Sbostic 	char *type;		/* Terminal type to select. */
3352052Sbostic 	int conditional;	/* Baud rate conditionals bitmask. */
3452052Sbostic 	int speed;		/* Baud rate to compare against. */
3552052Sbostic } MAP;
3652052Sbostic 
3752052Sbostic MAP *cur, *maplist;
3852052Sbostic 
3952052Sbostic /*
4052052Sbostic  * Syntax for -m:
4152052Sbostic  * [port-type][test baudrate]:terminal-type
4252052Sbostic  * The baud rate tests are: >, <, @, =, !
4352052Sbostic  */
4452052Sbostic void
add_mapping(port,arg)4552064Sbostic add_mapping(port, arg)
4652064Sbostic 	char *port, *arg;
4752052Sbostic {
4852052Sbostic 	MAP *mapp;
4952052Sbostic 	char *copy, *p, *termp;
5052052Sbostic 
5152052Sbostic 	copy = strdup(arg);
5252052Sbostic 	mapp = malloc((u_int)sizeof(MAP));
5352052Sbostic 	if (copy == NULL || mapp == NULL)
5452052Sbostic 		err("%s", strerror(errno));
5552052Sbostic 	mapp->next = NULL;
5652052Sbostic 	if (maplist == NULL)
5752052Sbostic 		cur = maplist = mapp;
5852052Sbostic 	else {
5952052Sbostic 		cur->next = mapp;
6052052Sbostic 		cur =  mapp;
6152052Sbostic 	}
6252052Sbostic 
6352052Sbostic 	mapp->porttype = arg;
6452052Sbostic 	mapp->conditional = 0;
6552052Sbostic 
6652052Sbostic 	arg = strpbrk(arg, "><@=!:");
6752052Sbostic 
6852052Sbostic 	if (arg == NULL) {			/* [?]term */
6952052Sbostic 		mapp->type = mapp->porttype;
7052052Sbostic 		mapp->porttype = NULL;
7152064Sbostic 		goto done;
7252052Sbostic 	}
7352052Sbostic 
7452052Sbostic 	if (arg == mapp->porttype)		/* [><@=! baud]:term */
7552052Sbostic 		termp = mapp->porttype = NULL;
7652052Sbostic 	else
7752052Sbostic 		termp = arg;
7852052Sbostic 
7952052Sbostic 	for (;; ++arg)				/* Optional conditionals. */
8052052Sbostic 		switch(*arg) {
8152052Sbostic 		case '<':
8252052Sbostic 			if (mapp->conditional & GT)
8352052Sbostic 				goto badmopt;
8452052Sbostic 			mapp->conditional |= LT;
8552052Sbostic 			break;
8652052Sbostic 		case '>':
8752052Sbostic 			if (mapp->conditional & LT)
8852052Sbostic 				goto badmopt;
8952052Sbostic 			mapp->conditional |= GT;
9052052Sbostic 			break;
9152052Sbostic 		case '@':
9252052Sbostic 		case '=':			/* Not documented. */
9352052Sbostic 			mapp->conditional |= EQ;
9452052Sbostic 			break;
9552052Sbostic 		case '!':
9652052Sbostic 			mapp->conditional |= NOT;
9752052Sbostic 			break;
9852052Sbostic 		default:
9952052Sbostic 			goto next;
10052052Sbostic 		}
10152052Sbostic 
10252052Sbostic next:	if (*arg == ':') {
10352052Sbostic 		if (mapp->conditional)
10452052Sbostic 			goto badmopt;
10552052Sbostic 		++arg;
10652052Sbostic 	} else {				/* Optional baudrate. */
10752052Sbostic 		arg = index(p = arg, ':');
10852052Sbostic 		if (arg == NULL)
10952052Sbostic 			goto badmopt;
11052052Sbostic 		*arg++ = '\0';
11152052Sbostic 		mapp->speed = baudrate(p);
11252052Sbostic 	}
11352052Sbostic 
11452052Sbostic 	if (*arg == NULL)			/* Non-optional type. */
11552064Sbostic 		goto badmopt;
11652052Sbostic 
11752052Sbostic 	mapp->type = arg;
11852052Sbostic 
11952052Sbostic 	/* Terminate porttype, if specified. */
12052052Sbostic 	if (termp != NULL)
12152052Sbostic 		*termp = '\0';
12252052Sbostic 
12352052Sbostic 	/* If a NOT conditional, reverse the test. */
12452052Sbostic 	if (mapp->conditional & NOT)
12552052Sbostic 		mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
12652052Sbostic 
12752064Sbostic 	/* If user specified a port with an option flag, set it. */
12852064Sbostic done:	if (port) {
12952064Sbostic 		if (mapp->porttype)
13052064Sbostic badmopt:		err("illegal -m option format: %s", copy);
13152064Sbostic 		mapp->porttype = port;
13252064Sbostic 	}
13352064Sbostic 
13452052Sbostic #ifdef MAPDEBUG
13552064Sbostic 	(void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
13652052Sbostic 	(void)printf("type: %s\n", mapp->type);
13752052Sbostic 	(void)printf("conditional: ");
13852052Sbostic 	p = "";
13952052Sbostic 	if (mapp->conditional & GT) {
14052052Sbostic 		(void)printf("GT");
14152052Sbostic 		p = "/";
14252052Sbostic 	}
14352052Sbostic 	if (mapp->conditional & EQ) {
14452052Sbostic 		(void)printf("%sEQ", p);
14552052Sbostic 		p = "/";
14652052Sbostic 	}
14752052Sbostic 	if (mapp->conditional & LT)
14852052Sbostic 		(void)printf("%sLT", p);
14952052Sbostic 	(void)printf("\nspeed: %d\n", mapp->speed);
15052052Sbostic #endif
15152052Sbostic }
15252052Sbostic 
15352052Sbostic /*
15452052Sbostic  * Return the type of terminal to use for a port of type 'type', as specified
15552052Sbostic  * by the first applicable mapping in 'map'.  If no mappings apply, return
15652052Sbostic  * 'type'.
15752052Sbostic  */
15852052Sbostic char *
mapped(type)15952052Sbostic mapped(type)
16052052Sbostic 	char *type;
16152052Sbostic {
16252052Sbostic 	MAP *mapp;
16352052Sbostic 	int match;
16452052Sbostic 
16552052Sbostic 	for (mapp = maplist; mapp; mapp = mapp->next)
16652052Sbostic 		if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) {
16752052Sbostic 			switch (mapp->conditional) {
16852052Sbostic 			case 0:			/* No test specified. */
16952052Sbostic 				match = 1;
17052052Sbostic 				break;
17152052Sbostic 			case EQ:
17252052Sbostic 				match = (ospeed == mapp->speed);
17352052Sbostic 				break;
17452052Sbostic 			case GE:
17552052Sbostic 				match = (ospeed >= mapp->speed);
17652052Sbostic 				break;
17752052Sbostic 			case GT:
17852052Sbostic 				match = (ospeed > mapp->speed);
17952052Sbostic 				break;
18052052Sbostic 			case LE:
18152052Sbostic 				match = (ospeed <= mapp->speed);
18252052Sbostic 				break;
18352052Sbostic 			case LT:
18452052Sbostic 				match = (ospeed < mapp->speed);
18552052Sbostic 				break;
18652052Sbostic 			}
18752052Sbostic 			if (match)
18852052Sbostic 				return (mapp->type);
18952052Sbostic 		}
19052052Sbostic 	/* No match found; return given type. */
19152052Sbostic 	return (type);
19252052Sbostic }
19352052Sbostic 
19452052Sbostic typedef struct speeds {
19552052Sbostic 	char	*string;
19652052Sbostic 	int	speed;
19752052Sbostic } SPEEDS;
19852052Sbostic 
19952052Sbostic SPEEDS speeds[] = {
20052052Sbostic 	"0",		B0,
20152052Sbostic 	"50",		B50,
20252052Sbostic 	"75",		B75,
20352052Sbostic 	"110",		B110,
20452052Sbostic 	"134",		B134,
20552052Sbostic 	"134.5",	B134,
20652052Sbostic 	"150",		B150,
20752052Sbostic 	"200",		B200,
20852052Sbostic 	"300",		B300,
20952052Sbostic 	"600",		B600,
21052052Sbostic 	"1200",		B1200,
21152052Sbostic 	"1800",		B1800,
21252052Sbostic 	"2400",		B2400,
21352052Sbostic 	"4800",		B4800,
21452052Sbostic 	"9600",		B9600,
21552052Sbostic 	"19200",	B19200,
21652052Sbostic 	"38400",	B38400,
21752052Sbostic 	"exta",		B19200,
21852052Sbostic 	"extb",		B38400,
21952052Sbostic 	NULL
22052052Sbostic };
22152052Sbostic 
22252052Sbostic int
baudrate(rate)22352052Sbostic baudrate(rate)
22452052Sbostic 	char *rate;
22552052Sbostic {
22652052Sbostic 	SPEEDS *sp;
22752052Sbostic 
22852052Sbostic 	/* The baudrate number can be preceded by a 'B', which is ignored. */
22952052Sbostic 	if (*rate == 'B')
23052052Sbostic 		++rate;
23152052Sbostic 
23252052Sbostic 	for (sp = speeds; sp->string; ++sp)
23352052Sbostic 		if (!strcasecmp(rate, sp->string))
23452052Sbostic 			return (sp->speed);
23552052Sbostic 	err("unknown baud rate %s", rate);
23652052Sbostic 	/* NOTREACHED */
23752052Sbostic }
238