home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / tn3270 / ascii / mset.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-26  |  9.5 KB  |  411 lines

  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
  35. char 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
  41. static 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.  
  66. struct 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.  
  74. static struct regstate regstates[500], *rptr= 0;    /* for sorting states */
  75. static char array[5000];        /* lot's of room */
  76. static int toshell = 0;            /* export to shell */
  77. static int numbchars = 0;        /* number of chars in envir. var */
  78.  
  79. static int
  80. MyStrcmp(str1, str2)
  81. char *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.  
  90. static void
  91. forwRegister(regptr, sptr)
  92. struct 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.  
  101. static void
  102. backRegister(regptr, sptr)
  103. struct 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.  
  112. static struct regstate *
  113. doRegister(regptr)
  114. register 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.  
  157. static char *
  158. addString(strcount, character)
  159. int strcount;
  160. char 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.  
  175. static char savename[20] = " ";  /* for deciding if name is new */
  176.  
  177. static void
  178. printString(string, begin, tc_name)
  179. register char *string;
  180. char *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.  
  314. static void
  315. recurse(strcount, head)
  316. state *head;
  317. int 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.  
  345. main(argc, argv)
  346. int argc;
  347. char *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. }
  411.