Logo Search packages:      
Sourcecode: wims version File versions  Download package

compare.c

/*    Copyright (C) 1998 XIAO, Gang of Universite de Nice - Sophia Antipolis
 *
 *  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.
 */

void bufprep(char *p)
{
    strip_trailing_spaces(p);
    singlespace(p);
    while(isspace(*p)) strcpy(p,p+1);
}

char *relation_type[]={
      "==", "!=", "<=", ">=", "=", "<", ">",
      "isin", "notin",
      "iswordof", "notwordof",
      "isvarof", "notvarof",
      "isvariableof", "notvariableof",
      "isitemof", "notitemof",
      "islineof", "notlineof",
      "issametext", "notsametext",
      "issamecase", "notsamecase"
};
#define total_relations (sizeof(relation_type)/sizeof(relation_type[0]))

      /* Compares two string. Returns 1 if yes, 0 if no, -1 if error. 
       * In fact, -1 will occur only if module_error() is modified to 
       * return instead of abort. */
      /* TODO: quoted string. */
int compare(char *p, int numerical)
{
    char *Rel, *rel, *first, *second;
    char *p1, *p2, *pp;
    int i, j;
    
    if(check_parentheses(p,0)) {
      error2("unmatched_parentheses"); return -1;
    }
      /* Check global pairs of parentheses */
  remove_parenth:
    p2=strip_trailing_spaces(p);
    p1=find_word_start(p);
    if(*p1=='(' && *p2==')') {
      for(i=1,pp=p1+1; pp<p2 && i>0; pp++) {
          if(*pp=='(') i++; if(*pp==')') i--;
      }
        /* Found global pair of parentheses; remove them, and recheck. */
      if(pp>=p2) {
          *p1=*p2=' '; goto remove_parenth;
      }
    }
    for(p2=wordchr(p,"||"); p2!=NULL; p2=wordchr(p2,"||"))
      string_modify(p,p2,p2+2,"or");
    for(p2=wordchr(p,"&&"); p2!=NULL; p2=wordchr(p2,"&&"))
      string_modify(p,p2,p2+2,"and");
    for(p2=strstr(p,"<>"); p2!=NULL; p2=strstr(p2,"<>")) {
      *p2='!'; *(p2+1)='=';
    }
    Rel=p;
  again_or:
    Rel=wordchr(Rel,"or");
    if(Rel!=NULL) {
      *Rel=0; if(check_parentheses(p,0)) {
          *Rel++='o'; goto again_or;
      }
      i=compare(p,numerical); if(i) return i;
      else return compare(Rel+3,numerical);
    }
    Rel=p;
  again_and:
    Rel=wordchr(Rel,"and");
    if(Rel!=NULL) {
      *Rel=0; if(check_parentheses(p,0)) {
          *Rel++='a'; goto again_and;
      }
      i=compare(p,numerical); if(i<=0) return i;
      else return compare(Rel+4,numerical);
    }
      /* Now a simple relation. */
      /* Inequalities are only for numerical comparisons. */
    if(strchr(p,'<')!=NULL || strchr(p,'>')!=NULL) numerical=1;
    for(i=0;i<total_relations;i++) {
      rel=p-1;
      do {
          rel=strstr(rel+1,relation_type[i]); j=0;
          if(rel>p) {
            *rel=0; j=check_parentheses(p,0);
            *rel=relation_type[i][0];
          }
      }
      while(rel!=NULL && i>6 && j!=0 &&
            ((rel>p && !isspace(*(rel-1))) || 
             !isspace(*(rel+strlen(relation_type[i])))));
      if(rel!=NULL) break;
    }
    if(rel==NULL || i>=total_relations) {
      setenv(error_data_string,"relation not defined",1);
      error2("comp_syntax"); return -1;
    }
    second=rel+strlen(relation_type[i]);
    first=p; *rel=0;
    if(i>6) numerical=0;

       /* the follow now should never occur. Remove? */
    if(check_parentheses(first,0) || check_parentheses(second,0)) {
      error2("unmatched_parentheses"); return -1;
    }
    if(strlen(first)>=MAX_LINELEN || strlen(second)>=MAX_LINELEN) {
      error2("parm_too_long");
      return -1;
    }
    if(numerical) {
        double d1, d2, sum, diff, prec;
      d1=evalue(first); d2=evalue(second);
      sum=d1+d2; if(sum<0) sum=-sum;
      diff=d1-d2; if(diff<0) diff=-diff;
      prec=evalue(getvar("wims_compare_precision"));  /* Move string name to header! */
      diff=diff*prec;
      if(prec>0 && prec<1E10) sum=sum+1/prec;
      switch(i) {
          case 0:
          case 4: /* equal */
              if(sum>=diff) return 1; else return 0;
          case 1: /* not equal */
              if(sum<diff) return 1; else return 0;
          case 2: /* <= */
              if(d1<=d2) return 1; else return 0;
          case 3: /* >= */
              if(d1>=d2) return 1; else return 0;
          case 5: /* < */
              if(d1<d2) return 1; else return 0;
          case 6: /* > */
              if(d1>d2) return 1; else return 0;
      }
    }
    else {
        char buf1[MAX_LINELEN+1], buf2[MAX_LINELEN+1];
      
      first=find_word_start(first); second=find_word_start(second);
      strip_trailing_spaces(first); strip_trailing_spaces(second);
        strcpy(buf1,first); strcpy(buf2,second);
        substitute(buf1); substitute(buf2);
      switch(i) {
          case 0:
          case 4: /* equal */
              if(strcmp(buf1,buf2)==0) return 1; else return 0;
          case 1: /* not equal */
              if(strcmp(buf1,buf2)==0) return 0; else return 1;
          case 7: /* isin */
              if(strstr(buf2,buf1)!=NULL) return 1; else return 0;
          case 8: /* notin */
            if(strstr(buf2,buf1)==NULL) return 1; else return 0;
          
          case 9: /* iswordof */
              if(wordchr(buf2,buf1)!=NULL) return 1; else return 0;
          case 10: /* notwordof */
              if(wordchr(buf2,buf1)==NULL) return 1; else return 0;
          
          case 11: /* isvarof */
          case 13:
              if(varchr(buf2,buf1)!=NULL) return 1; else return 0;
          case 12: /* notvarof */
          case 14:
              if(varchr(buf2,buf1)==NULL) return 1; else return 0;
          
          case 15: /* isitemof */
              if(itemchr(buf2,buf1)!=NULL) return 1; else return 0;
          case 16: /* notitemof */
              if(itemchr(buf2,buf1)==NULL) return 1; else return 0;
          
          case 17: /* islineof */
              if(linechr(buf2,buf1)!=NULL) return 1; else return 0;
          case 18: /* notlineof */
              if(linechr(buf2,buf1)==NULL) return 1; else return 0;
          case 19: { /* issametext */
            bufprep(buf1); bufprep(buf2);
            deaccent(buf1); deaccent(buf2);
              if(strcmp(buf1,buf2)==0) return 1; else return 0;
          }
          case 20: { /* notsametext */
            bufprep(buf1); bufprep(buf2);
            deaccent(buf1); deaccent(buf2);
              if(strcmp(buf1,buf2)==0) return 0; else return 1;
          }
          case 21: { /* issamecase */
            bufprep(buf1); bufprep(buf2);
              if(strcmp(buf1,buf2)==0) return 1; else return 0;
          }
          case 22: { /* notsamecase */
            bufprep(buf1); bufprep(buf2);
              if(strcmp(buf1,buf2)==0) return 0; else return 1;
          }
      }
    }
    error3("compare(): this should never happen.");
    return -1;
}


Generated by  Doxygen 1.6.0   Back to index