Subversion Repositories wimsdev

Rev

Rev 8185 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 2002-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18. #include "mathexp.h"
  19.  
  20. struct {
  21.     char *orig, *reverse;
  22. } revtab[]={
  23.     {"=", "!="},
  24.     {"!=", "="},
  25.     {"==", "!="},
  26.     {"<>", "="},
  27.     {"<", ">="},
  28.     {">", "<="},
  29.     {"<=", ">"},
  30.     {">=", "<"},
  31.     {"and", "or"},
  32.     {"or", "and"},
  33. };
  34. #define revno (sizeof(revtab)/sizeof(revtab[0]))
  35.  
  36. /* p will contain the new exp, and must has a buffer of MAX_LINELEN+1 */
  37. void _not(char *p)
  38. {
  39.     char buf1[MAX_LINELEN+1], bufr[MAX_LINELEN+1];
  40.     char buft[16];
  41.     int commas[MAX_COMMAS], cmcnt;
  42.     char *pp;
  43.     int i, l;
  44.  
  45.     snprintf(buf1,sizeof(buf1),"%s",find_word_start(p));
  46.     retype:
  47.     if(buf1[0]==0) {*p=0; return;} /* empty */
  48.     strip_trailing_spaces(buf1);
  49.     switch(_type(buf1,commas,&cmcnt)) {
  50.      case exp_paren: {
  51.          if(buf1[0]=='(' && find_matching(buf1+1,')')==buf1+strlen(buf1)-1) {
  52.            buf1[strlen(buf1)-1]=0; ovlstrcpy(buf1,find_word_start(buf1+1));
  53.            goto retype;
  54.          }
  55.          snprintf(p,MAX_LINELEN,"not %s",buf1); return;
  56.      }
  57.      case exp_not: {
  58.          if(strncasecmp(buf1,"not",3)!=0) error("Syntax error.");
  59.          pp=find_word_start(buf1+3);
  60.          if(*pp=='(' && find_matching(pp+1,')')==pp+strlen(pp)-1) {
  61.           pp++; *(pp+strlen(pp)-1)=0;
  62.          }
  63.          snprintf(p,MAX_LINELEN,"%s",pp); return;
  64.      }
  65.      case exp_ineq:
  66.      case exp_eq: {
  67.          if(cmcnt!=2 || commas[1]-commas[0]>4) error("Syntax error.");
  68.          memmove(buft,buf1+commas[0],commas[1]-commas[0]);
  69.          buft[commas[1]-commas[0]]=0;
  70.          for(i=0;i<revno && strcmp(buft,revtab[i].orig)!=0;i++);
  71.          if(i>=revno) error("Software bug: bad sign.");
  72.          string_modify(buf1,buf1+commas[0],buf1+commas[1],revtab[i].reverse);
  73.          snprintf(p,MAX_LINELEN,"%s",buf1);
  74.          return;
  75.      }
  76.      case exp_and: {
  77.          if(cmcnt<2 || (cmcnt&1)!=0) error("Syntax error.");
  78.          commas[cmcnt]=strlen(buf1);
  79.          memmove(bufr,buf1,commas[0]); bufr[commas[0]]=0;
  80.          _not(bufr); snprintf(p,MAX_LINELEN+1,"%s",bufr); l=strlen(p);
  81.          for(i=1;i<=cmcnt/2;i++) {
  82.           memmove(bufr,buf1+commas[2*i-1],commas[2*i]-commas[2*i-1]);
  83.           bufr[commas[2*i]-commas[2*i-1]]=0;
  84.           _not(bufr);
  85.           snprintf(p+l,MAX_LINELEN-l," or %s",bufr); l=strlen(p);
  86.          }
  87.          return;
  88.      }
  89.      case exp_or: {
  90.          int commas2[MAX_COMMAS], cmcnt2;
  91.          if(cmcnt<2 || (cmcnt&1)!=0) error("Syntax error.");
  92.          commas[cmcnt]=strlen(buf1);
  93.          memmove(bufr,buf1,commas[0]); bufr[commas[0]]=0;
  94.          _not(bufr);
  95.          if(_type(bufr,commas2,&cmcnt2)!=exp_or)
  96.            snprintf(p,MAX_LINELEN+1,"%s",bufr);
  97.          else snprintf(p,MAX_LINELEN+3,"(%s)",bufr);
  98.          l=strlen(p);
  99.          for(i=1;i<=cmcnt/2;i++) {
  100.           memmove(bufr,buf1+commas[2*i-1],commas[2*i]-commas[2*i-1]);
  101.           bufr[commas[2*i]-commas[2*i-1]]=0;
  102.           _not(bufr);
  103.           if(_type(bufr,commas2,&cmcnt2)!=exp_or)
  104.             snprintf(p+l,MAX_LINELEN-l," and %s",bufr);
  105.           else snprintf(p+l,MAX_LINELEN-l," and (%s)",bufr);
  106.           l=strlen(p);
  107.          }
  108.          return;
  109.      }
  110.      case exp_imply: {
  111.  
  112.  
  113.      }
  114.      case exp_quantifier: {
  115.  
  116.  
  117.      }
  118.      default: {
  119.          snprintf(p,MAX_LINELEN,"not(%s)",buf1); return;
  120.      }
  121.     }
  122. }
  123.  
  124. /* Logic reverse an expression */
  125. void req_not(void)
  126. {
  127.     int i;
  128.     char *p, *ld;
  129.     char nbuf[MAX_LINELEN+1];
  130.     if(objlinecnt<2) return;
  131.     for(i=1;i<objlinecnt;i++) {
  132.      thisobjline=i; p=find_word_start(objline[i]);
  133.      linelogdir=0; ld="";
  134.      if(*p=='>') {
  135.          if(logdir<0) continue;
  136.          ld=">"; p=find_word_start(p+1); linelogdir=1;
  137.      }
  138.      else if(*p=='<') {
  139.          if(logdir>0) continue;
  140.          ld="<"; p=find_word_start(p+1); linelogdir=-1;
  141.      }
  142.      thislinelen=strlen(p); if(thislinelen<=0) continue;
  143.      snprintf(nbuf,sizeof(nbuf),"%s",p);
  144.      _not(nbuf); printf("%s %s\n",ld, nbuf);
  145.     }
  146. }
  147.