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