New version numbering.
[unix-history] / usr / src / usr.bin / tn3270 / ascii / mset.c
CommitLineData
b0fc7846 1/*
992de934 2 * Copyright (c) 1984-1987 by the Regents of the
b0fc7846
GM
3 * University of California and by Gregory Glenn Minshall.
4 *
5 * Permission to use, copy, modify, and distribute these
6 * programs and their documentation for any purpose and
7 * without fee is hereby granted, provided that this
8 * copyright and permission appear on all copies and
9 * supporting documentation, the name of the Regents of
10 * the University of California not be used in advertising
11 * or publicity pertaining to distribution of the programs
12 * without specific prior permission, and notice be given in
13 * supporting documentation that copying and distribution is
14 * by permission of the Regents of the University of California
15 * and by Gregory Glenn Minshall. Neither the Regents of the
16 * University of California nor Gregory Glenn Minshall make
17 * representations about the suitability of this software
18 * for any purpose. It is provided "as is" without
19 * express or implied warranty.
20 */
21
22#ifndef lint
c578271f 23static char sccsid[] = "@(#)mset.c 3.1 (Berkeley) %G%";
b0fc7846
GM
24#endif /* ndef lint */
25
26/*
27 * this program outputs the user's 3270 mapping table in a form suitable
28 * for inclusion in the environment. Typically, this might be used
29 * by:
30 * setenv MAP3270 "`mset`"
31 */
32
5dcce654
GM
33#include <stdio.h>
34#if defined(unix)
b0fc7846 35#include <strings.h>
5dcce654
GM
36#else /* defined(unix) */
37#include <string.h>
38#endif /* defined(unix) */
addfa672
GM
39#include "../ctlr/function.h"
40
03bae598 41#include "state.h"
9c711786 42#include "../api/astosc.h"
b0fc7846 43
03bae598
GM
44#include "../general/globals.h"
45#include "map3270.ext"
b0fc7846
GM
46
47struct regstate {
48 char *result;
49 char *match_start;
50 char *match_end; /* start of NEXT state's match string */
51 struct regstate *forward;
52 struct regstate *backward;
53};
54
55static struct regstate regstates[500], *rptr= 0; /* for sorting states */
56static char array[5000]; /* lot's of room */
57static int toshell = 0; /* export to shell */
58static int numbchars = 0; /* number of chars in envir. var */
59
819f5745
GM
60static int
61MyStrcmp(str1, str2)
62char *str1, *str2;
63{
64 if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0
65 && strlen(str1) != strlen(str2)) {
66 return(strlen(str1) - strlen(str2));
67 }
68 return(strcmp(str1, str2));
69}
70
b0fc7846
GM
71static void
72forwRegister(regptr, sptr)
73struct regstate *regptr, *sptr;
74{
75
76 regptr->forward = sptr->forward;
77 regptr->backward = sptr;
78 (sptr->forward)->backward = regptr;
79 sptr->forward = regptr;
80}
81
82static void
83backRegister(regptr, sptr)
84struct regstate *regptr, *sptr;
85{
86
87 regptr->forward = sptr;
88 regptr->backward = sptr->backward;
89 (sptr->backward)->forward = regptr;
90 sptr->backward = regptr;
91}
92
93static struct regstate *
94doRegister(regptr)
95register struct regstate *regptr;
96{
97 static struct regstate *pivot = regstates;
98 register struct regstate *sptr = pivot;
99 int check;
100
101 if (pivot == regstates) { /* first time called */
102 pivot->forward = regptr;
103 regptr->backward = pivot++;
104 pivot->backward = regptr;
105 regptr->forward = pivot++;
106 return(++regptr);
107 }
819f5745 108 if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) {
b0fc7846
GM
109 while (check < 0) {
110 if (sptr->backward == regstates) {
111 backRegister(regptr, sptr);
112 pivot = pivot->backward;
113 return(++regptr);
114 }
115 sptr = sptr->backward;
819f5745 116 check = MyStrcmp(regptr->result, sptr->result);
b0fc7846
GM
117 }
118 forwRegister(regptr, sptr);
119 pivot = pivot->backward;
120 return(++regptr);
121 }
122 while (check > 0) {
123 if ((sptr->forward)->result == 0) {
124 forwRegister(regptr, sptr);
125 pivot = pivot->forward;
126 return(++regptr);
127 }
128 sptr = sptr->forward;
819f5745 129 check = MyStrcmp(regptr->result, sptr->result);
b0fc7846
GM
130 }
131 backRegister(regptr, sptr);
819f5745
GM
132 if (pivot->forward->result) {
133 pivot = pivot->forward;
134 }
b0fc7846
GM
135 return(++regptr);
136}
137
138static char *
139addString(strcount, character)
140int strcount;
141char character;
142{
143 static char *string = array;
144 int i;
145
146 if (rptr->match_start == 0) {
147 rptr->match_start = string;
148 for (i=0; i < strcount; i++) {
149 *string++ = *((rptr-1)->match_start+i);
150 }
151 }
152 *string++ = character;
153 return(string);
154}
155
156static char savename[20] = " "; /* for deciding if name is new */
157
158static void
159printString(string, begin, tc_name)
160register char *string;
161char *begin, *tc_name;
162{
163 register char *st1, *st2;
164 register int pchar;
165 static char suffix = 'A';
166 int new = strcmp(savename, tc_name);
167 char delim = new ? ';' : '|';
5dcce654 168 char *uncontrol();
b0fc7846
GM
169
170 st1 = begin;
171
172 numbchars += 5 + (new ? strlen(tc_name) : -1);
173 if (toshell && numbchars > 1011) {
174 new = 1;
175 delim = ';';
176 numbchars = 5 + strlen(tc_name);
177 printf(";\nsetenv MAP3270%c ", suffix++);
178 }
179 if (strcmp(" ", savename)) {
180 if (toshell) {
181 printf("%c%c", '\\', delim);
182 }
183 else {
184 printf("%c", delim);
185 }
186 }
187 else {
188 numbchars -= 2;
189 }
190 if (toshell && new) {
191 printf("%s=%c'", tc_name,'\\');
192 }
193 else if (new) {
194 printf("%s='", tc_name);
195 }
196 else if (toshell) {
197 printf("%c'", '\\');
198 }
199 else {
200 printf("'");
201 }
202 (void) strcpy(savename, tc_name);
203 while (st1 != string) {
204 if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
205 numbchars = 0;
206 printf(";\nsetenv MAP3270%c ", suffix++);
207 }
208 pchar = 0xff&(*st1++);
209 switch (pchar) {
210 case '"':
211 case '!':
212 case '$':
213 case '(':
214 case ')':
215 case ' ':
216 case ';':
217 case '&':
218 case '|':
219 case '>':
220 case '<':
221 case '`':
222 case '#':
223 numbchars += 2;
224 if (toshell) {
225 printf("%c%c", '\\', pchar);
226 }
227 else {
228 printf("%c", pchar);
229 }
230 break;
231 case '\\':
232 case '\'':
233 numbchars += 4;
234 if (toshell) {
235 printf("%c%c%c%c", '\\', '\\', '\\', pchar);
236 }
237 else {
238 printf("%c%c", '\\', pchar);
239 }
240 break;
241 case '^':
242 numbchars += 3;
243 if (toshell) {
244 printf("%c%c%c", '\\', '\\', pchar);
245 }
246 else {
247 printf("%c%c", '\\', pchar);
248 }
249 break;
250 default:
5dcce654 251 st2 = uncontrol(pchar);
b0fc7846
GM
252 while ((pchar = *st2++) != 0) {
253 switch (pchar) {
254 case '"':
255 case '!':
256 case '$':
257 case '(':
258 case ')':
259 case ' ':
260 case ';':
261 case '&':
262 case '|':
263 case '>':
264 case '<':
265 case '`':
266 case '#':
267 case '\\':
268 case '\'':
269 if (toshell) {
270 numbchars += 2;
271 printf("%c%c", '\\', pchar);
272 }
273 else {
274 printf("%c", pchar);
275 }
276 break;
277 default:
278 numbchars++;
279 printf("%c", pchar);
280 break;
281 }
282 }
283 break;
284 }
285 }
286 numbchars += 2;
287 if (toshell) {
288 printf("%c'", '\\');
289 }
290 else {
291 printf("'");
292 }
293}
294
295static void
296recurse(strcount, head)
297state *head;
298int strcount;
299{
300 /* if there is a left,
301 * recurse on left,
302 * if there is no down,
303 * print the string to here
304 * else,
305 * add the current match to the string,
306 * recurse.
307 * exit.
308 */
309
310 if (head->next) {
311 recurse(strcount, head->next);
312 }
addfa672 313 if (head->result != STATE_GOTO) {
b0fc7846 314 rptr->match_end = addString(strcount, head->match);
addfa672 315 rptr->result = astosc[head->result].name;
b0fc7846
GM
316 rptr = doRegister(rptr);
317 } else {
318 (void) addString(strcount, head->match);
319 recurse(strcount+1, head->address);
320 strcount--;
321 }
322 return;
323}
324
325
326main(argc, argv)
327int argc;
328char *argv[];
329{
330 state *head;
331 char *keybdPointer = (char *) 0;
332 char *commandName = argv[0];
333 extern char *getenv();
334 int picky = 0;
335
336 while ((argc > 1) && (argv[1][0] == '-')) {
337 if (!strcmp(argv[1], "-picky")) {
338 picky++;
339 } else if (!strcmp(argv[1], "-shell")) {
340 toshell++;
341 } else {
342 fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
343 commandName);
344 exit(1);
345 /*NOTREACHED*/
346 }
347 argv++;
348 argc--;
349 }
350 if (argc == 2) {
351 keybdPointer = argv[1];
352 } else if (argc > 2) {
353 fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
354 commandName);
355 exit(1);
356 /*NOTREACHED*/
357 }
addfa672 358 head = InitControl(keybdPointer, picky, ascii_to_index);
b0fc7846
GM
359 if (!head) {
360 return(1);
361 }
362 if (keybdPointer == 0) {
363 keybdPointer = getenv("KEYBD");
364 }
365 if (keybdPointer == 0) {
366 keybdPointer = getenv("TERM");
367 }
368 if (keybdPointer == 0) {
369 keybdPointer = "3a"; /* use 3a as the terminal */
370 }
371 if (toshell) {
372 printf("set noglob;\nsetenv MAP3270 ");
373 }
374 printf("%s{", keybdPointer);
375 numbchars = 2 + strlen(keybdPointer);
376 /* now, run through the table registering entries */
377 rptr = regstates + 2;
378 recurse(0, head);
379 /* now print them out */
380 for (rptr = regstates[0].forward; rptr->result != 0;
381 rptr = rptr->forward) {
382 printString(rptr->match_end, rptr->match_start, rptr->result);
383 }
384 if (toshell) {
385 printf("%c;};\nunset noglob;\n", '\\');
386 }
387 else {
388 printf(";}\n");
389 }
390 return(0);
391}