cfgscan.c revision 76910425
176910425Smrg/* $Xorg: cfgscan.c,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ */
276910425Smrg/************************************************************
376910425Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
476910425Smrg
576910425Smrg Permission to use, copy, modify, and distribute this
676910425Smrg software and its documentation for any purpose and without
776910425Smrg fee is hereby granted, provided that the above copyright
876910425Smrg notice appear in all copies and that both that copyright
976910425Smrg notice and this permission notice appear in supporting
1076910425Smrg documentation, and that the name of Silicon Graphics not be
1176910425Smrg used in advertising or publicity pertaining to distribution
1276910425Smrg of the software without specific prior written permission.
1376910425Smrg Silicon Graphics makes no representation about the suitability
1476910425Smrg of this software for any purpose. It is provided "as is"
1576910425Smrg without any express or implied warranty.
1676910425Smrg
1776910425Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1876910425Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1976910425Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
2076910425Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2176910425Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2276910425Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2376910425Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
2476910425Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
2576910425Smrg
2676910425Smrg ********************************************************/
2776910425Smrg/* $XFree86: xc/programs/xkbevd/cfgscan.c,v 3.6 2001/01/17 23:46:07 dawes Exp $ */
2876910425Smrg
2976910425Smrg#include <stdio.h>
3076910425Smrg#include <stdlib.h>
3176910425Smrg#include <ctype.h>
3276910425Smrg#include <X11/Xos.h>
3376910425Smrg#include <X11/X.h>
3476910425Smrg#include <X11/extensions/XKB.h>
3576910425Smrg
3676910425Smrg#include "tokens.h"
3776910425Smrg#include "xkbevd.h"
3876910425Smrg
3976910425SmrgFILE	*yyin = NULL;
4076910425Smrg
4176910425Smrgstatic char scanFileBuf[1024];
4276910425Smrgchar *	 scanFile= scanFileBuf;
4376910425Smrgint	 lineNum=	0;
4476910425Smrg
4576910425Smrgint	 scanInt;
4676910425Smrgchar	*scanIntStr;
4776910425Smrgint	 scanIntClass;
4876910425Smrg
4976910425Smrgchar	*scanStr = NULL;
5076910425Smrgint	 scanStrLine=	0;
5176910425Smrg
5276910425Smrg#define	BUFSIZE	512
5376910425Smrgstatic	int	nInBuf = 0;
5476910425Smrgstatic	char	buf[BUFSIZE];
5576910425Smrg
5676910425Smrg#ifdef DEBUG
5776910425Smrg
5876910425Smrgextern	unsigned debugFlags;
5976910425Smrg
6076910425Smrgstatic char *
6176910425SmrgtokText(int tok)
6276910425Smrg{
6376910425Smrgstatic char buf[32];
6476910425Smrg
6576910425Smrg    switch (tok) {
6676910425Smrg	case END_OF_FILE:	sprintf(buf, "END_OF_FILE");break;
6776910425Smrg	case ERROR:		sprintf(buf, "ERROR");	break;
6876910425Smrg
6976910425Smrg	case BELL:		sprintf(buf, "BELL"); break;
7076910425Smrg	case ACCESSX:		sprintf(buf, "ACCESSX"); break;
7176910425Smrg	case MESSAGE:		sprintf(buf, "MESSAGE"); break;
7276910425Smrg
7376910425Smrg	case NONE:		sprintf(buf, "NONE"); break;
7476910425Smrg	case IGNORE:		sprintf(buf, "IGNORE"); break;
7576910425Smrg	case ECHO:		sprintf(buf, "ECHO"); break;
7676910425Smrg	case PRINT_EV:		sprintf(buf, "PRINT_EV"); break;
7776910425Smrg	case SHELL:		sprintf(buf, "SHELL"); break;
7876910425Smrg	case SOUND:		sprintf(buf, "SOUND"); break;
7976910425Smrg
8076910425Smrg	case EQUALS:		sprintf(buf, "EQUALS");	break;
8176910425Smrg	case PLUS:		sprintf(buf, "PLUS");	break;
8276910425Smrg	case MINUS:		sprintf(buf, "MINUS");	break;
8376910425Smrg	case DIVIDE:		sprintf(buf, "DIVIDE");	break;
8476910425Smrg	case TIMES:		sprintf(buf, "TIMES");	break;
8576910425Smrg	case OBRACE:		sprintf(buf, "OBRACE");	break;
8676910425Smrg	case CBRACE:		sprintf(buf, "CBRACE");	break;
8776910425Smrg	case OPAREN:		sprintf(buf, "OPAREN");	break;
8876910425Smrg	case CPAREN:		sprintf(buf, "CPAREN");	break;
8976910425Smrg	case OBRACKET:		sprintf(buf, "OBRACKET");break;
9076910425Smrg	case CBRACKET:		sprintf(buf, "CBRACKET");break;
9176910425Smrg	case DOT:		sprintf(buf, "DOT");	break;
9276910425Smrg	case COMMA:		sprintf(buf, "COMMA");	break;
9376910425Smrg	case SEMI:		sprintf(buf, "SEMI");	break;
9476910425Smrg	case EXCLAM:		sprintf(buf, "EXCLAM");	break;
9576910425Smrg	case INVERT:		sprintf(buf, "INVERT");	break;
9676910425Smrg
9776910425Smrg	case STRING:		sprintf(buf, "STRING (%s)",scanStr);	break;
9876910425Smrg	case INTEGER:		sprintf(buf, "INTEGER (0x%x)",scanInt);	break;
9976910425Smrg	case FLOAT:		sprintf(buf, "FLOAT (%d.%d)",
10076910425Smrg					     scanInt/XkbGeomPtsPerMM,
10176910425Smrg					     scanInt%XkbGeomPtsPerMM);break;
10276910425Smrg	case IDENT:		sprintf(buf, "IDENT (%s)",scanStr);	break;
10376910425Smrg	case KEYNAME:		sprintf(buf, "KEYNAME (%s)",scanStr);	break;
10476910425Smrg	default:		sprintf(buf, "UNKNOWN");	break;
10576910425Smrg    }
10676910425Smrg    return buf;
10776910425Smrg}
10876910425Smrg#endif
10976910425Smrg
11076910425Smrgint
11176910425SmrgsetScanState(char *file, int line)
11276910425Smrg{
11376910425Smrg    if (file!=NULL)
11476910425Smrg	strncpy(scanFile,file,1024);
11576910425Smrg    if (line>=0)
11676910425Smrg	lineNum= line;
11776910425Smrg    return 1;
11876910425Smrg}
11976910425Smrg
12076910425Smrgstatic int
12176910425SmrgyyGetString(void)
12276910425Smrg{
12376910425Smrgint ch;
12476910425Smrg
12576910425Smrg    nInBuf = 0;
12676910425Smrg    while ( ((ch=getc(yyin))!=EOF) && (ch!='"') ) {
12776910425Smrg	if ( ch == '\\' ) {
12876910425Smrg	    if ((ch = getc(yyin))!=EOF) {
12976910425Smrg		if ( ch=='n' )		ch = '\n';
13076910425Smrg		else if ( ch == 't' )	ch = '\t';
13176910425Smrg		else if ( ch == 'v' )	ch = '\v';
13276910425Smrg		else if ( ch == 'b' )	ch = '\b';
13376910425Smrg		else if ( ch == 'r' )	ch = '\r';
13476910425Smrg		else if ( ch == 'f' )	ch = '\f';
13576910425Smrg		else if ( ch == 'e' )	ch = '\033';
13676910425Smrg		else if ( ch == '0' ) {
13776910425Smrg		    int tmp,stop;
13876910425Smrg		    ch = stop = 0;
13976910425Smrg		    if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
14076910425Smrg						(tmp!='8') && (tmp!='9')) {
14176910425Smrg			ch= (ch*8)+(tmp-'0');
14276910425Smrg		    }
14376910425Smrg		    else {
14476910425Smrg			stop= 1;
14576910425Smrg			ungetc(tmp,yyin);
14676910425Smrg		    }
14776910425Smrg		    if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
14876910425Smrg						(tmp!='8') && (tmp!='9')) {
14976910425Smrg			ch= (ch*8)+(tmp-'0');
15076910425Smrg		    }
15176910425Smrg		    else {
15276910425Smrg			stop= 1;
15376910425Smrg			ungetc(tmp,yyin);
15476910425Smrg		    }
15576910425Smrg		    if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
15676910425Smrg						(tmp!='8') && (tmp!='9')) {
15776910425Smrg			ch= (ch*8)+(tmp-'0');
15876910425Smrg		    }
15976910425Smrg		    else {
16076910425Smrg			stop= 1;
16176910425Smrg			ungetc(tmp,yyin);
16276910425Smrg		    }
16376910425Smrg		}
16476910425Smrg	    }
16576910425Smrg	    else return ERROR;
16676910425Smrg	}
16776910425Smrg
16876910425Smrg	if ( nInBuf < BUFSIZE-1 )
16976910425Smrg	    buf[nInBuf++] = ch;
17076910425Smrg    }
17176910425Smrg    if ( ch == '"' ) {
17276910425Smrg	buf[nInBuf++] = '\0';
17376910425Smrg	if  ( scanStr )
17476910425Smrg	    free( scanStr );
17576910425Smrg	scanStr = uStringDup(buf);
17676910425Smrg	scanStrLine = lineNum;
17776910425Smrg	return STRING;
17876910425Smrg    }
17976910425Smrg    return ERROR;
18076910425Smrg}
18176910425Smrg
18276910425Smrgstatic int
18376910425SmrgyyGetKeyName(void)
18476910425Smrg{
18576910425Smrgint ch;
18676910425Smrg
18776910425Smrg    nInBuf = 0;
18876910425Smrg    while ( ((ch=getc(yyin))!=EOF) && (ch!='>') ) {
18976910425Smrg	if ( ch == '\\' ) {
19076910425Smrg	    if ((ch = getc(yyin))!=EOF) {
19176910425Smrg		if ( ch=='n' )		ch = '\n';
19276910425Smrg		else if ( ch == 't' )	ch = '\t';
19376910425Smrg		else if ( ch == 'v' )	ch = '\v';
19476910425Smrg		else if ( ch == 'b' )	ch = '\b';
19576910425Smrg		else if ( ch == 'r' )	ch = '\r';
19676910425Smrg		else if ( ch == 'f' )	ch = '\f';
19776910425Smrg		else if ( ch == 'e' )	ch = '\033';
19876910425Smrg		else if ( ch == '0' ) {
19976910425Smrg		    int tmp,stop;
20076910425Smrg		    ch = stop = 0;
20176910425Smrg		    if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
20276910425Smrg						(tmp!='8') && (tmp!='9')) {
20376910425Smrg			ch= (ch*8)+(tmp-'0');
20476910425Smrg		    }
20576910425Smrg		    else {
20676910425Smrg			stop= 1;
20776910425Smrg			ungetc(tmp,yyin);
20876910425Smrg		    }
20976910425Smrg		    if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
21076910425Smrg						(tmp!='8') && (tmp!='9')) {
21176910425Smrg			ch= (ch*8)+(tmp-'0');
21276910425Smrg		    }
21376910425Smrg		    else {
21476910425Smrg			stop= 1;
21576910425Smrg			ungetc(tmp,yyin);
21676910425Smrg		    }
21776910425Smrg		    if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) &&
21876910425Smrg						(tmp!='8') && (tmp!='9')) {
21976910425Smrg			ch= (ch*8)+(tmp-'0');
22076910425Smrg		    }
22176910425Smrg		    else {
22276910425Smrg			stop= 1;
22376910425Smrg			ungetc(tmp,yyin);
22476910425Smrg		    }
22576910425Smrg		}
22676910425Smrg	    }
22776910425Smrg	    else return ERROR;
22876910425Smrg	}
22976910425Smrg
23076910425Smrg	if ( nInBuf < BUFSIZE-1 )
23176910425Smrg	    buf[nInBuf++] = ch;
23276910425Smrg    }
23376910425Smrg    if (( ch == '>' )&&(nInBuf<5)) {
23476910425Smrg	buf[nInBuf++] = '\0';
23576910425Smrg	if  ( scanStr )
23676910425Smrg	    free( scanStr );
23776910425Smrg	scanStr = uStringDup(buf);
23876910425Smrg	scanStrLine = lineNum;
23976910425Smrg	return KEYNAME;
24076910425Smrg    }
24176910425Smrg    return ERROR;
24276910425Smrg}
24376910425Smrg
24476910425Smrgstruct _Keyword {
24576910425Smrg	char	*keyword;
24676910425Smrg	int	 token;
24776910425Smrg} keywords[] = {
24876910425Smrg    { "bell",			BELL			},
24976910425Smrg    { "accessx",		ACCESSX			},
25076910425Smrg    { "message",		MESSAGE			},
25176910425Smrg    { "none",			NONE			},
25276910425Smrg    { "ignore",			IGNORE			},
25376910425Smrg    { "echo",			ECHO			},
25476910425Smrg    { "printevent",		PRINT_EV		},
25576910425Smrg    { "shell",			SHELL			},
25676910425Smrg    { "sound",			SOUND			}
25776910425Smrg};
25876910425Smrgint	numKeywords = sizeof(keywords)/sizeof(struct _Keyword);
25976910425Smrg
26076910425Smrgstatic int
26176910425SmrgyyGetIdent(int first)
26276910425Smrg{
26376910425Smrgint ch,i,found;
26476910425Smrgint	rtrn = -1;
26576910425Smrg
26676910425Smrg    buf[0] = first; nInBuf = 1;
26776910425Smrg    while ( ((ch=getc(yyin))!=EOF) && (isalnum(ch)||(ch=='_')) ) {
26876910425Smrg	if ( nInBuf < BUFSIZE - 1 )
26976910425Smrg	    buf[nInBuf++] = ch;
27076910425Smrg    }
27176910425Smrg    buf[nInBuf++] = '\0';
27276910425Smrg    found= 0;
27376910425Smrg
27476910425Smrg    for (i=0;(!found)&&(i<numKeywords);i++) {
27576910425Smrg	if (uStrCaseCmp(buf,keywords[i].keyword)==0) {
27676910425Smrg	    rtrn= keywords[i].token;
27776910425Smrg	    found= 1;
27876910425Smrg	}
27976910425Smrg    }
28076910425Smrg    if (!found) {
28176910425Smrg	if  ( scanStr )
28276910425Smrg	    free( scanStr );
28376910425Smrg	scanStr = uStringDup(buf);
28476910425Smrg	scanStrLine = lineNum;
28576910425Smrg	rtrn = IDENT;
28676910425Smrg    }
28776910425Smrg
28876910425Smrg    if ( (ch!=EOF) && (!isspace(ch)) )
28976910425Smrg	ungetc( ch, yyin );
29076910425Smrg    else if ( ch=='\n' )
29176910425Smrg	lineNum++;
29276910425Smrg
29376910425Smrg    return rtrn;
29476910425Smrg}
29576910425Smrg
29676910425Smrgstatic int
29776910425SmrgyyGetNumber(int ch)
29876910425Smrg{
29976910425Smrgint	isFloat= 0;
30076910425Smrg
30176910425Smrg    buf[0]= ch;
30276910425Smrg    nInBuf= 1;
30376910425Smrg    while (((ch=getc(yyin))!=EOF)&&(isxdigit(ch)||((nInBuf==1)&&(ch=='x')))) {
30476910425Smrg	buf[nInBuf++]= ch;
30576910425Smrg    }
30676910425Smrg    if (ch=='.') {
30776910425Smrg	isFloat= 1;
30876910425Smrg	buf[nInBuf++]= ch;
30976910425Smrg	while (((ch=getc(yyin))!=EOF)&&(isxdigit(ch))) {
31076910425Smrg	    buf[nInBuf++]= ch;
31176910425Smrg	}
31276910425Smrg    }
31376910425Smrg    buf[nInBuf++]= '\0';
31476910425Smrg    if ((ch!=EOF)&&(!isspace(ch)))
31576910425Smrg	ungetc( ch, yyin );
31676910425Smrg
31776910425Smrg    if (isFloat) {
31876910425Smrg	float tmp;
31976910425Smrg	if (sscanf(buf,"%g",&tmp)==1) {
32076910425Smrg	    scanInt= tmp*XkbGeomPtsPerMM;
32176910425Smrg	    return FLOAT;
32276910425Smrg	}
32376910425Smrg    }
32476910425Smrg    else if ( sscanf(buf,"%i",&scanInt)==1 )
32576910425Smrg	return INTEGER;
32676910425Smrg    fprintf(stderr,"Malformed number %s\n",buf);
32776910425Smrg    return ERROR;
32876910425Smrg}
32976910425Smrg
33076910425Smrgint
33176910425Smrgyylex(void)
33276910425Smrg{
33376910425Smrgint	ch;
33476910425Smrgint	rtrn;
33576910425Smrg
33676910425Smrg    do {
33776910425Smrg	ch = getc(yyin);
33876910425Smrg	if ( ch == '\n' ) {
33976910425Smrg	    lineNum++;
34076910425Smrg	}
34176910425Smrg	else if ( ch=='/' ) {	/* handle C++ style double-/ comments */
34276910425Smrg	    int newch= getc(yyin);
34376910425Smrg	    if (newch=='/') {
34476910425Smrg		do {
34576910425Smrg		    ch= getc(yyin);
34676910425Smrg		} while ((ch!='\n')&&(ch!=EOF));
34776910425Smrg		lineNum++;
34876910425Smrg	    }
34976910425Smrg	    else if (newch!=EOF) {
35076910425Smrg		ungetc(newch,yyin);
35176910425Smrg	    }
35276910425Smrg	}
35376910425Smrg    } while ((ch!=EOF)&&(isspace(ch)));
35476910425Smrg    if ( ch == '=' )			rtrn = EQUALS;
35576910425Smrg    else if ( ch == '+' )		rtrn = PLUS;
35676910425Smrg    else if ( ch == '-' )		rtrn = MINUS;
35776910425Smrg    else if ( ch == '/' )		rtrn = DIVIDE;
35876910425Smrg    else if ( ch == '*' )		rtrn = TIMES;
35976910425Smrg    else if ( ch == '{' )		rtrn = OBRACE;
36076910425Smrg    else if ( ch == '}' )		rtrn = CBRACE;
36176910425Smrg    else if ( ch == '(' )		rtrn = OPAREN;
36276910425Smrg    else if ( ch == ')' )		rtrn = CPAREN;
36376910425Smrg    else if ( ch == '[' )		rtrn = OBRACKET;
36476910425Smrg    else if ( ch == ']' )		rtrn = CBRACKET;
36576910425Smrg    else if ( ch == '.' )		rtrn = DOT;
36676910425Smrg    else if ( ch == ',' )		rtrn = COMMA;
36776910425Smrg    else if ( ch == ';' )		rtrn = SEMI;
36876910425Smrg    else if ( ch == '!' )		rtrn = EXCLAM;
36976910425Smrg    else if ( ch == '~' )		rtrn = INVERT;
37076910425Smrg    else if ( ch == '"' )		rtrn = yyGetString();
37176910425Smrg    else if ( ch == '<' )		rtrn = yyGetKeyName();
37276910425Smrg    else if ( isalpha(ch) || (ch=='_')) rtrn = yyGetIdent(ch);
37376910425Smrg    else if ( isdigit(ch) )		rtrn = yyGetNumber(ch);
37476910425Smrg    else if ( ch == EOF )		rtrn = END_OF_FILE;
37576910425Smrg    else {
37676910425Smrg	fprintf(stderr,"Unexpected character %c (%d) in input stream\n",ch,ch);
37776910425Smrg	rtrn = ERROR;
37876910425Smrg    }
37976910425Smrg#ifdef DEBUG
38076910425Smrg    if (debugFlags&0x2)
38176910425Smrg	fprintf(stderr,"scan: %s\n",tokText(rtrn));
38276910425Smrg#endif
38376910425Smrg    return rtrn;
38476910425Smrg}
385