/***************************************************************************/ /* Killer List Of Video-games Database. */ /* Copyright (C) 1993 John Keay */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* */ /* For more details see 'COPYING' */ /* John Keay (keay@tiuk.ti.com) */ /***************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "proto.h" #include "parse.h" #ifndef TRUE #define TRUE (!0) #endif #ifndef FALSE #define FALSE 0 #endif void *safe_malloc(size) unsigned size; { void *tmp; tmp = (void *) malloc(size); if(tmp == NULL) { fprintf(stderr,"No MEMORY for malloc\n"); exit(1); } return(tmp); } static char *error_name[] = { "WARNING", "ERROR" }; /* I usually use stdarg.h here, but given this makes it less portable */ /* and there isn't much error checking in the code anyway I'll take */ /* it out. */ static void parse_error PROTO((error_t e,parse_ptr p,char *mess)); static void parse_error(e,p,mess) error_t e; parse_ptr p; char *mess; { char *ptr; int i; if(p) { fprintf(p->err,"%s: ",error_name[e]); fprintf(p->err,mess); fprintf(p->err,"\n"); ptr = p->line; while(*ptr != '\0' && *ptr != '\n') fprintf(p->err,"%c",*ptr++); fprintf(p->err,"\n"); for(i=0;i<p->token_pos;i++) fprintf(p->err," "); fprintf(p->err,"^\n"); } else { fprintf(stderr,"%s: ",error_name[e]); fprintf(stderr,mess); fprintf(stderr,"\n"); } if(e == E_FATAL) exit(1); } static void parse_get_char PROTO((parse_ptr p)); static void parse_get_char(p) parse_ptr p; { if(p->cptr && *p->cptr) p->cptr++; if(!p->cptr || !*p->cptr) { p->eof = !fgets(p->line,MAX_TOKEN_LEN,p->fp); p->cptr = p->line; } } static void parse_skip_white PROTO((parse_ptr p)); static void parse_skip_white(p) parse_ptr p; { while(*p->cptr == ' ' || *p->cptr == '\t') parse_get_char(p); } void parse_get_token(p) parse_ptr p; { char *t = p->token; parse_skip_white(p); p->token_pos = (int) (p->cptr - p->line); if (isalnum(*p->cptr) || *p->cptr == '?' || *p->cptr == '\'' || *p->cptr == '-' ||*p->cptr == '*') { do { *t++ = *p->cptr; parse_get_char(p); } while (isalnum(*p->cptr) || *p->cptr == '?' || *p->cptr == '.' || *p->cptr == '\'' || *p->cptr == '-' || *p->cptr == '*'); } else { *t++ = *p->cptr; parse_get_char(p); } *t++ = '\0'; } parse_ptr parse_open(filename) char *filename; { FILE *fp; parse_ptr p=NULL; if(!(fp = fopen(filename,"r"))) { char tmp[1024]; /* If only stdarg.h was standard */ sprintf(tmp,"Can't open file \"%s\" for read",filename); parse_error(E_WARNING,NULL,tmp); } else { p = (parse_ptr) safe_malloc(sizeof(parse_t)); p->filename = (char *) safe_malloc(strlen(filename)+1); p->line = (char *) safe_malloc(MAX_TOKEN_LEN); p->token = (char *) safe_malloc(MAX_LINE_LEN); strcpy(p->filename,filename); strcpy(p->line ,""); strcpy(p->token ,""); p->fp = fp; p->cptr = NULL; p->eof = FALSE; p->token_pos = 0; p->err = stderr; parse_get_char(p); parse_get_token(p); } return(p); } void parse_close(p) parse_ptr p; { fclose(p->fp); free(p->filename); free(p->token); free(p->line); free(p); } int its(p,s) parse_ptr p; char *s; { if (p->eof) { return(FALSE); } else if (!strcmp(s,p->token)) { parse_get_token(p); return(TRUE); } return(FALSE); } int its_not(p,s) parse_ptr p; char *s; { if (p->eof) { return(FALSE); } else if (!strcmp(s,p->token)) { parse_get_token(p); return(FALSE); } return(TRUE); } void mustbe(p,s) parse_ptr p; char *s; { static char tmp[1024]; if (p->eof) { /* If only stdarg.h was standard */ sprintf(tmp,"Expecting '%s' found EOF",s); parse_error(E_FATAL,p,tmp); } else if (strcmp(s,p->token)) { sprintf(tmp,"Expecting '%s' found '%s'",s,p->token); parse_error(E_FATAL,p,tmp); } parse_get_token(p); }