home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / KEYMAP / READMAP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-23  |  17.9 KB  |  366 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <math.h>
  5. #include <malloc.h>
  6. #include <string.h>
  7.  
  8. #include "vskeys.h"
  9.  
  10. #define MAX_LINE_LENGTH        160
  11.  
  12. typedef unsigned char byte;
  13. typedef unsigned int uint;
  14.  
  15. static void read_keyboard_file(char *key_file);
  16. static char *parse_str(char *file_str,uint *ret_code);
  17. static int parse_verb(char *verb_str,uint *ret_code);
  18.  
  19. static char white_sp[]="\x009\x00a\x00b\x00c\x00d\x020";    /* string which contains all the white space characters */
  20. static char end_token[]="\x000\x009\x00a\x00b\x00c\x00d\x020};";    /* string which contains all the white space characters, and the right curley brace & the semi-colon */
  21.  
  22. static int parse_verb(char *verb_str,uint *ret_code)
  23. {
  24.     if(!strnicmp(verb_str,"null",4)) {        /* check for sending NULL (0) character */
  25.         *ret_code=0;        /* indicate NULL character */
  26.         return(4);            /* indicate the number of characters to skip */
  27.       }    /* end if */
  28.     else if(!strnicmp(verb_str,"gold",4)) {    /* check for vt102 function key f1 */
  29.         *ret_code=VSF1;        /* indicate f1 character */
  30.         return(4);            /* indicate the number of characters to skip */
  31.       }    /* end if */
  32.     else if(!strnicmp(verb_str,"pf1",3)) {    /* check for vt102 function key f1 */
  33.         *ret_code=VSF1;        /* indicate f1 character */
  34.         return(3);            /* indicate the number of characters to skip */
  35.       }    /* end if */
  36.     else if(!strnicmp(verb_str,"pf2",3)) {    /* check for vt102 function key f2 */
  37.         *ret_code=VSF2;        /* indicate f2 character */
  38.         return(3);            /* indicate the number of characters to skip */
  39.       }    /* end if */
  40.     else if(!strnicmp(verb_str,"pf3",3)) {    /* check for vt102 function key f3 */
  41.         *ret_code=VSF3;        /* indicate f3 character */
  42.         return(3);            /* indicate the number of characters to skip */
  43.       }    /* end if */
  44.     else if(!strnicmp(verb_str,"pf4",3)) {    /* check for vt102 function key f4 */
  45.         *ret_code=VSF4;        /* indicate f4 character */
  46.         return(3);            /* indicate the number of characters to skip */
  47.       }    /* end if */
  48.     else if(!strnicmp(verb_str,"kp0",3)) {    /* check for vt102 keypad numeric keys */
  49.         *ret_code=VSK0;        /* indicate keypad character */
  50.         return(3);            /* indicate the number of characters to skip */
  51.       }    /* end if */
  52.     else if(!strnicmp(verb_str,"kp1",3)) {    /* check for vt102 keypad numeric keys */
  53.         *ret_code=VSK1;        /* indicate keypad character */
  54.         return(3);            /* indicate the number of characters to skip */
  55.       }    /* end if */
  56.     else if(!strnicmp(verb_str,"kp2",3)) {    /* check for vt102 keypad numeric keys */
  57.         *ret_code=VSK2;        /* indicate keypad character */
  58.         return(3);            /* indicate the number of characters to skip */
  59.       }    /* end if */
  60.     else if(!strnicmp(verb_str,"kp3",3)) {    /* check for vt102 keypad numeric keys */
  61.         *ret_code=VSK3;        /* indicate keypad character */
  62.         return(3);            /* indicate the number of characters to skip */
  63.       }    /* end if */
  64.     else if(!strnicmp(verb_str,"kp4",3)) {    /* check for vt102 keypad numeric keys */
  65.         *ret_code=VSK4;        /* indicate keypad character */
  66.         return(3);            /* indicate the number of characters to skip */
  67.       }    /* end if */
  68.     else if(!strnicmp(verb_str,"kp5",3)) {    /* check for vt102 keypad numeric keys */
  69.         *ret_code=VSK5;        /* indicate keypad character */
  70.         return(3);            /* indicate the number of characters to skip */
  71.       }    /* end if */
  72.     else if(!strnicmp(verb_str,"kp6",3)) {    /* check for vt102 keypad numeric keys */
  73.         *ret_code=VSK6;        /* indicate keypad character */
  74.         return(3);            /* indicate the number of characters to skip */
  75.       }    /* end if */
  76.     else if(!strnicmp(verb_str,"kp7",3)) {    /* check for vt102 keypad numeric keys */
  77.         *ret_code=VSK7;        /* indicate keypad character */
  78.         return(3);            /* indicate the number of characters to skip */
  79.       }    /* end if */
  80.     else if(!strnicmp(verb_str,"kp8",3)) {    /* check for vt102 keypad numeric keys */
  81.         *ret_code=VSK8;        /* indicate keypad character */
  82.         return(3);            /* indicate the number of characters to skip */
  83.       }    /* end if */
  84.     else if(!strnicmp(verb_str,"kp9",3)) {    /* check for vt102 keypad numeric keys */
  85.         *ret_code=VSK9;        /* indicate keypad character */
  86.         return(3);            /* indicate the number of characters to skip */
  87.       }    /* end if */
  88.     else if(!strnicmp(verb_str,"kpdot",5)) {    /* check for other vt102 keypad keys */
  89.         *ret_code=VSKP;        /* indicate keypad character */
  90.         return(5);            /* indicate the number of characters to skip */
  91.       }    /* end if */
  92.     else if(!strnicmp(verb_str,"kpminus",7)) {    /* check for other vt102 keypad keys */
  93.         *ret_code=VSKM;        /* indicate keypad character */
  94.         return(7);            /* indicate the number of characters to skip */
  95.       }    /* end if */
  96.     else if(!strnicmp(verb_str,"kpcoma",6)) {    /* check for other vt102 keypad keys */
  97.         *ret_code=VSKC;        /* indicate keypad character */
  98.         return(6);            /* indicate the number of characters to skip */
  99.       }    /* end if */
  100.     else if(!strnicmp(verb_str,"kpenter",7)) {    /* check for other vt102 keypad keys */
  101.         *ret_code=VSKE;        /* indicate keypad character */
  102.         return(7);            /* indicate the number of characters to skip */
  103.       }    /* end if */
  104.     else if(!strnicmp(verb_str,"uparr",5)) {    /* check for vt102 cursor (arrow) keys */
  105.         *ret_code=VSUP;        /* indicate cursor key */
  106.         return(5);            /* indicate the number of characters to skip */
  107.       }    /* end if */
  108.     else if(!strnicmp(verb_str,"dnarr",5)) {    /* check for vt102 cursor (arrow) keys */
  109.         *ret_code=VSDN;        /* indicate cursor key */
  110.         return(5);            /* indicate the number of characters to skip */
  111.       }    /* end if */
  112.     else if(!strnicmp(verb_str,"lfarr",5)) {    /* check for vt102 cursor (arrow) keys */
  113.         *ret_code=VSLT;        /* indicate cursor key */
  114.         return(5);            /* indicate the number of characters to skip */
  115.       }    /* end if */
  116.     else if(!strnicmp(verb_str,"rtarr",5)) {    /* check for vt102 cursor (arrow) keys */
  117.         *ret_code=VSRT;        /* indicate cursor key */
  118.         return(5);            /* indicate the number of characters to skip */
  119.       }    /* end if */
  120.     else {            /* indicate that we recognize this kermit verb */
  121.         *ret_code=0xFFFF;        /* indicate that we don't recognize this verb */
  122.         return(strcspn(verb_str,end_token));    /* return the number of characters to skip */
  123.       }    /* end else */
  124. }    /* end parse_verb() */
  125.  
  126. static char *parse_str(char *file_str,uint *ret_code)
  127. {
  128.     int buff_off=0,            /* current location in the buffer */
  129.         ascii_num,            /* ascii character encoded after a backslash */
  130.         kermit_length,        /* the length of a kermit verb returned from parsing it */
  131.         done=0;                /* flag for dropping out of the loop */
  132.     byte *ret_str,            /* the string variable to return the result in */
  133.         *temp_str,            /* pointer to the current place in the string */
  134.         buffer[MAX_LINE_LENGTH];        /* buffer to store the string we are unravelling */
  135.  
  136.     *ret_code=0xFFFF;        /* mark return code to indicate nothing special to return */
  137.     temp_str=file_str;        /* start at the beginning of the string to parse */
  138.     while((*temp_str)!='\0' && buff_off<MAX_LINE_LENGTH && !done) {        /* parse until the end of the string or until the buffer is full */
  139.         while((*temp_str) && (*temp_str)!=';' && (*temp_str)!='\\' && (*temp_str)!='{' && (*temp_str)>' ') {    /* copy regular characters until a special one is hit */
  140.             buffer[buff_off]=(*temp_str);        /* copy the character */
  141.             buff_off++;        /* increment the position in the buffer */
  142.             temp_str++;        /* increment the position in the parse string */
  143.           }    /* end while */
  144.         if(*temp_str) {        /* check on the various special cases for dropping out of the loop */
  145.             switch(*temp_str) {        /* switch for the special case */
  146.                 case '\\':    /* backslash for escape coding a character */
  147.                     temp_str++;        /* get the character after the backslash */
  148.                     if((*temp_str)=='{') {    /* check for curly brace around numbers */
  149.                         temp_str++;    /* increment to the next character */
  150.                         if((*temp_str)=='K' || (*temp_str)=='k') {        /* check for Kermit escape code here also */
  151.                             temp_str++;        /* increment past the kermit flag */
  152.                             kermit_length=parse_verb(temp_str,ret_code);        /* parse the kermit verb, and return the correct kermit code in the ret_code */
  153.                             if(*ret_code!=0xFFFF)        /* a kermit verb was specified that we recognize */
  154.                                 return(NULL);        /* return now, indicating a kermit verb we recognize in the ret_code variable */
  155.                             temp_str+=kermit_length;    /* increment past the kermit verb */
  156.                             if((*temp_str)=='}')    /* found the closing curly brace */
  157.                                 temp_str++;        /* jump over the closing curly brace */
  158.                             else {        /* closing curly brace missing, indicate error */
  159.                                 buff_off=0;
  160.                                 done=1;
  161.                               }    /* end else */
  162.                           }    /* end if */
  163.                         else {        /* must be an escape integer */
  164.                             ascii_num=atoi(temp_str);    /* get the ascii number after the escape code */
  165.                             buffer[buff_off]=(byte)ascii_num;    /* store the ascii code in the buffer */
  166.                             buff_off++;                /* increment our position */
  167.                             if(ascii_num<10)        /* increment the parsing string once for numbers under ten */
  168.                                 temp_str++;
  169.                             else if(ascii_num<100)    /* increment twice for numbers under 100 */
  170.                                 temp_str+=2;
  171.                             else if(ascii_num<1000)    /* increment thrice for numbers under 1000 */
  172.                                 temp_str+=3;
  173.                             else if(ascii_num<10000)    /* increment four times for numbers under 10000 (I know it should happen, but why take chances) */
  174.                                 temp_str+=4;
  175.                             else        /* final, impossible case */
  176.                                 temp_str+=5;
  177.                             if((*temp_str)=='}')    /* found the closing curly brace */
  178.                                 temp_str++;        /* jump over the closing curly brace */
  179.                             else {        /* closing curly brace missing, indicate error */
  180.                                 buff_off=0;
  181.                                 done=1;
  182.                               }    /* end else */
  183.                           }    /* end else */
  184.                       }    /* end if */
  185.                     else if((*temp_str)=='K' || (*temp_str)=='k') {        /* check for Kermit escape code */
  186.                         temp_str++;        /* increment past the kermit flag */
  187.                         kermit_length=parse_verb(temp_str,ret_code);        /* parse the kermit verb, and return the correct kermit code in the ret_code */
  188.                         if(*ret_code!=0xFFFF)        /* a kermit verb was specified that we recognize */
  189.                             return(NULL);        /* return now, indicating a kermit verb we recognize in the ret_code variable */
  190.                         temp_str+=kermit_length;    /* increment past the kermit verb */
  191.                       }    /* end if */
  192.                     else {        /* must be an escape integer */
  193.                         ascii_num=atoi(temp_str);    /* get the ascii number after the escape flag */
  194.                         buffer[buff_off]=(byte)ascii_num;    /* store the ascii code in the buffer */
  195.                         buff_off++;                /* increment our position */
  196.                         if(ascii_num<10)        /* increment the parsing string once for numbers under ten */
  197.                             temp_str++;
  198.                         else if(ascii_num<100)    /* increment twice for numbers under 100 */
  199.                             temp_str+=2;
  200.                         else if(ascii_num<1000)    /* increment thrice for numbers under 1000 */
  201.                             temp_str+=3;
  202.                         else if(ascii_num<10000)    /* increment four times for numbers under 10000 (I know it should happen, but why take chances) */
  203.                             temp_str+=4;
  204.                         else        /* final, impossible case */
  205.                             temp_str+=5;
  206.                       }    /* end else */
  207.                     break;
  208.  
  209.                 case '{':    /* curly brace opens a quoted string */
  210.                     temp_str++;        /* jump over the brace itself */
  211.                     while((*temp_str) && (*temp_str)!='}') {    /* copy regular characters until a special one is hit */
  212.                         buffer[buff_off]=(*temp_str);        /* copy the character */
  213.                         buff_off++;        /* increment the position in the buffer */
  214.                         temp_str++;        /* increment the position in the parse string */
  215.                       }    /* end while */
  216.                     if((*temp_str)=='}')        /* found the closing brace */
  217.                         temp_str++;        /* jump over the closing brace */
  218.                     else {        /* line terminated without closing brace */
  219.                         buff_off=0;        /* indicate error condition */
  220.                         done=1;            /* drop out of the loop */
  221.                       }    /* end else */
  222.                     break;
  223.  
  224.                 default:    /* ctrl character, space, & semi-colon terminate string */
  225. #ifdef OLD_WAY
  226.                 case ' ':    /* space should end the parsing input */
  227.                 case ';':    /* so should semi-colon */
  228. #endif
  229.                     buffer[buff_off]='\0';    /* terminate the string */
  230.                     done=1;
  231.                     break;
  232.  
  233.               }    /* end switch */
  234.           }    /* end if */
  235.         else
  236.             buffer[buff_off]='\0';    /* terminate the string */
  237.       }    /* end while */
  238.     if(buff_off>0) {
  239.         ret_str=malloc(buff_off+1);
  240.         strcpy(ret_str,buffer);        /* copy the parsed string */
  241.         return(ret_str);
  242.       }    /* end if */
  243.     return(NULL);
  244. }    /* end parse_str() */
  245.  
  246. static void read_keyboard_file(char *key_file)
  247. {
  248.     FILE *key_fp;            /* pointer to the keyboard file */
  249.     char key_line[MAX_LINE_LENGTH],        /* static array to store lines read from keyboard file */
  250.         *map_str,            /* the parsed string from the keyboard file */
  251.         *temp_str,*temp_2str;    /* temporary pointer to a string */
  252.     uint line_no=0,            /* what line in the file we are on */
  253.         token_num,            /* the current token we are parsing */
  254.         where,                /* pointer to the beginning of text */
  255.         kermit_code,        /* the variable to return the possible 'kermit verb' code in */
  256.         re_map_key;            /* the key to re-map */
  257.  
  258.     if((key_fp=fopen(key_file,"rt"))!=NULL) {
  259.         while((temp_str=fgets(key_line,MAX_LINE_LENGTH,key_fp))!=NULL) {    /* get a line of input */
  260.             printf("\nline:%d, '%s\n",line_no,key_line);        /* print the line we just read */
  261.             token_num=0;            /* initialize the token we are on */
  262.             if((temp_str=strtok(key_line,white_sp))!=NULL) {    /* get the first token from the string */
  263.                 printf("first token=%s\n",temp_str);
  264.                 if((*temp_str)!=';') {        /* check for a comment line */
  265.                     do {
  266.                         printf("token #%d: '%s'\n",token_num,temp_str);
  267.                         switch(token_num) {        /* switch on which token we are processing */
  268.                             case 0:        /* the 'SET' token (we already know it is not a comment) */
  269.                                 if(strcmp(temp_str,"SET") && strcmp(temp_str,"set")) {    /* make certain the first token is a SET token */
  270.                                     printf("invalid token #%d:'%s' on line %d\n",token_num,temp_str,line_no);
  271.                                     token_num=4;    /* bump the token count up to drop out of the loop */
  272.                                   }    /* end if */
  273.                                 break;
  274.  
  275.                             case 1:        /* the 'KEY' token */
  276.                                 if(strcmp(temp_str,"KEY") && strcmp(temp_str,"key")) {    /* make certain the first token is a KEY token */
  277.                                     printf("invalid token #%d:'%s' on line %d\n",token_num,temp_str,line_no);
  278.                                     token_num=4;    /* bump the token count up to drop out of the loop */
  279.                                   }    /* end if */
  280.                                 break;
  281.  
  282.                             case 2:        /* the key to be re-mapped */
  283.                                 if(!strcmp(temp_str,"CLEAR") || !strcmp(temp_str,"OFF") || !strcmp(temp_str,"ON") || (*temp_str)==';') {    /* ignore the rest of the line if the 'key' is one of the tokens we don't support */
  284.                                     token_num=4;    /* bump the token count up to drop out of the loop */
  285.                                   }    /* end if */
  286.                                 else {        /* the 'key' field is not a special command or a comment, must be a valid character */
  287.                                     if(*(temp_str)!='\\') {    /* the key to re-map is not an escape code */
  288.                                         re_map_key=*temp_str;    /* set the re-mapping key */
  289.                                       }    /* end if */
  290.                                     else {
  291.                                         re_map_key=atoi(temp_str+1);    /* get the re-mapping key value from the string */
  292.                                         if(re_map_key==0) {        /* invalid key code */
  293.                                             printf("Error, invalid key code:%s, on line %d\n",temp_str,line_no);
  294.                                             token_num=4;    /* bump the token count up to drop out of the loop */
  295.                                           }    /* end if */
  296.                                         else {
  297.                                             printf("Key code to re-map=%d\n",re_map_key);
  298.                                           }    /* end else */
  299.                                       }    /* end else */
  300.                                   }    /* end else */
  301.                                 break;
  302.  
  303.                             case 3:        /* the string to re-map the key to */
  304.                                 if((*temp_str)==';') {    /* ignore the rest of the line if the 'key' is one of the tokens we don't support */
  305.                                     printf("Resetting definition for %d on line %d\n",re_map_key,line_no);
  306.                                     token_num=4;    /* bump the token count up to drop out of the loop */
  307.                                   }    /* end if */
  308.                                 else {
  309.                                     if((map_str=parse_str(temp_str,&kermit_code))!=NULL) {        /* parse the re-mapping string */
  310.                                         printf("parsed string=");
  311.                                         temp_2str=map_str;
  312.                                         while(!isprint(*temp_2str) && (*temp_2str)!='\0') {
  313.                                             printf("\\%d",(int)*temp_2str);
  314.                                             temp_2str++;
  315.                                           }    /* end while */
  316.                                         printf("%s\n",temp_2str);
  317.                                         free((char *)map_str);
  318.                                       }    /* end if */
  319.                                     else {
  320.                                         if(kermit_code!=0xFFFF) {    /* check for special kermit verb returned */
  321.                                             printf("Kermit code:%u, on line %d\n",kermit_code,line_no);
  322.                                           }    /* end if */
  323.                                         else {
  324.                                             printf("Error, re-mapping string:%s invalid on line %d\n",temp_str,line_no);
  325.                                             token_num=4;    /* bump the token count up to drop out of the loop */
  326.                                           }    /* end else */
  327.                                       }    /* end else */
  328.                                   }    /* end else */
  329.                                 break;
  330.                           }    /* end switch */
  331.                         token_num++;
  332.                         if(token_num<3)        /* if the next token is not the last one, then grab it */
  333.                             temp_str=strtok(NULL,white_sp);        /* get the next token */
  334.                         else if(token_num==3) {        /* for the last 'token' (after the remapping key to the end of the line), just get the next character in the line */
  335.                             temp_str+=(strlen(temp_str)+1);        /* jump over the previous token */
  336.                             where=strspn(temp_str,white_sp);    /* look for the first non-white space in the line */
  337.                             temp_str+=where;    /* jump to the first position with a character */
  338.                             if(where==0)
  339.                                 printf("*temp_str=%d\n",(int)*temp_str);
  340.                             if(!isgraph(*temp_str)) {        /* not more characters in the line */
  341.                                 printf("Truncated line, Resetting definition for %d on line %d\n",re_map_key,line_no);
  342.                                 token_num=4;    /* bump the token count to drop out of the loop */
  343.                               }    /* end if */
  344.                           }    /* end if */
  345.                       }    while(temp_str!=NULL && token_num<4);
  346.                   }    /* end if */
  347.                 else {
  348.                     printf("Whole line is a comment\n");
  349.                   }    /* end else */
  350.               }    /* end if */
  351.             line_no++;            /* increment current line */
  352.           }    /* end while */
  353.         fclose(key_fp);
  354.       }    /* end if */
  355. }    /* end read_keyboard_file() */
  356.  
  357. int main(int argc,char *argv[])
  358. {
  359.     if(argc!=2) {
  360.         printf("Usage:\nreadmap keyboard_file\n");
  361.         return(1);
  362.       }    /* end if */
  363.     read_keyboard_file(argv[1]);
  364.     return(0);
  365. }    /* end readmap() */
  366.