Back to index

wims  3.65+svn20090927
not.c
Go to the documentation of this file.
00001 /*    Copyright (C) 2002-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 struct {
00019     char *orig, *reverse;
00020 } revtab[]={
00021     {"=",     "!="},
00022     {"!=",    "="},
00023     {"==",    "!="},
00024     {"<>",    "="},
00025     {"<",     ">="},
00026     {">",     "<="},
00027     {"<=",    ">"},
00028     {">=",    "<"},
00029     {"and",   "or"},
00030     {"or",    "and"},
00031 };
00032 #define revno (sizeof(revtab)/sizeof(revtab[0]))
00033 
00034        /* p will contain the new exp, and must has a buffer of MAX_LINELEN+1 */
00035 void _not(char *p)
00036 {
00037     char buf1[MAX_LINELEN+1], bufr[MAX_LINELEN+1];
00038     char buft[16];
00039     int commas[MAX_COMMAS], cmcnt;
00040     char *pp;
00041     int i, l;
00042     
00043     snprintf(buf1,sizeof(buf1),"%s",find_word_start(p));
00044     retype:
00045     if(buf1[0]==0) {*p=0; return;} /* empty */
00046     strip_trailing_spaces(buf1);
00047     switch(_type(buf1,commas,&cmcnt)) {
00048        case exp_paren: {
00049            if(buf1[0]=='(' && find_matching(buf1+1,')')==buf1+strlen(buf1)-1) {
00050               buf1[strlen(buf1)-1]=0; strcpy(buf1,find_word_start(buf1+1));
00051               goto retype;
00052            }
00053            snprintf(p,MAX_LINELEN,"not %s",buf1); return;
00054        }
00055        case exp_not: {
00056            if(strncasecmp(buf1,"not",3)!=0) error("Syntax error.");
00057            pp=find_word_start(buf1+3);
00058            if(*pp=='(' && find_matching(pp+1,')')==pp+strlen(pp)-1) {
00059               pp++; *(pp+strlen(pp)-1)=0;
00060            }
00061            snprintf(p,MAX_LINELEN,"%s",pp); return;
00062        }
00063        case exp_ineq:
00064        case exp_eq: {
00065            if(cmcnt!=2 || commas[1]-commas[0]>4) error("Syntax error.");
00066            memmove(buft,buf1+commas[0],commas[1]-commas[0]);
00067            buft[commas[1]-commas[0]]=0;
00068            for(i=0;i<revno && strcmp(buft,revtab[i].orig)!=0;i++);
00069            if(i>=revno) error("Software bug: bad sign.");
00070            string_modify(buf1,buf1+commas[0],buf1+commas[1],revtab[i].reverse);
00071            snprintf(p,MAX_LINELEN,"%s",buf1);
00072            return;
00073        }
00074        case exp_and: {
00075            if(cmcnt<2 || (cmcnt&1)!=0) error("Syntax error.");
00076            commas[cmcnt]=strlen(buf1);
00077            memmove(bufr,buf1,commas[0]); bufr[commas[0]]=0;
00078            _not(bufr); snprintf(p,MAX_LINELEN,"%s",bufr); l=strlen(p);
00079            for(i=1;i<=cmcnt/2;i++) {
00080               memmove(bufr,buf1+commas[2*i-1],commas[2*i]-commas[2*i-1]);
00081               bufr[commas[2*i]-commas[2*i-1]]=0;
00082               _not(bufr);
00083               snprintf(p+l,MAX_LINELEN-l," or %s",bufr); l=strlen(p);
00084            }
00085            return;
00086        }
00087        case exp_or: {
00088            int commas2[MAX_COMMAS], cmcnt2;
00089            if(cmcnt<2 || (cmcnt&1)!=0) error("Syntax error.");
00090            commas[cmcnt]=strlen(buf1);
00091            memmove(bufr,buf1,commas[0]); bufr[commas[0]]=0;
00092            _not(bufr); 
00093            if(_type(bufr,commas2,&cmcnt2)!=exp_or)
00094              snprintf(p,MAX_LINELEN,"%s",bufr); 
00095            else snprintf(p,MAX_LINELEN,"(%s)",bufr); 
00096            l=strlen(p);
00097            for(i=1;i<=cmcnt/2;i++) {
00098               memmove(bufr,buf1+commas[2*i-1],commas[2*i]-commas[2*i-1]);
00099               bufr[commas[2*i]-commas[2*i-1]]=0;
00100               _not(bufr);
00101               if(_type(bufr,commas2,&cmcnt2)!=exp_or)
00102                 snprintf(p+l,MAX_LINELEN-l," and %s",bufr); 
00103               else snprintf(p+l,MAX_LINELEN-l," and (%s)",bufr); 
00104               l=strlen(p);
00105            }
00106            return;
00107        }
00108        case exp_imply: {
00109            
00110            
00111        }
00112        case exp_quantifier: {
00113            
00114            
00115        }
00116        default: {
00117            snprintf(p,MAX_LINELEN,"not(%s)",buf1); return;
00118        }
00119     }
00120 }
00121 
00122        /* Logic reverse an expression */
00123 void req_not(void)
00124 {
00125     int i;
00126     char *p, *ld;
00127     char nbuf[MAX_LINELEN+1];
00128     if(objlinecnt<2) return;
00129     for(i=1;i<objlinecnt;i++) {
00130        thisobjline=i; p=find_word_start(objline[i]);
00131        linelogdir=0; ld="";
00132        if(*p=='>') {
00133            if(logdir<0) continue;
00134            ld=">"; p=find_word_start(p+1); linelogdir=1;
00135        }
00136        else if(*p=='<') {
00137            if(logdir>0) continue;
00138            ld="<"; p=find_word_start(p+1); linelogdir=-1;
00139        }
00140        thislinelen=strlen(p); if(thislinelen<=0) continue;
00141        snprintf(nbuf,sizeof(nbuf),"%s",p);
00142        _not(nbuf); printf("%s %s\n",ld, nbuf);
00143     }
00144 
00145 }
00146