cfgscan.c revision 9ff100ac
176910425Smrg/************************************************************
276910425Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
376910425Smrg
476910425Smrg Permission to use, copy, modify, and distribute this
576910425Smrg software and its documentation for any purpose and without
676910425Smrg fee is hereby granted, provided that the above copyright
776910425Smrg notice appear in all copies and that both that copyright
876910425Smrg notice and this permission notice appear in supporting
99ff100acSmrg documentation, and that the name of Silicon Graphics not be
109ff100acSmrg used in advertising or publicity pertaining to distribution
1176910425Smrg of the software without specific prior written permission.
129ff100acSmrg Silicon Graphics makes no representation about the suitability
1376910425Smrg of this software for any purpose. It is provided "as is"
1476910425Smrg without any express or implied warranty.
159ff100acSmrg
169ff100acSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
179ff100acSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1876910425Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
199ff100acSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
209ff100acSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
219ff100acSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2276910425Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
2376910425Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
2476910425Smrg
2576910425Smrg ********************************************************/
2676910425Smrg
2776910425Smrg#include <stdio.h>
2876910425Smrg#include <stdlib.h>
2976910425Smrg#include <ctype.h>
3076910425Smrg#include <X11/Xos.h>
3176910425Smrg#include <X11/X.h>
3276910425Smrg#include <X11/extensions/XKB.h>
3376910425Smrg
3476910425Smrg#include "tokens.h"
3576910425Smrg#include "xkbevd.h"
3676910425Smrg
379ff100acSmrgFILE    *yyin = NULL;
3876910425Smrg
3976910425Smrgstatic char scanFileBuf[1024];
409ff100acSmrgchar    *scanFile = scanFileBuf;
419ff100acSmrgint      lineNum = 0;
4276910425Smrg
439ff100acSmrgint      scanInt;
449ff100acSmrgchar    *scanIntStr;
459ff100acSmrgint      scanIntClass;
4676910425Smrg
479ff100acSmrgchar    *scanStr = NULL;
489ff100acSmrgint      scanStrLine = 0;
4976910425Smrg
509ff100acSmrg#define BUFSIZE 512
519ff100acSmrgstatic int      nInBuf = 0;
529ff100acSmrgstatic char     buf[BUFSIZE];
5376910425Smrg
5476910425Smrg#ifdef DEBUG
5576910425Smrg
569ff100acSmrgextern unsigned debugFlags;
5776910425Smrg
5876910425Smrgstatic char *
5976910425SmrgtokText(int tok)
6076910425Smrg{
619ff100acSmrg    static char buf[32];
6276910425Smrg
6376910425Smrg    switch (tok) {
649ff100acSmrg    case END_OF_FILE:
659ff100acSmrg        snprintf(buf, sizeof(buf), "END_OF_FILE");
669ff100acSmrg        break;
679ff100acSmrg    case ERROR:
689ff100acSmrg        snprintf(buf, sizeof(buf), "ERROR");
699ff100acSmrg        break;
709ff100acSmrg
719ff100acSmrg    case BELL:
729ff100acSmrg        snprintf(buf, sizeof(buf), "BELL");
739ff100acSmrg        break;
749ff100acSmrg    case ACCESSX:
759ff100acSmrg        snprintf(buf, sizeof(buf), "ACCESSX");
769ff100acSmrg        break;
779ff100acSmrg    case MESSAGE:
789ff100acSmrg        snprintf(buf, sizeof(buf), "MESSAGE");
799ff100acSmrg        break;
809ff100acSmrg
819ff100acSmrg    case NONE:
829ff100acSmrg        snprintf(buf, sizeof(buf), "NONE");
839ff100acSmrg        break;
849ff100acSmrg    case IGNORE:
859ff100acSmrg        snprintf(buf, sizeof(buf), "IGNORE");
869ff100acSmrg        break;
879ff100acSmrg    case ECHO:
889ff100acSmrg        snprintf(buf, sizeof(buf), "ECHO");
899ff100acSmrg        break;
909ff100acSmrg    case PRINT_EV:
919ff100acSmrg        snprintf(buf, sizeof(buf), "PRINT_EV");
929ff100acSmrg        break;
939ff100acSmrg    case SHELL:
949ff100acSmrg        snprintf(buf, sizeof(buf), "SHELL");
959ff100acSmrg        break;
969ff100acSmrg    case SOUND:
979ff100acSmrg        snprintf(buf, sizeof(buf), "SOUND");
989ff100acSmrg        break;
999ff100acSmrg
1009ff100acSmrg    case EQUALS:
1019ff100acSmrg        snprintf(buf, sizeof(buf), "EQUALS");
1029ff100acSmrg        break;
1039ff100acSmrg    case PLUS:
1049ff100acSmrg        snprintf(buf, sizeof(buf), "PLUS");
1059ff100acSmrg        break;
1069ff100acSmrg    case MINUS:
1079ff100acSmrg        snprintf(buf, sizeof(buf), "MINUS");
1089ff100acSmrg        break;
1099ff100acSmrg    case DIVIDE:
1109ff100acSmrg        snprintf(buf, sizeof(buf), "DIVIDE");
1119ff100acSmrg        break;
1129ff100acSmrg    case TIMES:
1139ff100acSmrg        snprintf(buf, sizeof(buf), "TIMES");
1149ff100acSmrg        break;
1159ff100acSmrg    case OBRACE:
1169ff100acSmrg        snprintf(buf, sizeof(buf), "OBRACE");
1179ff100acSmrg        break;
1189ff100acSmrg    case CBRACE:
1199ff100acSmrg        snprintf(buf, sizeof(buf), "CBRACE");
1209ff100acSmrg        break;
1219ff100acSmrg    case OPAREN:
1229ff100acSmrg        snprintf(buf, sizeof(buf), "OPAREN");
1239ff100acSmrg        break;
1249ff100acSmrg    case CPAREN:
1259ff100acSmrg        snprintf(buf, sizeof(buf), "CPAREN");
1269ff100acSmrg        break;
1279ff100acSmrg    case OBRACKET:
1289ff100acSmrg        snprintf(buf, sizeof(buf), "OBRACKET");
1299ff100acSmrg        break;
1309ff100acSmrg    case CBRACKET:
1319ff100acSmrg        snprintf(buf, sizeof(buf), "CBRACKET");
1329ff100acSmrg        break;
1339ff100acSmrg    case DOT:
1349ff100acSmrg        snprintf(buf, sizeof(buf), "DOT");
1359ff100acSmrg        break;
1369ff100acSmrg    case COMMA:
1379ff100acSmrg        snprintf(buf, sizeof(buf), "COMMA");
1389ff100acSmrg        break;
1399ff100acSmrg    case SEMI:
1409ff100acSmrg        snprintf(buf, sizeof(buf), "SEMI");
1419ff100acSmrg        break;
1429ff100acSmrg    case EXCLAM:
1439ff100acSmrg        snprintf(buf, sizeof(buf), "EXCLAM");
1449ff100acSmrg        break;
1459ff100acSmrg    case INVERT:
1469ff100acSmrg        snprintf(buf, sizeof(buf), "INVERT");
1479ff100acSmrg        break;
1489ff100acSmrg
1499ff100acSmrg    case STRING:
1509ff100acSmrg        snprintf(buf, sizeof(buf), "STRING (%s)", scanStr);
1519ff100acSmrg        break;
1529ff100acSmrg    case INTEGER:
1539ff100acSmrg        snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
1549ff100acSmrg        break;
1559ff100acSmrg    case FLOAT:
1569ff100acSmrg        snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
1579ff100acSmrg                 scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
1589ff100acSmrg        break;
1599ff100acSmrg    case IDENT:
1609ff100acSmrg        snprintf(buf, sizeof(buf), "IDENT (%s)", scanStr);
1619ff100acSmrg        break;
1629ff100acSmrg    case KEYNAME:
1639ff100acSmrg        snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanStr);
1649ff100acSmrg        break;
1659ff100acSmrg    default:
1669ff100acSmrg        snprintf(buf, sizeof(buf), "UNKNOWN");
1679ff100acSmrg        break;
16876910425Smrg    }
16976910425Smrg    return buf;
17076910425Smrg}
17176910425Smrg#endif
17276910425Smrg
17376910425Smrgint
1749ff100acSmrgsetScanState(const char *file, int line)
17576910425Smrg{
1769ff100acSmrg    if (file != NULL)
1779ff100acSmrg        strncpy(scanFile, file, 1024);
1789ff100acSmrg    if (line >= 0)
1799ff100acSmrg        lineNum = line;
18076910425Smrg    return 1;
18176910425Smrg}
18276910425Smrg
18376910425Smrgstatic int
18476910425SmrgyyGetString(void)
18576910425Smrg{
1869ff100acSmrg    int ch;
18776910425Smrg
18876910425Smrg    nInBuf = 0;
1899ff100acSmrg    while (((ch = getc(yyin)) != EOF) && (ch != '"')) {
1909ff100acSmrg        if (ch == '\\') {
1919ff100acSmrg            if ((ch = getc(yyin)) != EOF) {
1929ff100acSmrg                if (ch == 'n')
1939ff100acSmrg                    ch = '\n';
1949ff100acSmrg                else if (ch == 't')
1959ff100acSmrg                    ch = '\t';
1969ff100acSmrg                else if (ch == 'v')
1979ff100acSmrg                    ch = '\v';
1989ff100acSmrg                else if (ch == 'b')
1999ff100acSmrg                    ch = '\b';
2009ff100acSmrg                else if (ch == 'r')
2019ff100acSmrg                    ch = '\r';
2029ff100acSmrg                else if (ch == 'f')
2039ff100acSmrg                    ch = '\f';
2049ff100acSmrg                else if (ch == 'e')
2059ff100acSmrg                    ch = '\033';
2069ff100acSmrg                else if (ch == '0') {
2079ff100acSmrg                    int tmp, stop;
2089ff100acSmrg
2099ff100acSmrg                    ch = stop = 0;
2109ff100acSmrg                    if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) &&
2119ff100acSmrg                        (tmp != '8') && (tmp != '9')) {
2129ff100acSmrg                        ch = (ch * 8) + (tmp - '0');
2139ff100acSmrg                    }
2149ff100acSmrg                    else {
2159ff100acSmrg                        stop = 1;
2169ff100acSmrg                        ungetc(tmp, yyin);
2179ff100acSmrg                    }
2189ff100acSmrg                    if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
2199ff100acSmrg                        && (tmp != '8') && (tmp != '9')) {
2209ff100acSmrg                        ch = (ch * 8) + (tmp - '0');
2219ff100acSmrg                    }
2229ff100acSmrg                    else {
2239ff100acSmrg                        stop = 1;
2249ff100acSmrg                        ungetc(tmp, yyin);
2259ff100acSmrg                    }
2269ff100acSmrg                    if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
2279ff100acSmrg                        && (tmp != '8') && (tmp != '9')) {
2289ff100acSmrg                        ch = (ch * 8) + (tmp - '0');
2299ff100acSmrg                    }
2309ff100acSmrg                    else {
2319ff100acSmrg                        stop = 1;
2329ff100acSmrg                        ungetc(tmp, yyin);
2339ff100acSmrg                    }
2349ff100acSmrg                }
2359ff100acSmrg            }
2369ff100acSmrg            else
2379ff100acSmrg                return ERROR;
2389ff100acSmrg        }
2399ff100acSmrg
2409ff100acSmrg        if (nInBuf < BUFSIZE - 1)
2419ff100acSmrg            buf[nInBuf++] = ch;
24276910425Smrg    }
2439ff100acSmrg    if (ch == '"') {
2449ff100acSmrg        buf[nInBuf++] = '\0';
2459ff100acSmrg        if (scanStr)
2469ff100acSmrg            free(scanStr);
2479ff100acSmrg        scanStr = uStringDup(buf);
2489ff100acSmrg        scanStrLine = lineNum;
2499ff100acSmrg        return STRING;
25076910425Smrg    }
25176910425Smrg    return ERROR;
25276910425Smrg}
25376910425Smrg
25476910425Smrgstatic int
25576910425SmrgyyGetKeyName(void)
25676910425Smrg{
2579ff100acSmrg    int ch;
25876910425Smrg
25976910425Smrg    nInBuf = 0;
2609ff100acSmrg    while (((ch = getc(yyin)) != EOF) && (ch != '>')) {
2619ff100acSmrg        if (ch == '\\') {
2629ff100acSmrg            if ((ch = getc(yyin)) != EOF) {
2639ff100acSmrg                if (ch == 'n')
2649ff100acSmrg                    ch = '\n';
2659ff100acSmrg                else if (ch == 't')
2669ff100acSmrg                    ch = '\t';
2679ff100acSmrg                else if (ch == 'v')
2689ff100acSmrg                    ch = '\v';
2699ff100acSmrg                else if (ch == 'b')
2709ff100acSmrg                    ch = '\b';
2719ff100acSmrg                else if (ch == 'r')
2729ff100acSmrg                    ch = '\r';
2739ff100acSmrg                else if (ch == 'f')
2749ff100acSmrg                    ch = '\f';
2759ff100acSmrg                else if (ch == 'e')
2769ff100acSmrg                    ch = '\033';
2779ff100acSmrg                else if (ch == '0') {
2789ff100acSmrg                    int tmp, stop;
2799ff100acSmrg
2809ff100acSmrg                    ch = stop = 0;
2819ff100acSmrg                    if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp)) &&
2829ff100acSmrg                        (tmp != '8') && (tmp != '9')) {
2839ff100acSmrg                        ch = (ch * 8) + (tmp - '0');
2849ff100acSmrg                    }
2859ff100acSmrg                    else {
2869ff100acSmrg                        stop = 1;
2879ff100acSmrg                        ungetc(tmp, yyin);
2889ff100acSmrg                    }
2899ff100acSmrg                    if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
2909ff100acSmrg                        && (tmp != '8') && (tmp != '9')) {
2919ff100acSmrg                        ch = (ch * 8) + (tmp - '0');
2929ff100acSmrg                    }
2939ff100acSmrg                    else {
2949ff100acSmrg                        stop = 1;
2959ff100acSmrg                        ungetc(tmp, yyin);
2969ff100acSmrg                    }
2979ff100acSmrg                    if ((!stop) && ((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
2989ff100acSmrg                        && (tmp != '8') && (tmp != '9')) {
2999ff100acSmrg                        ch = (ch * 8) + (tmp - '0');
3009ff100acSmrg                    }
3019ff100acSmrg                    else {
3029ff100acSmrg                        stop = 1;
3039ff100acSmrg                        ungetc(tmp, yyin);
3049ff100acSmrg                    }
3059ff100acSmrg                }
3069ff100acSmrg            }
3079ff100acSmrg            else
3089ff100acSmrg                return ERROR;
3099ff100acSmrg        }
3109ff100acSmrg
3119ff100acSmrg        if (nInBuf < BUFSIZE - 1)
3129ff100acSmrg            buf[nInBuf++] = ch;
31376910425Smrg    }
3149ff100acSmrg    if ((ch == '>') && (nInBuf < 5)) {
3159ff100acSmrg        buf[nInBuf++] = '\0';
3169ff100acSmrg        if (scanStr)
3179ff100acSmrg            free(scanStr);
3189ff100acSmrg        scanStr = uStringDup(buf);
3199ff100acSmrg        scanStrLine = lineNum;
3209ff100acSmrg        return KEYNAME;
32176910425Smrg    }
32276910425Smrg    return ERROR;
32376910425Smrg}
32476910425Smrg
325db17cd6dSmrgstatic struct _Keyword {
3269ff100acSmrg    const char  *keyword;
3279ff100acSmrg    int         token;
32876910425Smrg} keywords[] = {
3299ff100acSmrg    { "bell",           BELL },
3309ff100acSmrg    { "accessx",        ACCESSX },
3319ff100acSmrg    { "message",        MESSAGE },
3329ff100acSmrg    { "none",           NONE },
3339ff100acSmrg    { "ignore",         IGNORE },
3349ff100acSmrg    { "echo",           ECHO },
3359ff100acSmrg    { "printevent",     PRINT_EV },
3369ff100acSmrg    { "shell",          SHELL },
3379ff100acSmrg    { "sound",          SOUND }
33876910425Smrg};
3399ff100acSmrgstatic int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
34076910425Smrg
34176910425Smrgstatic int
34276910425SmrgyyGetIdent(int first)
34376910425Smrg{
3449ff100acSmrg    int ch, i, found;
3459ff100acSmrg
3469ff100acSmrg    int rtrn = -1;
34776910425Smrg
3489ff100acSmrg    buf[0] = first;
3499ff100acSmrg    nInBuf = 1;
3509ff100acSmrg    while (((ch = getc(yyin)) != EOF) && (isalnum(ch) || (ch == '_'))) {
3519ff100acSmrg        if (nInBuf < BUFSIZE - 1)
3529ff100acSmrg            buf[nInBuf++] = ch;
35376910425Smrg    }
35476910425Smrg    buf[nInBuf++] = '\0';
3559ff100acSmrg    found = 0;
35676910425Smrg
3579ff100acSmrg    for (i = 0; (!found) && (i < numKeywords); i++) {
3589ff100acSmrg        if (uStrCaseCmp(buf, keywords[i].keyword) == 0) {
3599ff100acSmrg            rtrn = keywords[i].token;
3609ff100acSmrg            found = 1;
3619ff100acSmrg        }
36276910425Smrg    }
36376910425Smrg    if (!found) {
3649ff100acSmrg        if (scanStr)
3659ff100acSmrg            free(scanStr);
3669ff100acSmrg        scanStr = uStringDup(buf);
3679ff100acSmrg        scanStrLine = lineNum;
3689ff100acSmrg        rtrn = IDENT;
36976910425Smrg    }
37076910425Smrg
3719ff100acSmrg    if ((ch != EOF) && (!isspace(ch)))
3729ff100acSmrg        ungetc(ch, yyin);
3739ff100acSmrg    else if (ch == '\n')
3749ff100acSmrg        lineNum++;
37576910425Smrg
37676910425Smrg    return rtrn;
37776910425Smrg}
37876910425Smrg
37976910425Smrgstatic int
38076910425SmrgyyGetNumber(int ch)
38176910425Smrg{
3829ff100acSmrg    int isFloat = 0;
38376910425Smrg
3849ff100acSmrg    buf[0] = ch;
3859ff100acSmrg    nInBuf = 1;
3869ff100acSmrg    while (((ch = getc(yyin)) != EOF) &&
3879ff100acSmrg           (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x')))) {
3889ff100acSmrg        buf[nInBuf++] = ch;
38976910425Smrg    }
3909ff100acSmrg    if (ch == '.') {
3919ff100acSmrg        isFloat = 1;
3929ff100acSmrg        buf[nInBuf++] = ch;
3939ff100acSmrg        while (((ch = getc(yyin)) != EOF) && (isxdigit(ch))) {
3949ff100acSmrg            buf[nInBuf++] = ch;
3959ff100acSmrg        }
39676910425Smrg    }
3979ff100acSmrg    buf[nInBuf++] = '\0';
3989ff100acSmrg    if ((ch != EOF) && (!isspace(ch)))
3999ff100acSmrg        ungetc(ch, yyin);
40076910425Smrg
40176910425Smrg    if (isFloat) {
4029ff100acSmrg        float tmp;
4039ff100acSmrg
4049ff100acSmrg        if (sscanf(buf, "%g", &tmp) == 1) {
4059ff100acSmrg            scanInt = tmp * XkbGeomPtsPerMM;
4069ff100acSmrg            return FLOAT;
4079ff100acSmrg        }
40876910425Smrg    }
4099ff100acSmrg    else if (sscanf(buf, "%i", &scanInt) == 1)
4109ff100acSmrg        return INTEGER;
4119ff100acSmrg    fprintf(stderr, "Malformed number %s\n", buf);
41276910425Smrg    return ERROR;
41376910425Smrg}
41476910425Smrg
41576910425Smrgint
41676910425Smrgyylex(void)
41776910425Smrg{
4189ff100acSmrg    int ch;
4199ff100acSmrg    int rtrn;
4209ff100acSmrg
42176910425Smrg    do {
4229ff100acSmrg        ch = getc(yyin);
4239ff100acSmrg        if (ch == '\n') {
4249ff100acSmrg            lineNum++;
4259ff100acSmrg        }
4269ff100acSmrg        else if (ch == '/') {   /* handle C++ style double-/ comments */
4279ff100acSmrg            int newch = getc(yyin);
4289ff100acSmrg
4299ff100acSmrg            if (newch == '/') {
4309ff100acSmrg                do {
4319ff100acSmrg                    ch = getc(yyin);
4329ff100acSmrg                } while ((ch != '\n') && (ch != EOF));
4339ff100acSmrg                lineNum++;
4349ff100acSmrg            }
4359ff100acSmrg            else if (newch != EOF) {
4369ff100acSmrg                ungetc(newch, yyin);
4379ff100acSmrg            }
4389ff100acSmrg        }
4399ff100acSmrg    } while ((ch != EOF) && (isspace(ch)));
4409ff100acSmrg    if (ch == '=')
4419ff100acSmrg        rtrn = EQUALS;
4429ff100acSmrg    else if (ch == '+')
4439ff100acSmrg        rtrn = PLUS;
4449ff100acSmrg    else if (ch == '-')
4459ff100acSmrg        rtrn = MINUS;
4469ff100acSmrg    else if (ch == '/')
4479ff100acSmrg        rtrn = DIVIDE;
4489ff100acSmrg    else if (ch == '*')
4499ff100acSmrg        rtrn = TIMES;
4509ff100acSmrg    else if (ch == '{')
4519ff100acSmrg        rtrn = OBRACE;
4529ff100acSmrg    else if (ch == '}')
4539ff100acSmrg        rtrn = CBRACE;
4549ff100acSmrg    else if (ch == '(')
4559ff100acSmrg        rtrn = OPAREN;
4569ff100acSmrg    else if (ch == ')')
4579ff100acSmrg        rtrn = CPAREN;
4589ff100acSmrg    else if (ch == '[')
4599ff100acSmrg        rtrn = OBRACKET;
4609ff100acSmrg    else if (ch == ']')
4619ff100acSmrg        rtrn = CBRACKET;
4629ff100acSmrg    else if (ch == '.')
4639ff100acSmrg        rtrn = DOT;
4649ff100acSmrg    else if (ch == ',')
4659ff100acSmrg        rtrn = COMMA;
4669ff100acSmrg    else if (ch == ';')
4679ff100acSmrg        rtrn = SEMI;
4689ff100acSmrg    else if (ch == '!')
4699ff100acSmrg        rtrn = EXCLAM;
4709ff100acSmrg    else if (ch == '~')
4719ff100acSmrg        rtrn = INVERT;
4729ff100acSmrg    else if (ch == '"')
4739ff100acSmrg        rtrn = yyGetString();
4749ff100acSmrg    else if (ch == '<')
4759ff100acSmrg        rtrn = yyGetKeyName();
4769ff100acSmrg    else if (isalpha(ch) || (ch == '_'))
4779ff100acSmrg        rtrn = yyGetIdent(ch);
4789ff100acSmrg    else if (isdigit(ch))
4799ff100acSmrg        rtrn = yyGetNumber(ch);
4809ff100acSmrg    else if (ch == EOF)
4819ff100acSmrg        rtrn = END_OF_FILE;
48276910425Smrg    else {
4839ff100acSmrg        fprintf(stderr, "Unexpected character %c (%d) in input stream\n",
4849ff100acSmrg                ch, ch);
4859ff100acSmrg        rtrn = ERROR;
48676910425Smrg    }
48776910425Smrg#ifdef DEBUG
4889ff100acSmrg    if (debugFlags & 0x2)
4899ff100acSmrg        fprintf(stderr, "scan: %s\n", tokText(rtrn));
49076910425Smrg#endif
49176910425Smrg    return rtrn;
49276910425Smrg}
493