1
0
Files
irix-657m-src/eoe/cmd/fcman/cfg_scanner.c
2022-09-29 17:59:04 +03:00

199 lines
4.0 KiB
C

#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <fcntl.h> /* for I/O functions */
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include "cfg_scanner.h"
#define isident(_c) \
(isalpha(_c) || isdigit(_c) || (_c == '-') || (_c == '_') || (_c == '.'))
#define GETC(_scf) \
(_cfg_char_interface(0, _scf))
#define UNGETC(_scf, _ch) \
(_cfg_char_interface(1, _scf, _ch))
int _cfg_char_interface(int cmd, CFG_SC_FILE *scf, ...)
{
va_list ap;
char ch;
switch (cmd) {
case 0: /* getc() */
if (scf->_ungetc_valid) {
scf->_ungetc_valid = 0;
return(scf->_ungetc_char);
}
ch = getc(scf->_f);
return(ch);
case 1: /* ungetc() */
va_start(ap, scf);
ch = va_arg(ap, int);
va_end(ap);
if (scf->_ungetc_valid)
fatal("_cfg_char_available() : scf->_ungetc_valid = 1.\n");
scf->_ungetc_valid = 1;
scf->_ungetc_char = ch;
return(0);
default:
fatal("_cfg_char_interface() : invalid cmd.\n");
}
/* NOTREACHED */
}
void cfg_unget_token(CFG_SC_FILE *scf, token_t tk)
{
if (tk != &scf->_tk_curr)
fatal("cfg_unget_token() : tk != &scf->_tk_curr\n");
if (scf->_tk_curr_valid != 0)
fatal("cfg_unget_token() : scf->_tk_curr_valid != 0\n");
scf->_tk_curr_valid = 1;
}
token_t cfg_get_token(CFG_SC_FILE *scf)
{
char ch, *p;
int repeat = 0;
if (scf->_tk_curr_valid) {
scf->_tk_curr_valid = 0;
return(&scf->_tk_curr);
}
do {
repeat = 0;
ch = GETC(scf);
/* ch = tolower(ch); */
if (isalpha(ch) || (ch == '/')) {
p = scf->_tk_string;
do {
*p++ = ch;
ch = GETC(scf);
/* ch = tolower(ch); */
} while (isident(ch) || (ch == '/'));
UNGETC(scf, ch);
*p = '\0';
scf->_tk_curr.tk_value = scf->_tk_string;
scf->_tk_curr.tk_type = TK_STRING;
}
else
if (isdigit(ch)) {
int hex_flag = 0;
p = scf->_tk_string;
if (ch == '0') {
*p++ = ch;
ch = GETC(scf);
/* ch = tolower(ch); */
if (ch == 'x') {
hex_flag = 1;
ch = GETC(scf);
}
}
while ((hex_flag && isxdigit(ch)) ||
isdigit(ch)) {
*p++ = ch;
ch = GETC(scf);
/* ch = tolower(ch); */
}
UNGETC(scf, ch);
*p = '\0';
if (hex_flag)
sscanf(scf->_tk_string, "%x", &(scf->_tk_curr.tk_value));
else
sscanf(scf->_tk_string, "%d", &(scf->_tk_curr.tk_value));
scf->_tk_curr.tk_type = TK_NUMBER;
}
else
if (ch == '"') {
p = scf->_tk_string;
ch = GETC(scf);
while ((ch != '"') && (ch != '\n') && (ch != (char)EOF)) {
*p++ = ch;
if (ch == '\\')
*p++ = GETC(scf);
ch = GETC(scf);
}
*p = '\0';
if ((ch == '\n') && (ch == (char)EOF))
UNGETC(scf, ch);
scf->_tk_curr.tk_type = TK_STRING;
scf->_tk_curr.tk_value = (void *)malloc(strlen(scf->_tk_string) + 1);
strcpy(scf->_tk_curr.tk_value, scf->_tk_string);
}
else
switch(ch) {
case '#' :
while (1) {
ch = GETC(scf);
if (ch == '\n') {
scf->_tk_curr.tk_type = TK_EOL;
break;
}
if (ch == (char)EOF) {
scf->_tk_curr.tk_type = TK_EOF;
break;
}
}
break;
case '+' :
scf->_tk_curr.tk_type = TK_PLUS;
break;
case '-' :
scf->_tk_curr.tk_type = TK_MINUS;
break;
case ',' :
scf->_tk_curr.tk_type = TK_COMMA;
break;
case ':' :
scf->_tk_curr.tk_type = TK_COLON;
break;
case '\n':
scf->_tk_curr.tk_type = TK_EOL;
break;
case (char)EOF :
scf->_tk_curr.tk_type = TK_EOF;
break;
case '\\' :
while ((ch = GETC(scf)) != '\n')
;
repeat = 1;
break;
case ' ' :
case '\t' :
repeat = 1;
break;
default:
scf->_tk_curr.tk_type = TK_UNKNOWN;
}
} while(repeat);
return (&scf->_tk_curr);
}
CFG_SC_FILE *cfg_scopen(char *fn, char *type)
{
CFG_SC_FILE *scf;
FILE *f;
if ((f = fopen(fn, type)) == NULL)
return(NULL);
scf = (CFG_SC_FILE *)malloc(sizeof(CFG_SC_FILE));
bzero(scf, sizeof(CFG_SC_FILE));
scf->_f = f;
return(scf);
}
void cfg_scclose(CFG_SC_FILE *scf)
{
fclose(scf->_f);
bzero(scf, sizeof(CFG_SC_FILE));
free(scf);
}