break up into multiple modules
[unix-history] / usr / src / usr.bin / tset / map.c
CommitLineData
c161724f
KB
1/*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
9static char sccsid[] = "@(#)map.c 5.1 (Berkeley) %G%";
10#endif /* not lint */
11
12#include <sys/types.h>
13#include <termios.h>
14#include <errno.h>
15#include <stdlib.h>
16#include <string.h>
17#include "extern.h"
18
19int baudrate __P((char *));
20
21/* Baud rate conditionals for mapping. */
22#define GT 0x01
23#define EQ 0x02
24#define LT 0x04
25#define NOT 0x08
26#define GE (GT | EQ)
27#define LE (LT | EQ)
28
29typedef struct map {
30 struct map *next; /* Linked list of maps. */
31 char *porttype; /* Port type, or "" for any. */
32 char *type; /* Terminal type to select. */
33 int conditional; /* Baud rate conditionals bitmask. */
34 int speed; /* Baud rate to compare against. */
35} MAP;
36
37MAP *cur, *maplist;
38
39/*
40 * Syntax for -m:
41 * [port-type][test baudrate]:terminal-type
42 * The baud rate tests are: >, <, @, =, !
43 */
44void
45add_mapping(arg)
46 char *arg;
47{
48 MAP *mapp;
49 char *copy, *p, *termp;
50
51 copy = strdup(arg);
52 mapp = malloc((u_int)sizeof(MAP));
53 if (copy == NULL || mapp == NULL)
54 err("%s", strerror(errno));
55 mapp->next = NULL;
56 if (maplist == NULL)
57 cur = maplist = mapp;
58 else {
59 cur->next = mapp;
60 cur = mapp;
61 }
62
63 mapp->porttype = arg;
64 mapp->conditional = 0;
65
66 arg = strpbrk(arg, "><@=!:");
67
68 if (arg == NULL) { /* [?]term */
69 mapp->type = mapp->porttype;
70 mapp->porttype = NULL;
71#ifdef MAPDEBUG
72 goto mdebug;
73#else
74 return;
75#endif
76 }
77
78 if (arg == mapp->porttype) /* [><@=! baud]:term */
79 termp = mapp->porttype = NULL;
80 else
81 termp = arg;
82
83 for (;; ++arg) /* Optional conditionals. */
84 switch(*arg) {
85 case '<':
86 if (mapp->conditional & GT)
87 goto badmopt;
88 mapp->conditional |= LT;
89 break;
90 case '>':
91 if (mapp->conditional & LT)
92 goto badmopt;
93 mapp->conditional |= GT;
94 break;
95 case '@':
96 case '=': /* Not documented. */
97 mapp->conditional |= EQ;
98 break;
99 case '!':
100 mapp->conditional |= NOT;
101 break;
102 default:
103 goto next;
104 }
105
106next: if (*arg == ':') {
107 if (mapp->conditional)
108 goto badmopt;
109 ++arg;
110 } else { /* Optional baudrate. */
111 arg = index(p = arg, ':');
112 if (arg == NULL)
113 goto badmopt;
114 *arg++ = '\0';
115 mapp->speed = baudrate(p);
116 }
117
118 if (*arg == NULL) /* Non-optional type. */
119badmopt: err("illegal -m option format: %s", copy);
120
121 mapp->type = arg;
122
123 /* Terminate porttype, if specified. */
124 if (termp != NULL)
125 *termp = '\0';
126
127 /* If a NOT conditional, reverse the test. */
128 if (mapp->conditional & NOT)
129 mapp->conditional = ~mapp->conditional & (EQ | GT | LT);
130
131#ifdef MAPDEBUG
132mdebug: (void)printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
133 (void)printf("type: %s\n", mapp->type);
134 (void)printf("conditional: ");
135 p = "";
136 if (mapp->conditional & GT) {
137 (void)printf("GT");
138 p = "/";
139 }
140 if (mapp->conditional & EQ) {
141 (void)printf("%sEQ", p);
142 p = "/";
143 }
144 if (mapp->conditional & LT)
145 (void)printf("%sLT", p);
146 (void)printf("\nspeed: %d\n", mapp->speed);
147#endif
148}
149
150/*
151 * Return the type of terminal to use for a port of type 'type', as specified
152 * by the first applicable mapping in 'map'. If no mappings apply, return
153 * 'type'.
154 */
155char *
156mapped(type)
157 char *type;
158{
159 MAP *mapp;
160 int match;
161
162 for (mapp = maplist; mapp; mapp = mapp->next)
163 if (mapp->porttype == NULL || !strcmp(mapp->porttype, type)) {
164 switch (mapp->conditional) {
165 case 0: /* No test specified. */
166 match = 1;
167 break;
168 case EQ:
169 match = (ospeed == mapp->speed);
170 break;
171 case GE:
172 match = (ospeed >= mapp->speed);
173 break;
174 case GT:
175 match = (ospeed > mapp->speed);
176 break;
177 case LE:
178 match = (ospeed <= mapp->speed);
179 break;
180 case LT:
181 match = (ospeed < mapp->speed);
182 break;
183 }
184 if (match)
185 return (mapp->type);
186 }
187 /* No match found; return given type. */
188 return (type);
189}
190
191typedef struct speeds {
192 char *string;
193 int speed;
194} SPEEDS;
195
196SPEEDS speeds[] = {
197 "0", B0,
198 "50", B50,
199 "75", B75,
200 "110", B110,
201 "134", B134,
202 "134.5", B134,
203 "150", B150,
204 "200", B200,
205 "300", B300,
206 "600", B600,
207 "1200", B1200,
208 "1800", B1800,
209 "2400", B2400,
210 "4800", B4800,
211 "9600", B9600,
212 "19200", B19200,
213 "38400", B38400,
214 "exta", B19200,
215 "extb", B38400,
216 NULL
217};
218
219int
220baudrate(rate)
221 char *rate;
222{
223 SPEEDS *sp;
224
225 /* The baudrate number can be preceded by a 'B', which is ignored. */
226 if (*rate == 'B')
227 ++rate;
228
229 for (sp = speeds; sp->string; ++sp)
230 if (!strcasecmp(rate, sp->string))
231 return (sp->speed);
232 err("unknown baud rate %s", rate);
233 /* NOTREACHED */
234}