📄 parser.c
字号:
/* TradeClient <http://tradeclient.sourceforge.net> * $Id: parser.c,v 1.12 2001/03/20 22:19:33 ttabner Exp $ * * Copyright (C) 1999-2000 Bynari Inc. * Copyright (C) 2001 Project TradeClient * * LGPL * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library 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 Library * General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "parser.h"// MEMWATCH#ifdef MEMWATCH#include "memwatch.h"#endif// DMALLOC#ifdef DMALLOC#include "dmalloc.h"#endifkeyword *set_option(const struct keyword rep) { keyword *option=(keyword *)calloc(1, sizeof(keyword)); option->kword=rep.kword; option->vtype=rep.vtype; option->var=rep.var; option->funct=rep.funct; return option;}pfile *new_pfile () { pfile *pf=(pfile *)calloc(1, sizeof(pfile)); pf->name=(char *)calloc(2048, sizeof(char)); pf->T_EOF=0; pf->T_BOF=0; pf->lineno=1; return pf;}voiddelete_pfile( pfile *pf ) { if( pf ) { free( pf -> name ) ; free( pf ) ; pf = NULL ; } return ;}char getch (pfile *pf) { char tmpp ; if ((ftell(pf->fs) == 0) && (pf->T_BOF == 1)) { pf->T_BOF=0; return '\n'; } if (fread (&tmpp, 1, 1, pf->fs)==0) { if (feof(pf->fs)!=0) { pf->T_EOF=1; return EOF; } else {#if DEBUG > 8 printf("parser.o: PIPEERROR: getch(): A file error occurred\n");#endif return FERR; } } return tmpp ;}char *getline (pfile *pf) { char *ret=NULL; int i=0; unsigned long j;gl1top: if ((pf->T_BOF == 1)) { pf->T_BOF=0; } if (!pf->buff) { pf->bboff=ftell (pf->fs); pf->buff=(char *)calloc(1024*1024+2, sizeof(char)); j=fread (pf->buff, sizeof(char), 1024*1024, pf->fs); if (j<1024*1024) { if (j==0) { pf->T_EOF=1; } if (feof (pf->fs)!=0) { pf->bff=TRUE; } } pf->bpos=0; pf->blpos=0; } pf->btp=strchr(pf->buff+pf->bpos, '\n'); if (pf->T_EOF==1) { if (pf->buff) free (pf->buff); pf->buff=NULL; ret=(char *)calloc(i+2, sizeof(char)); return ret; } if (!pf->btp) { fseek (pf->fs, pf->bboff+pf->bpos, SEEK_SET); free (pf->buff); pf->buff=NULL; goto gl1top; } pf->btp++; i=pf->btp-(pf->buff+pf->bpos); ret=(char *)calloc(i+2, sizeof(char)); memmove (ret, pf->buff+pf->bpos, i); pf->blpos=pf->bpos; pf->bpos+=i; return ret;}void getline_ (pfile *pf, char *str) { int i; unsigned long j;gl2top: if ((pf->T_BOF == 1)) { pf->T_BOF=0; } if (!pf->buff) { pf->bboff=ftell (pf->fs); pf->buff=(char *)calloc(1024*1024+2, sizeof(char)); j=fread (pf->buff, sizeof(char), 1024*1024, pf->fs); if (j<1024*1024) { if (j==0) { pf->T_EOF=1; } if (feof (pf->fs)==0) { pf->bff=TRUE; } } pf->bpos=0; pf->blpos=0; } pf->btp=strchr(pf->buff+pf->bpos, '\n'); if (pf->T_EOF!=0) { if (pf->buff) free (pf->buff); pf->buff=NULL; memset (str, 0, 10); return; } if (!pf->btp) { fseek (pf->fs, pf->bboff+pf->bpos, SEEK_SET); free (pf->buff); pf->buff=NULL; goto gl2top; } pf->btp++; i=pf->btp-(pf->buff+pf->bpos); if (i>1024) { memmove (str, pf->buff+pf->bpos, i); } else { memmove (str, pf->buff+pf->bpos, 1024); } pf->blpos=pf->bpos; pf->bpos+=i;}void ungetline (pfile *pf) { if (pf->bpos!=pf->blpos) { pf->bpos=pf->blpos; } else { while (pf->bpos>0) { pf->bpos--; if (pf->buff[pf->bpos]=='\n') { pf->bpos++; break; } } }}void ungetch (pfile *pf) { long fpos=ftell(pf->fs); if (fpos == 0) pf->T_BOF=1; else fseek(pf->fs, fpos-1, SEEK_SET);}void skipspaces (pfile *pf) { char ch=' '; while (((ch == ' ')||(ch == '\033')||(ch == '\t')||(ch == '\0'))&&(ch!=EOF)) { ch=getch(pf); } ungetch(pf);}void gteol (pfile *pf) { char ch='\255'; while ((ch != '\n')&&(ch != '\r')&&(ch != EOF)) { ch=getch(pf); }}char *getword (pfile *pf) { char *tmp=(char *)calloc(4*1024, sizeof(char)); char ch=getch(pf); int j=0; if ((ch=='\n')||(ch=='\r')||(ch=='#')||(ch==EOF)) { free (tmp); return NULL; } else if (ch=='"') { ch='\255'; while ((ch != '"')&&(ch != EOF)&&(j<4*1024)) { ch=getch(pf); tmp[j]=ch; j++; } } else { ungetch(pf); while ((ch != ' ')&&(ch != '\033')&&(ch != '\r')&& (ch != '\n')&&(ch != '\t')&&(ch != '\0')&& (ch != '=')&&(ch != '#')&&(ch != EOF)) { ch=getch(pf); tmp[j]=ch; j++; } } ungetch(pf); tmp[j-1]='\0'; return tmp;}void ungetword (pfile *pf) { char ch='\255'; while ((ch != ' ')&&(ch != '\033')&& (ch != '\n')&&(ch != '\t')&& (ch != '\0')&&(ch != '\r')){ ungetch(pf); ungetch(pf); ch=getch(pf); }}void substitute (char *string, const char *match, const char *replace) { int slen=strlen (string); int mlen=strlen (match); int rlen=strlen (replace); int sub=0, i; char *tmpmatch=(char *)calloc(mlen+1, sizeof(char)); char *ret=(char *)calloc(((slen-mlen)+rlen)+5, sizeof(char)); for (i=0; i<slen; i++) { if (string[i]==match[0]) { memmove (tmpmatch,string+i,mlen); if (strcmp(tmpmatch,match)==0) { memmove (ret,string,i); memmove (ret+i,replace,rlen); memmove (ret+i+rlen,string+i+mlen,slen-mlen-i); i=slen;sub=1; } } } if (sub==1) memmove(string,ret,((slen-mlen)+rlen)+1); free(tmpmatch); free(ret);}void env_srch_rep(char *str) { char *envn ; char *envr ; char *eq; int i=0;int j=0; envn = calloc( 1024, 1*sizeof(char) ); envr = calloc( 1024, 1*sizeof(char) ) ; while ((str[i]!='\0')&&(i<sizeof(envr))) { if (str[i]=='$') { if (str[i+1]=='(') { i+=2;j=0; while((str[j+i]!='\0')&&(str[j+i]!=')')&&(j+i<1024)) { envn[j]=str[j+i]; j++; } if (str[j+i]!='\0') { eq=getenv(envn); if (eq!=NULL) { sprintf(envr,"$(%s)",envn); substitute (str,envr,eq); } } } } i++; } free( envn ) ; free( envr ) ; return ;}void parsekword (pfile *pf, keyword *options[], int noo) { int i=0,found=-1; char ch=(char)255; char *tmpw; char *tmps; char *tmpv; tmpw = getword( pf ) ;#if DEBUG > 8 printf("parser.o: parsekword(): %s: %d : word '%s' parsed.\n", pf->name, pf->lineno, tmpw);#endif if( tmpw ) { for (i=0; i<noo; i++) {#if DEBUG > 8 printf("parser.o: parsekword(): comparing to word: %d - %s match: %d\n", i, options[i]->kword, strcmp(options[i]->kword, tmpw));#endif if (strcmp(options[i]->kword, tmpw)==0) { found=i; break; } } if (found!=-1) {#if DEBUG > 8 printf("parser.o: parsekword(): %s: %d: found keyword '%s'.\n",pf->name, pf->lineno, options[found]->kword);#endif if( tmpw ) { free( tmpw ) ; tmpw = NULL ; } skipspaces(pf); ch=getch(pf); if (ch == '=') { skipspaces(pf); tmps=getword(pf); if (tmps==NULL) {#if DEBUG > 8 printf("parser.o: WARNING: parsekword(): NULL value found for keyword '%s' leaving default.\n", options[found]->kword);#endif } else { if (strcmp(options[found]->vtype,"char*")==0) { if (options[found]->funct==NULL) { tmpv=(char *)options[found]->var; env_srch_rep(tmps); memmove(tmpv, tmps, strlen(tmps)); } else { env_srch_rep(tmps); options[found]->funct(tmps); } } else if (strcmp(options[found]->vtype,"int")==0) { if (options[found]->funct==NULL) { int *tmpi=(int *)options[found]->var; *tmpi=atoi(tmps); } else { int *tmpi=(int *)calloc(1, sizeof(int)); *tmpi=atoi(tmps); options[found]->funct(tmpi); } } else if (strcmp(options[found]->vtype,"bool")==0) { int *tmpi; if (options[found]->funct==NULL) { tmpi=(int *)options[found]->var; } else { tmpi=(int *)calloc(1, sizeof(int)); } *tmpi=1; if (strlen(tmps)==1) { switch (tmps[0]) { case '0': case 'n': case 'N': *tmpi=0; break; } } else { if ((strcasecmp(tmps, "no")==0)|| (strcasecmp(tmps, "off")==0)) { *tmpi=0; } } if (options[found]->funct!=NULL) { options[found]->funct(tmpi); } } } } else {#if DEBUG > 8 printf("parser.o: parsekword(): WARNING: %s: %d: Keyword '%s' found, but no declaration.\n", pf->name, pf->lineno, options[found]->kword);#endif gteol(pf); } } else {#if DEBUG > 8 printf("parser.o: parsekword(): WARNING: %s: %d: unknown keyword: '%s' skipping.\n", pf->name, pf->lineno, tmpw);#endif gteol(pf); } if( tmpw ) free(tmpw) ; } return ;}void get_token (pfile *pf, keyword *options[], int noo) { char ch1,ch2; ch1 = getch(pf); switch (ch1) { case EOF: pf->T_EOF=1; break; case '#':#if DEBUG > 8 printf("parser.o: get_token(): comment on line %d\n", pf->lineno);#endif ungetch(pf); ungetch(pf); ch2 = getch(pf); if ((ch2 != '\n') && (ch2 != '\r')) { ch2 = getch(pf); break; } ch2 = getch(pf); while ((ch2 != '\n') && (ch2 != '\r')) { ch2 = getch(pf); if(ch2==EOF) { pf->T_EOF=1; break; } } if (ch2 =='\n') { pf->lineno++; } break; case '=': ungetch(pf); ungetword(pf); parsekword(pf, options, noo); break; case '\n': pf->lineno++; break; default: break; }}int parse (char *filename, keyword *options[], int noo) { pfile *pf=new_pfile(); int i; snprintf(pf->name, 2048, "%s", filename); pf->fs = fopen(filename,"r"); if (pf->fs==NULL) {#ifdef DEBUG perror ("parser.o: file error");#endif return (FALSE); }#if DEBUG > 8 printf("parser.o: parse(): number of options to parse: %d\n", noo);#endif for (i=0; pf->T_EOF==0; i++) { get_token(pf, options, noo); } fclose (pf->fs);#if DEBUG > 8 printf("parser.o: parse(): %s: parsed %d lines\n", pf->name, pf->lineno);#endif delete_pfile( pf ) ; return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -