Back to index

wims  3.65+svn20090927
compare.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018 char *bufprep(char *p)
00019 {
00020 /*  singlespace(p); strip_trailing_spaces(p); return find_word_start(p); */
00021     nospace(p); return p;
00022 }
00023 
00024 char *parend(char *p)
00025 {
00026     char *pp; int t;
00027     t=0; for(pp=p;*pp;pp++) {
00028        if(*pp=='(') t++;
00029        if(*pp==')') {t--; if(t==0) return pp; if(t<0) return NULL;}
00030     }
00031     return NULL;
00032 }
00033 
00034 char *relation_type[]={
00035     "sametext","samecase",
00036     "in",  "wordof","itemof","lineof","varof","variableof"
00037 };
00038 #define total_relations (sizeof(relation_type)/sizeof(relation_type[0]))
00039 
00040        /* Here we only check syntax correctness. Returns 1 if OK. */
00041 int _check_compare(char *p, int lvl)
00042 {
00043     char *p1, *p2, *pp, *pt;
00044     char *r1, *r2;
00045     int i, l, k, gotl;
00046     
00047        /* Check global pairs of parentheses */
00048     p2=strip_trailing_spaces(p);
00049     p1=find_word_start(p);
00050     while(*p1=='(' && *p2==')' && p2==parend(p1)) {
00051        lvl=0; p1=find_word_start(++p1);
00052        do p2--; while(p2>=p1 && myisspace(*p2));
00053        p2[1]=0;
00054     }
00055     gotl=100; r1=r2=p1;
00056     for(pp=p1; *pp; pp++) {
00057        if(*pp==')') return 0;
00058        if(*pp=='(') {
00059            pp=parend(pp); if(pp==NULL) return 0;
00060            continue;
00061        }
00062        if(gotl>3) {
00063            switch(*pp) {
00064               case '<': {
00065                   gotl=3; r1=pp; r2=r1+1;
00066                   if(*r2=='=') {r2++;break;}
00067                   if(*r2=='>') r2++;
00068                   break;
00069               }
00070               case '>': {
00071                   gotl=3; r1=pp; r2=r1+1;
00072                   if(*r2=='=') r2++;
00073                   break;
00074               }
00075               case '=': {
00076                   gotl=3; r1=pp; r2=r1+1; if(*r2=='=') r2++;
00077                   break;
00078               }
00079               case '!': {
00080                   if(pp[1]=='=') {
00081                      gotl=3; r1=pp; r2=pp+2;
00082                   }
00083                   break;
00084               }
00085            }
00086            if(r2>p1) {
00087               if(lvl==2) break;
00088               pp=r2-1; continue;
00089            }
00090        }
00091        if(!myisspace(*pp)) continue;
00092        pp=find_word_start(pp);
00093        if(gotl>3) {
00094            if(pp[0]=='i' && pp[1]=='s') {k=2; goto isnot;}
00095            if(pp[0]=='n' && pp[1]=='o' && pp[2]=='t') {k=3; goto isnot;}
00096            goto rel;
00097            isnot:
00098            if(strchr("siwlv",pp[k])==NULL) goto rel;
00099            pt=pp; pp+=k; l=0;
00100            for(i=0;i<total_relations;i++) {
00101               l=strlen(relation_type[i]);
00102               if(strncmp(pp, relation_type[i], l)==0 && 
00103                  ((!myisalnum(pp[l]) && pp[l]!='_') || pp[l]==0)) break;
00104            }
00105            if(i>=total_relations) {pp--; continue;}
00106            gotl=3; pp+=l; r1=pt; r2=pp;
00107            if(lvl==2) break; else {pp--; continue;}
00108        }
00109        rel:
00110        if(*pp!='|' && *pp!='&' && *pp!='a' && *pp!='o')
00111            {pp--; continue;}
00112        if(gotl>2 && 
00113           ((myisspace(pp[3]) && strncmp(pp,"and",3)==0) || 
00114            (myisspace(pp[2]) && strncmp(pp,"&&",2)==0))) {
00115            gotl=2; r1=pp; pp=r2=find_word_end(r1);
00116            if(lvl==1) break; else {pp--;continue;}
00117        }
00118        if(gotl>1 && myisspace(pp[2]) && 
00119           (strncmp(pp,"or",2)==0 || strncmp(pp,"||",2)==0)) {
00120            gotl=1; r1=pp; r2=pp=r1+2; break;
00121        }
00122     }
00123     switch(gotl) {
00124        case 1: {     /* or */
00125            *r1=0;
00126            if(!_check_compare(p1,1)) return 0;
00127            if(!_check_compare(r2,0)) return 0;
00128            return 1;
00129        }
00130        case 2:       {      /* and */
00131            *r1=0;
00132            if(!_check_compare(p1,2)) return 0;
00133            if(!_check_compare(r2,1)) return 0;
00134        }
00135        case 3: {
00136            return 1; /* this is considered as OK. */
00137        }
00138     }
00139     return 0;
00140 }
00141 
00142 int check_compare(char *p)
00143 {
00144     char buf[MAX_LINELEN+1];
00145     char *pp;
00146     snprintf(buf,sizeof(buf),"%s",p);
00147     pp=strparchr(buf,'?'); if(pp) *pp=0;
00148     return _check_compare(buf,0);
00149 }
00150 
00151