static int parse_verb(char *verb_str,uint *ret_code);
static int add_key(unsigned int search_key,char *key_map_str,int is_special,byte special_code);
static int del_key(unsigned int search_key);
/* Local variables */
static char white_sp[]="\x009\x00a\x00b\x00c\x00d\x020"; /* string which contains all the white space characters */
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 */
int buff_off=0, /* current location in the buffer */
ascii_num, /* ascii character encoded after a backslash */
kermit_length, /* the length of a kermit verb returned from parsing it */
done=0; /* flag for dropping out of the loop */
byte *ret_str, /* the string variable to return the result in */
*temp_str, /* pointer to the current place in the string */
buffer[MAX_LINE_LENGTH]; /* buffer to store the string we are unravelling */
*ret_code=0xFFFF; /* mark return code to indicate nothing special to return */
temp_str=file_str; /* start at the beginning of the string to parse */
while((*temp_str)!='\0' && buff_off<MAX_LINE_LENGTH && !done) { /* parse until the end of the string or until the buffer is full */
while((*temp_str) && (*temp_str)!=';' && (*temp_str)!='\\' && (*temp_str)!='{' && (*temp_str)>' ') { /* copy regular characters until a special one is hit */
buffer[buff_off]=(*temp_str); /* copy the character */
buff_off++; /* increment the position in the buffer */
temp_str++; /* increment the position in the parse string */
} /* end while */
if(*temp_str) { /* check on the various special cases for dropping out of the loop */
switch(*temp_str) { /* switch for the special case */
case '\\': /* backslash for escape coding a character */
temp_str++; /* get the character after the backslash */
if((*temp_str)=='{') { /* check for curly brace around numbers */
temp_str++; /* increment to the next character */
if((*temp_str)=='K' || (*temp_str)=='k') { /* check for Kermit escape code here also */
temp_str++; /* increment past the kermit flag */
kermit_length=parse_verb(temp_str,ret_code); /* parse the kermit verb, and return the correct kermit code in the ret_code */
if(*ret_code!=0xFFFF) /* a kermit verb was specified that we recognize */
return(NULL); /* return now, indicating a kermit verb we recognize in the ret_code variable */
temp_str+=kermit_length; /* increment past the kermit verb */
} /* end if */
else if((*temp_str)=='o') { /* check for octal number */
ascii_num=octal_to_int(temp_str); /* get the acii number after the escape code */
buffer[buff_off]=(byte)ascii_num; /* store the ascii code in the buffer */
buff_off++; /* increment our position */
while((*temp_str)>='0' && (*temp_str)<='7') /* increment our position past the digits */
temp_str++;
} /* end if */
else if((*temp_str)=='x') { /* check for hexadecimal number */
ascii_num=hex_to_int(temp_str); /* get the acii number after the escape code */
buffer[buff_off]=(byte)ascii_num; /* store the ascii code in the buffer */
buff_off++; /* increment our position */
while(isxdigit((int)(*temp_str))) /* increment our position past the digits */
temp_str++;
} /* end if */
else { /* must be an escape integer */
if((*temp_str)=='d') /* check for redundant decimal number specification */
temp_str++;
ascii_num=atoi(temp_str); /* get the ascii number after the escape code */
buffer[buff_off]=(byte)ascii_num; /* store the ascii code in the buffer */
buff_off++; /* increment our position */
while(isdigit((int)(*temp_str))) /* increment our position past the digits */
temp_str++;
} /* end else */
if((*temp_str)=='}') /* found the closing curly brace */
temp_str++; /* jump over the closing curly brace */
char key_line[MAX_LINE_LENGTH], /* static array to store lines read from keyboard file */
*map_str, /* the parsed string from the keyboard file */
*temp_str; /* temporary pointer to a string */
uint line_no=0, /* what line in the file we are on */
token_num, /* the current token we are parsing */
where, /* pointer to the beginning of text */
kermit_code, /* the variable to return the possible 'kermit verb' code in */
re_map_key, /* the key to re-map */
error=0; /* error from the file reading */
if((key_fp=fopen(key_file,"rt"))!=NULL) {
while((temp_str=fgets(key_line,MAX_LINE_LENGTH,key_fp))!=NULL && !error) { /* get a line of input */
token_num=0; /* initialize the token we are on */
if((temp_str=strtok(key_line,white_sp))!=NULL) { /* get the first token from the string */
if((*temp_str)!=';') { /* check for a comment line */
do {
switch(token_num) { /* switch on which token we are processing */
case 0: /* the 'SET' token (we already know it is not a comment) */
if(stricmp(temp_str,"SET")) { /* make certain the first token is a SET token */
printf("invalid token #%d:'%s' on line %d\n",token_num,temp_str,line_no);
token_num=4; /* bump the token count up to drop out of the loop */
} /* end if */
break;
case 1: /* the 'KEY' token */
if(stricmp(temp_str,"KEY")) { /* make certain the first token is a KEY token */
printf("invalid token #%d:'%s' on line %d\n",token_num,temp_str,line_no);
token_num=4; /* bump the token count up to drop out of the loop */
} /* end if */
break;
case 2: /* the key to be re-mapped */
if(!stricmp(temp_str,"CLEAR") || !stricmp(temp_str,"OFF") || !stricmp(temp_str,"ON") || (*temp_str)==';') { /* ignore the rest of the line if the 'key' is one of the tokens we don't support */
token_num=4; /* bump the token count up to drop out of the loop */
} /* end if */
else { /* the 'key' field is not a special command or a comment, must be a valid character */
if(*(temp_str)!='\\') { /* the key to re-map is not an escape code */
re_map_key=*temp_str; /* set the re-mapping key */
} /* end if */
else {
re_map_key=atoi(temp_str+1); /* get the re-mapping key value from the string */
if(re_map_key==0) { /* invalid key code */
printf("Error, invalid key code:%s, on line %d\n",temp_str,line_no);
token_num=4; /* bump the token count up to drop out of the loop */
} /* end if */
} /* end else */
} /* end else */
break;
case 3: /* the string to re-map the key to */
if((*temp_str)==';') { /* ignore the rest of the line if the 'key' is one of the tokens we don't support */
if(IS_KEY_MAPPED(re_map_key)) /* check for the key being already re-mapped */
error=del_key(re_map_key);
token_num=4; /* bump the token count up to drop out of the loop */
} /* end if */
else {
if((map_str=parse_str(temp_str,&kermit_code))!=NULL) { /* parse the re-mapping string */
error=add_key(re_map_key,map_str,0,0); /* add a regular key string to the key mapping list */
free((char *)map_str);
} /* end if */
else {
if(kermit_code!=0xFFFF) { /* check for special kermit verb returned */
error=add_key(re_map_key,NULL,1,(byte)kermit_code); /* add a kermit code to the list */
} /* end if */
else {
if(IS_KEY_MAPPED(re_map_key)) /* check for the key being already re-mapped */
error=del_key(re_map_key);
printf("Error, re-mapping string:%s invalid on line %d\n",temp_str,line_no);
token_num=4; /* bump the token count up to drop out of the loop */
} /* end else */
} /* end else */
} /* end else */
break;
} /* end switch */
token_num++;
if(token_num<3) /* if the next token is not the last one, then grab it */
temp_str=strtok(NULL,white_sp); /* get the next token */
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 */
temp_str+=(strlen(temp_str)+1); /* jump over the previous token */
where=strspn(temp_str,white_sp); /* look for the first non-white space in the line */
temp_str+=where; /* jump to the first position with a character */
if(!isgraph(*temp_str)) { /* not more characters in the line */
if(IS_KEY_MAPPED(re_map_key)) /* check for the key being already re-mapped */
error=del_key(re_map_key);
token_num=4; /* bump the token count to drop out of the loop */