386BSD 0.0 development
[unix-history] / usr / src / usr.bin / tn3270 / ascii / mset.c
CommitLineData
c431f253
WJ
1/*-
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1988 The Regents of the University of California.\n\
37 All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)mset.c 4.2 (Berkeley) 4/26/91";
42#endif /* not lint */
43
44/*
45 * this program outputs the user's 3270 mapping table in a form suitable
46 * for inclusion in the environment. Typically, this might be used
47 * by:
48 * setenv MAP3270 "`mset`"
49 */
50
51#include <stdio.h>
52#if defined(unix)
53#include <strings.h>
54#else /* defined(unix) */
55#include <string.h>
56#endif /* defined(unix) */
57#include "../ctlr/function.h"
58
59#include "state.h"
60#include "map3270.h"
61
62#include "../api/astosc.h"
63
64#include "../general/globals.h"
65
66struct regstate {
67 char *result;
68 char *match_start;
69 char *match_end; /* start of NEXT state's match string */
70 struct regstate *forward;
71 struct regstate *backward;
72};
73
74static struct regstate regstates[500], *rptr= 0; /* for sorting states */
75static char array[5000]; /* lot's of room */
76static int toshell = 0; /* export to shell */
77static int numbchars = 0; /* number of chars in envir. var */
78
79static int
80MyStrcmp(str1, str2)
81char *str1, *str2;
82{
83 if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0
84 && strlen(str1) != strlen(str2)) {
85 return(strlen(str1) - strlen(str2));
86 }
87 return(strcmp(str1, str2));
88}
89
90static void
91forwRegister(regptr, sptr)
92struct regstate *regptr, *sptr;
93{
94
95 regptr->forward = sptr->forward;
96 regptr->backward = sptr;
97 (sptr->forward)->backward = regptr;
98 sptr->forward = regptr;
99}
100
101static void
102backRegister(regptr, sptr)
103struct regstate *regptr, *sptr;
104{
105
106 regptr->forward = sptr;
107 regptr->backward = sptr->backward;
108 (sptr->backward)->forward = regptr;
109 sptr->backward = regptr;
110}
111
112static struct regstate *
113doRegister(regptr)
114register struct regstate *regptr;
115{
116 static struct regstate *pivot = regstates;
117 register struct regstate *sptr = pivot;
118 int check;
119
120 if (pivot == regstates) { /* first time called */
121 pivot->forward = regptr;
122 regptr->backward = pivot++;
123 pivot->backward = regptr;
124 regptr->forward = pivot++;
125 return(++regptr);
126 }
127 if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) {
128 while (check < 0) {
129 if (sptr->backward == regstates) {
130 backRegister(regptr, sptr);
131 pivot = pivot->backward;
132 return(++regptr);
133 }
134 sptr = sptr->backward;
135 check = MyStrcmp(regptr->result, sptr->result);
136 }
137 forwRegister(regptr, sptr);
138 pivot = pivot->backward;
139 return(++regptr);
140 }
141 while (check > 0) {
142 if ((sptr->forward)->result == 0) {
143 forwRegister(regptr, sptr);
144 pivot = pivot->forward;
145 return(++regptr);
146 }
147 sptr = sptr->forward;
148 check = MyStrcmp(regptr->result, sptr->result);
149 }
150 backRegister(regptr, sptr);
151 if (pivot->forward->result) {
152 pivot = pivot->forward;
153 }
154 return(++regptr);
155}
156
157static char *
158addString(strcount, character)
159int strcount;
160char character;
161{
162 static char *string = array;
163 int i;
164
165 if (rptr->match_start == 0) {
166 rptr->match_start = string;
167 for (i=0; i < strcount; i++) {
168 *string++ = *((rptr-1)->match_start+i);
169 }
170 }
171 *string++ = character;
172 return(string);
173}
174
175static char savename[20] = " "; /* for deciding if name is new */
176
177static void
178printString(string, begin, tc_name)
179register char *string;
180char *begin, *tc_name;
181{
182 register char *st1, *st2;
183 register int pchar;
184 static char suffix = 'A';
185 int new = strcmp(savename, tc_name);
186 char delim = new ? ';' : '|';
187 char *uncontrol();
188
189 st1 = begin;
190
191 numbchars += 5 + (new ? strlen(tc_name) : -1);
192 if (toshell && numbchars > 1011) {
193 new = 1;
194 delim = ';';
195 numbchars = 5 + strlen(tc_name);
196 printf(";\nsetenv MAP3270%c ", suffix++);
197 }
198 if (strcmp(" ", savename)) {
199 if (toshell) {
200 printf("%c%c", '\\', delim);
201 }
202 else {
203 printf("%c", delim);
204 }
205 }
206 else {
207 numbchars -= 2;
208 }
209 if (toshell && new) {
210 printf("%s=%c'", tc_name,'\\');
211 }
212 else if (new) {
213 printf("%s='", tc_name);
214 }
215 else if (toshell) {
216 printf("%c'", '\\');
217 }
218 else {
219 printf("'");
220 }
221 (void) strcpy(savename, tc_name);
222 while (st1 != string) {
223 if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
224 numbchars = 0;
225 printf(";\nsetenv MAP3270%c ", suffix++);
226 }
227 pchar = 0xff&(*st1++);
228 switch (pchar) {
229 case '"':
230 case '!':
231 case '$':
232 case '(':
233 case ')':
234 case ' ':
235 case ';':
236 case '&':
237 case '|':
238 case '>':
239 case '<':
240 case '`':
241 case '#':
242 numbchars += 2;
243 if (toshell) {
244 printf("%c%c", '\\', pchar);
245 }
246 else {
247 printf("%c", pchar);
248 }
249 break;
250 case '\\':
251 case '\'':
252 numbchars += 4;
253 if (toshell) {
254 printf("%c%c%c%c", '\\', '\\', '\\', pchar);
255 }
256 else {
257 printf("%c%c", '\\', pchar);
258 }
259 break;
260 case '^':
261 numbchars += 3;
262 if (toshell) {
263 printf("%c%c%c", '\\', '\\', pchar);
264 }
265 else {
266 printf("%c%c", '\\', pchar);
267 }
268 break;
269 default:
270 st2 = uncontrol(pchar);
271 while ((pchar = *st2++) != 0) {
272 switch (pchar) {
273 case '"':
274 case '!':
275 case '$':
276 case '(':
277 case ')':
278 case ' ':
279 case ';':
280 case '&':
281 case '|':
282 case '>':
283 case '<':
284 case '`':
285 case '#':
286 case '\\':
287 case '\'':
288 if (toshell) {
289 numbchars += 2;
290 printf("%c%c", '\\', pchar);
291 }
292 else {
293 printf("%c", pchar);
294 }
295 break;
296 default:
297 numbchars++;
298 printf("%c", pchar);
299 break;
300 }
301 }
302 break;
303 }
304 }
305 numbchars += 2;
306 if (toshell) {
307 printf("%c'", '\\');
308 }
309 else {
310 printf("'");
311 }
312}
313
314static void
315recurse(strcount, head)
316state *head;
317int strcount;
318{
319 /* if there is a left,
320 * recurse on left,
321 * if there is no down,
322 * print the string to here
323 * else,
324 * add the current match to the string,
325 * recurse.
326 * exit.
327 */
328
329 if (head->next) {
330 recurse(strcount, head->next);
331 }
332 if (head->result != STATE_GOTO) {
333 rptr->match_end = addString(strcount, head->match);
334 rptr->result = astosc[head->result].name;
335 rptr = doRegister(rptr);
336 } else {
337 (void) addString(strcount, head->match);
338 recurse(strcount+1, head->address);
339 strcount--;
340 }
341 return;
342}
343
344
345main(argc, argv)
346int argc;
347char *argv[];
348{
349 state *head;
350 char *keybdPointer = (char *) 0;
351 char *commandName = argv[0];
352 extern char *getenv();
353 int picky = 0;
354
355 while ((argc > 1) && (argv[1][0] == '-')) {
356 if (!strcmp(argv[1], "-picky")) {
357 picky++;
358 } else if (!strcmp(argv[1], "-shell")) {
359 toshell++;
360 } else {
361 fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
362 commandName);
363 exit(1);
364 /*NOTREACHED*/
365 }
366 argv++;
367 argc--;
368 }
369 if (argc == 2) {
370 keybdPointer = argv[1];
371 } else if (argc > 2) {
372 fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
373 commandName);
374 exit(1);
375 /*NOTREACHED*/
376 }
377 head = InitControl(keybdPointer, picky, ascii_to_index);
378 if (!head) {
379 return(1);
380 }
381 if (keybdPointer == 0) {
382 keybdPointer = getenv("KEYBD");
383 }
384 if (keybdPointer == 0) {
385 keybdPointer = getenv("TERM");
386 }
387 if (keybdPointer == 0) {
388 keybdPointer = "3a"; /* use 3a as the terminal */
389 }
390 if (toshell) {
391 printf("set noglob;\nsetenv MAP3270 ");
392 }
393 printf("%s{", keybdPointer);
394 numbchars = 2 + strlen(keybdPointer);
395 /* now, run through the table registering entries */
396 rptr = regstates + 2;
397 recurse(0, head);
398 /* now print them out */
399 for (rptr = regstates[0].forward; rptr->result != 0;
400 rptr = rptr->forward) {
401 printString(rptr->match_end, rptr->match_start, rptr->result);
402 }
403 if (toshell) {
404 printf("%c;};\nunset noglob;\n", '\\');
405 }
406 else {
407 printf(";}\n");
408 }
409 return(0);
410}