home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xim_LcPrs.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  12KB  |  515 lines

  1. /* $XConsortium: imLcPrs.c /main/7 1996/11/20 18:13:05 kaleb $ */
  2. /******************************************************************
  3.  
  4.               Copyright 1992 by Oki Technosystems Laboratory, Inc.
  5.               Copyright 1992 by Fuji Xerox Co., Ltd.
  6.  
  7. Permission to use, copy, modify, distribute, and sell this software
  8. and its documentation for any purpose is hereby granted without fee,
  9. provided that the above copyright notice appear in all copies and
  10. that both that copyright notice and this permission notice appear
  11. in supporting documentation, and that the name of Oki Technosystems
  12. Laboratory and Fuji Xerox not be used in advertising or publicity
  13. pertaining to distribution of the software without specific, written
  14. prior permission.
  15. Oki Technosystems Laboratory and Fuji Xerox make no representations
  16. about the suitability of this software for any purpose.  It is provided
  17. "as is" without express or implied warranty.
  18.  
  19. OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
  20. WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  21. MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
  22. LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  23. CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  24. OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  25. OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  26. OR PERFORMANCE OF THIS SOFTWARE.
  27.  
  28.   Author: Yasuhiro Kawai    Oki Technosystems Laboratory
  29.   Author: Kazunori Nishihara    Fuji Xerox
  30.  
  31. ******************************************************************/
  32.  
  33. /* $XFree86: xc/lib/X11/imLcPrs.c,v 1.1.1.3.2.2 1998/05/19 07:31:41 dawes Exp $ */
  34.  
  35. #include <stdio.h>
  36. #include "Xlib_private.h"
  37. #include <X11/Xlib.h>
  38. #include <X11/Xmd.h>
  39. #include <X11/Xos.h>
  40. #include "Xlcint.h"
  41. #include "Ximint.h"
  42.  
  43. extern int _Xmbstowcs(
  44. #if NeedFunctionPrototypes
  45.     wchar_t    *wstr,
  46.     char    *str,
  47.     int        len
  48. #endif
  49. );
  50.  
  51. /*
  52.  *    Parsing File Format:
  53.  *
  54.  *    FILE          ::= { [PRODUCTION] [COMMENT] "\n"}
  55.  *    PRODUCTION    ::= LHS ":" RHS [ COMMENT ]
  56.  *    COMMENT       ::= "#" {<any character except null or newline>}
  57.  *    LHS           ::= EVENT { EVENT }
  58.  *    EVENT         ::= [MODIFIER_LIST] "<" keysym ">"
  59.  *    MODIFIER_LIST ::= ("!" {MODIFIER} ) | "None"
  60.  *    MODIFIER      ::= ["~"] modifier_name
  61.  *    RHS           ::= ( STRING | keysym | STRING keysym )
  62.  *    STRING        ::= '"' { CHAR } '"'
  63.  *    CHAR          ::= GRAPHIC_CHAR | ESCAPED_CHAR
  64.  *    GRAPHIC_CHAR  ::= locale (codeset) dependent code
  65.  *    ESCAPED_CHAR  ::= ('\\' | '\"' | OCTAL | HEX )
  66.  *    OCTAL         ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]]
  67.  *    OCTAL_CHAR    ::= (0|1|2|3|4|5|6|7)
  68.  *    HEX           ::= '\' (x|X) HEX_CHAR [HEX_CHAR]]
  69.  *    HEX_CHAR      ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f)
  70.  *
  71.  */
  72.  
  73. static int
  74. nextch(fp, lastch)
  75.     FILE *fp;
  76.     int *lastch;
  77. {
  78.     int c;
  79.  
  80.     if (*lastch != 0) {
  81.     c = *lastch;
  82.     *lastch = 0;
  83.     } else {
  84.     c = getc(fp);
  85.     if (c == '\\') {
  86.         c = getc(fp);
  87.         if (c == '\n') {
  88.         c = getc(fp);
  89.         } else {
  90.         ungetc(c, fp);
  91.         c = '\\';
  92.         }
  93.     }
  94.     }
  95.     return(c);
  96. }
  97.  
  98. static void
  99. putbackch(c, lastch)
  100.     int c;
  101.     int *lastch;
  102. {
  103.     *lastch = c;
  104. }
  105.  
  106. #define ENDOFFILE 0
  107. #define ENDOFLINE 1
  108. #define COLON 2
  109. #define LESS 3
  110. #define GREATER 4
  111. #define EXCLAM 5
  112. #define TILDE 6
  113. #define STRING 7
  114. #define KEY 8
  115. #define ERROR 9
  116.  
  117. #define MAXSTRLEN 100
  118.  
  119. #ifndef isalnum
  120. #define isalnum(c)      \
  121.     (('0' <= (c) && (c) <= '9')  || \
  122.      ('A' <= (c) && (c) <= 'Z')  || \
  123.      ('a' <= (c) && (c) <= 'z'))
  124. #endif
  125.  
  126. static int
  127. nexttoken(fp, tokenbuf, lastch)
  128.     FILE *fp;
  129.     char *tokenbuf;
  130.     int *lastch;
  131. {
  132.     int c;
  133.     int token;
  134.     char *p;
  135.     int i, j;
  136.  
  137. #define CHECKBUF() if (p - tokenbuf >= MAXSTRLEN - 1) return ERROR; else
  138.  
  139.     while ((c = nextch(fp, lastch)) == ' ' || c == '\t') {
  140.     }
  141.     switch (c) {
  142.       case EOF:
  143.     token = ENDOFFILE;
  144.     break;
  145.       case '\n':
  146.     token = ENDOFLINE;
  147.     break;
  148.       case '<':
  149.     token = LESS;
  150.     break;
  151.       case '>':
  152.     token = GREATER;
  153.     break;
  154.       case ':':
  155.     token = COLON;
  156.     break;
  157.       case '!':
  158.     token = EXCLAM;
  159.     break;
  160.       case '~':
  161.     token = TILDE;
  162.     break;
  163.       case '"':
  164.     p = tokenbuf;
  165.     while ((c = nextch(fp, lastch)) != '"') {
  166.         if (c == '\n' || c == EOF) {
  167.         putbackch(c, lastch);
  168.         token = ERROR;
  169.         goto string_error;
  170.         } else if (c == '\\') {
  171.         c = nextch(fp, lastch);
  172.         switch (c) {
  173.           case '\\':
  174.           case '"':
  175.             CHECKBUF();
  176.             *p++ = c;
  177.             break;
  178.           case '0':
  179.           case '1':
  180.           case '2':
  181.           case '3':
  182.           case '4':
  183.           case '5':
  184.           case '6':
  185.           case '7':
  186.             i = c - '0';
  187.             c = nextch(fp, lastch);
  188.             for (j = 0; j < 2 && c >= '0' && c <= '7'; j++) {
  189.             i <<= 3;
  190.             i += c - '0';
  191.             c = nextch(fp, lastch);
  192.             }
  193.             putbackch(c, lastch);
  194.             CHECKBUF();
  195.             *p++ = (char)i;
  196.             break;
  197.           case 'X':
  198.           case 'x':
  199.             i = 0;
  200.             c = nextch(fp, lastch);
  201. #define ishexch(c) (((c) >= '0' && (c) <= '9') || \
  202.             ((c) >= 'A' && (c) <= 'F') || \
  203.             ((c) >= 'a' && (c) <= 'f'))
  204.             for (j = 0; j < 2 && ishexch(c); j++) {
  205.             i <<= 4;
  206.             if (c >= '0' && c <= '9') {
  207.                 i += c - '0';
  208.             } else if (c >= 'A' && c <= 'F') {
  209.                 i += c - 'A' + 10;
  210.             } else {
  211.                 i += c - 'a' + 10;
  212.             }
  213.             c = nextch(fp, lastch);
  214.             }
  215.             if (j == 0) {
  216.                 token = ERROR;
  217.                 goto string_error;
  218.             }
  219.             putbackch(c, lastch);
  220.             CHECKBUF();
  221.             *p++ = (char)i;
  222. #undef ishexch
  223.             break;
  224.           case '\n':
  225.           case EOF:
  226.             putbackch(c, lastch);
  227.             token = ERROR;
  228.             goto string_error;
  229.           default:
  230.             CHECKBUF();
  231.             *p++ = c;
  232.             break;
  233.         }
  234.         } else {
  235.         CHECKBUF();
  236.         *p++ = c;
  237.         }
  238.     }
  239.     *p = '\0';
  240.     token = STRING;
  241.     break;
  242.       case '#':
  243.     while ((c = nextch(fp, lastch)) != '\n' && c != EOF) {
  244.     }
  245.     if (c == '\n') {
  246.         token = ENDOFLINE;
  247.     } else {
  248.         token = ENDOFFILE;
  249.     }
  250.     break;
  251.       default:
  252.     if (isalnum(c) || c == '_' || c == '-') {
  253.         p = tokenbuf;
  254.         CHECKBUF();
  255.         *p++ = c;
  256.         c = nextch(fp, lastch);
  257.         while (isalnum(c) || c == '_' || c == '-') {
  258.         CHECKBUF();
  259.         *p++ = c;
  260.         c = nextch(fp, lastch);
  261.         }
  262.         *p = '\0';
  263.         putbackch(c, lastch);
  264.         token = KEY;
  265.     } else {
  266.         token = ERROR;
  267.     }
  268.     break;
  269.     }
  270. string_error:
  271.     return(token);
  272. }
  273.  
  274. static long
  275. modmask(name)
  276.     char *name;
  277. {
  278.     long mask;
  279.  
  280.     struct _modtbl {
  281.     char *name;
  282.     long mask;
  283.     };
  284.     struct _modtbl *p;
  285.  
  286.     static struct _modtbl tbl[] = {
  287.     { "Ctrl",    ControlMask    },
  288.         { "Lock",    LockMask    },
  289.         { "Caps",    LockMask    },
  290.         { "Shift",    ShiftMask    },
  291.         { "Alt",    Mod1Mask    },
  292.         { "Meta",    Mod1Mask    },
  293.         { NULL,        0        }};
  294.  
  295.     p = tbl;
  296.     mask = 0;
  297.     for (p = tbl; p->name != NULL; p++) {
  298.     if (strcmp(name, p->name) == 0) {
  299.         mask = p->mask;
  300.         break;
  301.     }
  302.     }
  303.     return(mask);
  304. }
  305.  
  306. #define AllMask (ShiftMask | LockMask | ControlMask | Mod1Mask) 
  307. #define LOCAL_WC_BUFSIZE 128
  308. #define SEQUENCE_MAX    10
  309.  
  310. static int
  311. parseline(fp, top, tokenbuf, lastch)
  312.     FILE *fp;
  313.     DefTree **top;
  314.     char *tokenbuf;
  315.     int *lastch;
  316. {
  317.     int token;
  318.     unsigned modifier_mask;
  319.     unsigned modifier;
  320.     unsigned tmp;
  321.     KeySym keysym = NoSymbol;
  322.     DefTree *p;
  323.     Bool exclam, tilde;
  324.     KeySym rhs_keysym;
  325.     char *rhs_string_mb;
  326.     int l;
  327.     wchar_t local_wc_buf[LOCAL_WC_BUFSIZE], *rhs_string_wc;
  328.  
  329.     struct DefBuffer {
  330.     unsigned modifier_mask;
  331.     unsigned modifier;
  332.     KeySym keysym;
  333.     };
  334.  
  335.     struct DefBuffer buf[SEQUENCE_MAX];
  336.     int i, n;
  337.  
  338.     do {
  339.     token = nexttoken(fp, tokenbuf, lastch);
  340.     } while (token == ENDOFLINE);
  341.     
  342.     if (token == ENDOFFILE) {
  343.     return(-1);
  344.     }
  345.  
  346.     n = 0;
  347.     do {
  348.     if ((token == KEY) && (strcmp("None", tokenbuf) == 0)) {
  349.         modifier = 0;
  350.         modifier_mask = AllMask;
  351.         token = nexttoken(fp, tokenbuf, lastch);
  352.     } else {
  353.         modifier_mask = modifier = 0;
  354.         exclam = False;
  355.         if (token == EXCLAM) {
  356.         exclam = True;
  357.         token = nexttoken(fp, tokenbuf, lastch);
  358.         }
  359.         while (token == TILDE || token == KEY) {
  360.         tilde = False;
  361.         if (token == TILDE) {
  362.             token = nexttoken(fp, tokenbuf, lastch);
  363.             tilde = True;
  364.             if (token != KEY)
  365.             goto error;
  366.         }
  367.         token = nexttoken(fp, tokenbuf, lastch);
  368.         tmp = modmask(tokenbuf);
  369.         if (!tmp) {
  370.             goto error;
  371.         }
  372.         modifier_mask |= tmp;
  373.         if (tilde) {
  374.             modifier &= ~tmp;
  375.         } else {
  376.             modifier |= tmp;
  377.         }
  378.         }
  379.         if (exclam) {
  380.         modifier_mask = AllMask;
  381.         }
  382.     }
  383.  
  384.     if (token != LESS) {
  385.         goto error;
  386.     }
  387.  
  388.     token = nexttoken(fp, tokenbuf, lastch);
  389.     if (token != KEY) {
  390.         goto error;
  391.     }
  392.  
  393.     token = nexttoken(fp, tokenbuf, lastch);
  394.     if (token != GREATER) {
  395.         goto error;
  396.     }
  397.  
  398.     keysym = XStringToKeysym(tokenbuf);
  399.     if (keysym == NoSymbol) {
  400.         goto error;
  401.     }
  402.  
  403.     buf[n].keysym = keysym;
  404.     buf[n].modifier = modifier;
  405.     buf[n].modifier_mask = modifier_mask;
  406.     n++;
  407.     if( n >= SEQUENCE_MAX )
  408.         goto error;
  409.     token = nexttoken(fp, tokenbuf, lastch);
  410.     } while (token != COLON);
  411.  
  412.     token = nexttoken(fp, tokenbuf, lastch);
  413.     if (token == STRING) {
  414.     if( (rhs_string_mb = Xmalloc(strlen(tokenbuf) + 1)) == NULL )
  415.         goto error;
  416.     strcpy(rhs_string_mb, tokenbuf);
  417.     token = nexttoken(fp, tokenbuf, lastch);
  418.     if (token == KEY) {
  419.         rhs_keysym = XStringToKeysym(tokenbuf);
  420.         if (rhs_keysym == NoSymbol) {
  421.         Xfree(rhs_string_mb);
  422.         goto error;
  423.         }
  424.         token = nexttoken(fp, tokenbuf, lastch);
  425.     }
  426.     if (token != ENDOFLINE && token != ENDOFFILE) {
  427.         Xfree(rhs_string_mb);
  428.         goto error;
  429.     }
  430.     } else if (token == KEY) {
  431.     rhs_keysym = XStringToKeysym(tokenbuf);
  432.     if (rhs_keysym == NoSymbol) {
  433.         goto error;
  434.     }
  435.     token = nexttoken(fp, tokenbuf, lastch);
  436.     if (token != ENDOFLINE && token != ENDOFFILE) {
  437.         goto error;
  438.     }
  439.     if( (rhs_string_mb = Xmalloc(1)) == NULL ) {
  440.         Xfree( rhs_string_mb );
  441.         goto error;
  442.     }
  443.     rhs_string_mb[0] = '\0';
  444.     } else {
  445.     goto error;
  446.     }
  447.  
  448.     l = _Xmbstowcs(local_wc_buf, rhs_string_mb, LOCAL_WC_BUFSIZE - 1);
  449.     if (l == LOCAL_WC_BUFSIZE - 1) {
  450.     local_wc_buf[l] = (wchar_t)'\0';
  451.     }
  452.     if( (rhs_string_wc = (wchar_t *)Xmalloc((l + 1) * sizeof(wchar_t))) == NULL ) {
  453.     Xfree( rhs_string_mb );
  454.     return( 0 );
  455.     }
  456.     memcpy((char *)rhs_string_wc, (char *)local_wc_buf, (l + 1) * sizeof(wchar_t) );
  457.  
  458.     for (i = 0; i < n; i++) {
  459.     for (p = *top; p; p = p->next) {
  460.         if (buf[i].keysym        == p->keysym &&
  461.         buf[i].modifier      == p->modifier &&
  462.         buf[i].modifier_mask == p->modifier_mask) {
  463.         break;
  464.         }
  465.     }
  466.     if (p) {
  467.         top = &p->succession;
  468.     } else {
  469.         if( (p = (DefTree*)Xmalloc(sizeof(DefTree))) == NULL ) {
  470.         Xfree( rhs_string_mb );
  471.         goto error;
  472.         }
  473.         p->keysym        = buf[i].keysym;
  474.         p->modifier      = buf[i].modifier;
  475.         p->modifier_mask = buf[i].modifier_mask;
  476.         p->succession    = NULL;
  477.         p->next          = *top;
  478.         p->mb            = NULL;
  479.         p->wc            = NULL;
  480.         p->ks            = NoSymbol;
  481.         *top = p;
  482.         top = &p->succession;
  483.     }
  484.     }
  485.  
  486.     if( p->mb != NULL )
  487.     Xfree( p->mb );
  488.     p->mb = rhs_string_mb;
  489.     if( p->wc != NULL )
  490.     Xfree( p->wc );
  491.     p->wc = rhs_string_wc;
  492.     p->ks = rhs_keysym;
  493.     return(n);
  494. error:
  495.     while (token != ENDOFLINE && token != ENDOFFILE) {
  496.     token = nexttoken(fp, tokenbuf, lastch);
  497.     }
  498.     return(0);
  499. }
  500.  
  501. int
  502. XimParseStringFile(fp, ptop)
  503.     FILE *fp;
  504.     DefTree **ptop;
  505. {
  506.     int max_ev_seq = 0, i;
  507.     char tokenbuf[MAXSTRLEN];
  508.     int lastch = 0;
  509.  
  510.     while ((i = parseline(fp, ptop, tokenbuf, &lastch)) >= 0) {
  511.     if (i > max_ev_seq) max_ev_seq = i;
  512.     }
  513.     return (max_ev_seq);
  514. }
  515.