148755Sbostic /*-
2*62321Sbostic * Copyright (c) 1988, 1993
3*62321Sbostic * The Regents of the University of California. All rights reserved.
431056Sminshall *
548755Sbostic * %sccs.include.redist.c%
631056Sminshall */
731056Sminshall
833817Sbostic #ifndef lint
9*62321Sbostic static char copyright[] =
10*62321Sbostic "@(#) Copyright (c) 1988, 1993\n\
11*62321Sbostic The Regents of the University of California. All rights reserved.\n";
1233817Sbostic #endif /* not lint */
1331056Sminshall
1433817Sbostic #ifndef lint
15*62321Sbostic static char sccsid[] = "@(#)mset.c 8.1 (Berkeley) 06/06/93";
1633817Sbostic #endif /* not lint */
1733817Sbostic
1831056Sminshall /*
1931056Sminshall * this program outputs the user's 3270 mapping table in a form suitable
2031056Sminshall * for inclusion in the environment. Typically, this might be used
2131056Sminshall * by:
2231056Sminshall * setenv MAP3270 "`mset`"
2331056Sminshall */
2431056Sminshall
2531100Sminshall #include <stdio.h>
2631100Sminshall #if defined(unix)
2731056Sminshall #include <strings.h>
2831100Sminshall #else /* defined(unix) */
2931100Sminshall #include <string.h>
3031100Sminshall #endif /* defined(unix) */
3131245Sminshall #include "../ctlr/function.h"
3231245Sminshall
3331176Sminshall #include "state.h"
3435419Sminshall #include "map3270.h"
3535419Sminshall
3631870Sminshall #include "../api/astosc.h"
3731056Sminshall
3831176Sminshall #include "../general/globals.h"
3931056Sminshall
4031056Sminshall struct regstate {
4131056Sminshall char *result;
4231056Sminshall char *match_start;
4331056Sminshall char *match_end; /* start of NEXT state's match string */
4431056Sminshall struct regstate *forward;
4531056Sminshall struct regstate *backward;
4631056Sminshall };
4731056Sminshall
4831056Sminshall static struct regstate regstates[500], *rptr= 0; /* for sorting states */
4931056Sminshall static char array[5000]; /* lot's of room */
5031056Sminshall static int toshell = 0; /* export to shell */
5131056Sminshall static int numbchars = 0; /* number of chars in envir. var */
5231056Sminshall
5331445Sminshall static int
MyStrcmp(str1,str2)5431445Sminshall MyStrcmp(str1, str2)
5531445Sminshall char *str1, *str2;
5631445Sminshall {
5731445Sminshall if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0
5831445Sminshall && strlen(str1) != strlen(str2)) {
5931445Sminshall return(strlen(str1) - strlen(str2));
6031445Sminshall }
6131445Sminshall return(strcmp(str1, str2));
6231445Sminshall }
6331445Sminshall
6431056Sminshall static void
forwRegister(regptr,sptr)6531056Sminshall forwRegister(regptr, sptr)
6631056Sminshall struct regstate *regptr, *sptr;
6731056Sminshall {
6831056Sminshall
6931056Sminshall regptr->forward = sptr->forward;
7031056Sminshall regptr->backward = sptr;
7131056Sminshall (sptr->forward)->backward = regptr;
7231056Sminshall sptr->forward = regptr;
7331056Sminshall }
7431056Sminshall
7531056Sminshall static void
backRegister(regptr,sptr)7631056Sminshall backRegister(regptr, sptr)
7731056Sminshall struct regstate *regptr, *sptr;
7831056Sminshall {
7931056Sminshall
8031056Sminshall regptr->forward = sptr;
8131056Sminshall regptr->backward = sptr->backward;
8231056Sminshall (sptr->backward)->forward = regptr;
8331056Sminshall sptr->backward = regptr;
8431056Sminshall }
8531056Sminshall
8631056Sminshall static struct regstate *
doRegister(regptr)8731056Sminshall doRegister(regptr)
8831056Sminshall register struct regstate *regptr;
8931056Sminshall {
9031056Sminshall static struct regstate *pivot = regstates;
9131056Sminshall register struct regstate *sptr = pivot;
9231056Sminshall int check;
9331056Sminshall
9431056Sminshall if (pivot == regstates) { /* first time called */
9531056Sminshall pivot->forward = regptr;
9631056Sminshall regptr->backward = pivot++;
9731056Sminshall pivot->backward = regptr;
9831056Sminshall regptr->forward = pivot++;
9931056Sminshall return(++regptr);
10031056Sminshall }
10131445Sminshall if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) {
10231056Sminshall while (check < 0) {
10331056Sminshall if (sptr->backward == regstates) {
10431056Sminshall backRegister(regptr, sptr);
10531056Sminshall pivot = pivot->backward;
10631056Sminshall return(++regptr);
10731056Sminshall }
10831056Sminshall sptr = sptr->backward;
10931445Sminshall check = MyStrcmp(regptr->result, sptr->result);
11031056Sminshall }
11131056Sminshall forwRegister(regptr, sptr);
11231056Sminshall pivot = pivot->backward;
11331056Sminshall return(++regptr);
11431056Sminshall }
11531056Sminshall while (check > 0) {
11631056Sminshall if ((sptr->forward)->result == 0) {
11731056Sminshall forwRegister(regptr, sptr);
11831056Sminshall pivot = pivot->forward;
11931056Sminshall return(++regptr);
12031056Sminshall }
12131056Sminshall sptr = sptr->forward;
12231445Sminshall check = MyStrcmp(regptr->result, sptr->result);
12331056Sminshall }
12431056Sminshall backRegister(regptr, sptr);
12531445Sminshall if (pivot->forward->result) {
12631445Sminshall pivot = pivot->forward;
12731445Sminshall }
12831056Sminshall return(++regptr);
12931056Sminshall }
13031056Sminshall
13131056Sminshall static char *
addString(strcount,character)13231056Sminshall addString(strcount, character)
13331056Sminshall int strcount;
13431056Sminshall char character;
13531056Sminshall {
13631056Sminshall static char *string = array;
13731056Sminshall int i;
13831056Sminshall
13931056Sminshall if (rptr->match_start == 0) {
14031056Sminshall rptr->match_start = string;
14131056Sminshall for (i=0; i < strcount; i++) {
14231056Sminshall *string++ = *((rptr-1)->match_start+i);
14331056Sminshall }
14431056Sminshall }
14531056Sminshall *string++ = character;
14631056Sminshall return(string);
14731056Sminshall }
14831056Sminshall
14931056Sminshall static char savename[20] = " "; /* for deciding if name is new */
15031056Sminshall
15131056Sminshall static void
printString(string,begin,tc_name)15231056Sminshall printString(string, begin, tc_name)
15331056Sminshall register char *string;
15431056Sminshall char *begin, *tc_name;
15531056Sminshall {
15631056Sminshall register char *st1, *st2;
15731056Sminshall register int pchar;
15831056Sminshall static char suffix = 'A';
15931056Sminshall int new = strcmp(savename, tc_name);
16031056Sminshall char delim = new ? ';' : '|';
16131100Sminshall char *uncontrol();
16231056Sminshall
16331056Sminshall st1 = begin;
16431056Sminshall
16531056Sminshall numbchars += 5 + (new ? strlen(tc_name) : -1);
16631056Sminshall if (toshell && numbchars > 1011) {
16731056Sminshall new = 1;
16831056Sminshall delim = ';';
16931056Sminshall numbchars = 5 + strlen(tc_name);
17031056Sminshall printf(";\nsetenv MAP3270%c ", suffix++);
17131056Sminshall }
17231056Sminshall if (strcmp(" ", savename)) {
17331056Sminshall if (toshell) {
17431056Sminshall printf("%c%c", '\\', delim);
17531056Sminshall }
17631056Sminshall else {
17731056Sminshall printf("%c", delim);
17831056Sminshall }
17931056Sminshall }
18031056Sminshall else {
18131056Sminshall numbchars -= 2;
18231056Sminshall }
18331056Sminshall if (toshell && new) {
18431056Sminshall printf("%s=%c'", tc_name,'\\');
18531056Sminshall }
18631056Sminshall else if (new) {
18731056Sminshall printf("%s='", tc_name);
18831056Sminshall }
18931056Sminshall else if (toshell) {
19031056Sminshall printf("%c'", '\\');
19131056Sminshall }
19231056Sminshall else {
19331056Sminshall printf("'");
19431056Sminshall }
19531056Sminshall (void) strcpy(savename, tc_name);
19631056Sminshall while (st1 != string) {
19731056Sminshall if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
19831056Sminshall numbchars = 0;
19931056Sminshall printf(";\nsetenv MAP3270%c ", suffix++);
20031056Sminshall }
20131056Sminshall pchar = 0xff&(*st1++);
20231056Sminshall switch (pchar) {
20331056Sminshall case '"':
20431056Sminshall case '!':
20531056Sminshall case '$':
20631056Sminshall case '(':
20731056Sminshall case ')':
20831056Sminshall case ' ':
20931056Sminshall case ';':
21031056Sminshall case '&':
21131056Sminshall case '|':
21231056Sminshall case '>':
21331056Sminshall case '<':
21431056Sminshall case '`':
21531056Sminshall case '#':
21631056Sminshall numbchars += 2;
21731056Sminshall if (toshell) {
21831056Sminshall printf("%c%c", '\\', pchar);
21931056Sminshall }
22031056Sminshall else {
22131056Sminshall printf("%c", pchar);
22231056Sminshall }
22331056Sminshall break;
22431056Sminshall case '\\':
22531056Sminshall case '\'':
22631056Sminshall numbchars += 4;
22731056Sminshall if (toshell) {
22831056Sminshall printf("%c%c%c%c", '\\', '\\', '\\', pchar);
22931056Sminshall }
23031056Sminshall else {
23131056Sminshall printf("%c%c", '\\', pchar);
23231056Sminshall }
23331056Sminshall break;
23431056Sminshall case '^':
23531056Sminshall numbchars += 3;
23631056Sminshall if (toshell) {
23731056Sminshall printf("%c%c%c", '\\', '\\', pchar);
23831056Sminshall }
23931056Sminshall else {
24031056Sminshall printf("%c%c", '\\', pchar);
24131056Sminshall }
24231056Sminshall break;
24331056Sminshall default:
24431100Sminshall st2 = uncontrol(pchar);
24531056Sminshall while ((pchar = *st2++) != 0) {
24631056Sminshall switch (pchar) {
24731056Sminshall case '"':
24831056Sminshall case '!':
24931056Sminshall case '$':
25031056Sminshall case '(':
25131056Sminshall case ')':
25231056Sminshall case ' ':
25331056Sminshall case ';':
25431056Sminshall case '&':
25531056Sminshall case '|':
25631056Sminshall case '>':
25731056Sminshall case '<':
25831056Sminshall case '`':
25931056Sminshall case '#':
26031056Sminshall case '\\':
26131056Sminshall case '\'':
26231056Sminshall if (toshell) {
26331056Sminshall numbchars += 2;
26431056Sminshall printf("%c%c", '\\', pchar);
26531056Sminshall }
26631056Sminshall else {
26731056Sminshall printf("%c", pchar);
26831056Sminshall }
26931056Sminshall break;
27031056Sminshall default:
27131056Sminshall numbchars++;
27231056Sminshall printf("%c", pchar);
27331056Sminshall break;
27431056Sminshall }
27531056Sminshall }
27631056Sminshall break;
27731056Sminshall }
27831056Sminshall }
27931056Sminshall numbchars += 2;
28031056Sminshall if (toshell) {
28131056Sminshall printf("%c'", '\\');
28231056Sminshall }
28331056Sminshall else {
28431056Sminshall printf("'");
28531056Sminshall }
28631056Sminshall }
28731056Sminshall
28831056Sminshall static void
recurse(strcount,head)28931056Sminshall recurse(strcount, head)
29031056Sminshall state *head;
29131056Sminshall int strcount;
29231056Sminshall {
29331056Sminshall /* if there is a left,
29431056Sminshall * recurse on left,
29531056Sminshall * if there is no down,
29631056Sminshall * print the string to here
29731056Sminshall * else,
29831056Sminshall * add the current match to the string,
29931056Sminshall * recurse.
30031056Sminshall * exit.
30131056Sminshall */
30231056Sminshall
30331056Sminshall if (head->next) {
30431056Sminshall recurse(strcount, head->next);
30531056Sminshall }
30631245Sminshall if (head->result != STATE_GOTO) {
30731056Sminshall rptr->match_end = addString(strcount, head->match);
30831245Sminshall rptr->result = astosc[head->result].name;
30931056Sminshall rptr = doRegister(rptr);
31031056Sminshall } else {
31131056Sminshall (void) addString(strcount, head->match);
31231056Sminshall recurse(strcount+1, head->address);
31331056Sminshall strcount--;
31431056Sminshall }
31531056Sminshall return;
31631056Sminshall }
31731056Sminshall
31831056Sminshall
main(argc,argv)31931056Sminshall main(argc, argv)
32031056Sminshall int argc;
32131056Sminshall char *argv[];
32231056Sminshall {
32331056Sminshall state *head;
32431056Sminshall char *keybdPointer = (char *) 0;
32531056Sminshall char *commandName = argv[0];
32631056Sminshall extern char *getenv();
32731056Sminshall int picky = 0;
32831056Sminshall
32931056Sminshall while ((argc > 1) && (argv[1][0] == '-')) {
33031056Sminshall if (!strcmp(argv[1], "-picky")) {
33131056Sminshall picky++;
33231056Sminshall } else if (!strcmp(argv[1], "-shell")) {
33331056Sminshall toshell++;
33431056Sminshall } else {
33531056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
33631056Sminshall commandName);
33731056Sminshall exit(1);
33831056Sminshall /*NOTREACHED*/
33931056Sminshall }
34031056Sminshall argv++;
34131056Sminshall argc--;
34231056Sminshall }
34331056Sminshall if (argc == 2) {
34431056Sminshall keybdPointer = argv[1];
34531056Sminshall } else if (argc > 2) {
34631056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
34731056Sminshall commandName);
34831056Sminshall exit(1);
34931056Sminshall /*NOTREACHED*/
35031056Sminshall }
35131245Sminshall head = InitControl(keybdPointer, picky, ascii_to_index);
35231056Sminshall if (!head) {
35331056Sminshall return(1);
35431056Sminshall }
35531056Sminshall if (keybdPointer == 0) {
35631056Sminshall keybdPointer = getenv("KEYBD");
35731056Sminshall }
35831056Sminshall if (keybdPointer == 0) {
35931056Sminshall keybdPointer = getenv("TERM");
36031056Sminshall }
36131056Sminshall if (keybdPointer == 0) {
36231056Sminshall keybdPointer = "3a"; /* use 3a as the terminal */
36331056Sminshall }
36431056Sminshall if (toshell) {
36531056Sminshall printf("set noglob;\nsetenv MAP3270 ");
36631056Sminshall }
36731056Sminshall printf("%s{", keybdPointer);
36831056Sminshall numbchars = 2 + strlen(keybdPointer);
36931056Sminshall /* now, run through the table registering entries */
37031056Sminshall rptr = regstates + 2;
37131056Sminshall recurse(0, head);
37231056Sminshall /* now print them out */
37331056Sminshall for (rptr = regstates[0].forward; rptr->result != 0;
37431056Sminshall rptr = rptr->forward) {
37531056Sminshall printString(rptr->match_end, rptr->match_start, rptr->result);
37631056Sminshall }
37731056Sminshall if (toshell) {
37831056Sminshall printf("%c;};\nunset noglob;\n", '\\');
37931056Sminshall }
38031056Sminshall else {
38131056Sminshall printf(";}\n");
38231056Sminshall }
38331056Sminshall return(0);
38431056Sminshall }
385