Rev 11104 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11104 | Rev 12244 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | * return instead of abort. |
28 | * return instead of abort. |
29 | */ |
29 | */ |
30 | /* TODO: quoted string. */ |
30 | /* TODO: quoted string. */ |
31 | int compare(char *p, int numeric, int lvl) |
31 | int compare(char *p, int numeric, int lvl) |
32 | { |
32 | { |
33 |
|
33 | char *p1, *p2, *pp, *pt; |
34 |
|
34 | char *r1, *r2; |
35 |
|
35 | int i, l, k, r, neg, gotl; |
36 | 36 | ||
37 | /* Check global pairs of parentheses */ |
37 | /* Check global pairs of parentheses */ |
38 |
|
38 | p2=strip_trailing_spaces(p); |
39 |
|
39 | p1=find_word_start(p); |
40 |
|
40 | if(lvl==0 && p2-p1>=MAX_LINELEN-1) module_error("parm_too_long"); |
41 |
|
41 | while(*p1=='(' && *p2==')' && p2==parend(p1)) { |
42 |
|
42 | lvl=0; p1=find_word_start(++p1); |
43 |
|
43 | do p2--; while(p2>=p1 && myisspace(*p2)); |
44 |
|
44 | p2[1]=0; |
- | 45 | } |
|
- | 46 | gotl=100; r1=r2=p1; r=-1; neg=0; |
|
- | 47 | for(pp=p1; *pp; pp++) { |
|
- | 48 | if(*pp==')') {badpar: module_error("unmatched_parentheses"); return -1;} |
|
- | 49 | if(*pp=='(') { |
|
- | 50 | pp=parend(pp); if(pp==NULL) goto badpar; |
|
- | 51 | continue; |
|
45 | } |
52 | } |
46 | gotl=100; r1=r2=p1; r=-1; neg=0; |
- | |
47 | for(pp=p1; *pp; pp++) { |
- | |
48 | if(*pp==')') {badpar: module_error("unmatched_parentheses"); return -1;} |
- | |
49 | if(*pp=='(') { |
- | |
50 | pp=parend(pp); if(pp==NULL) goto badpar; |
- | |
51 | continue; |
- | |
52 | } |
- | |
53 |
|
53 | if(gotl>3) { |
54 |
|
54 | switch(*pp) { |
55 |
|
55 | case '<': { |
56 |
|
56 | gotl=3; r1=pp; r2=r1+1; r=102; neg=0; |
57 |
|
57 | if(*r2=='=') {r2++; r=103; neg=1;} |
58 |
|
58 | if(*r2=='>') { |
59 |
|
59 | r2++; neg=1; |
60 |
|
60 | if(numeric) r=101; else r=0; |
61 | } |
- | |
62 | break; |
- | |
63 | } |
61 | } |
- | 62 | break; |
|
- | 63 | } |
|
64 |
|
64 | case '>': { |
65 |
|
65 | gotl=3; r1=pp; r2=r1+1; r=103; neg=0; |
66 |
|
66 | if(*r2=='=') {r2++; r=102; neg=1;} |
- | 67 | break; |
|
- | 68 | } |
|
- | 69 | case '=': { |
|
- | 70 | gotl=3; neg=0; r1=pp; r2=r1+1; if(*r2=='=') r2++; |
|
- | 71 | if(numeric) r=101; else r=0; |
|
67 |
|
72 | break; |
- | 73 | } |
|
- | 74 | case '!': { |
|
- | 75 | if(pp[1]=='=') { |
|
- | 76 | gotl=3; r1=pp; r2=pp+2; neg=1; |
|
- | 77 | if(numeric) r=101; else r=0; |
|
68 | } |
78 | } |
69 | case '=': { |
- | |
70 | gotl=3; neg=0; r1=pp; r2=r1+1; if(*r2=='=') r2++; |
- | |
71 | if(numeric) r=101; else r=0; |
- | |
72 |
|
79 | break; |
73 | } |
- | |
74 | case '!': { |
- | |
75 | if(pp[1]=='=') { |
- | |
76 | gotl=3; r1=pp; r2=pp+2; neg=1; |
- | |
77 | if(numeric) r=101; else r=0; |
- | |
78 | } |
- | |
79 | break; |
- | |
80 |
|
80 | } |
81 |
|
81 | } |
82 |
|
82 | if(r2>p1) { |
83 |
|
83 | if(lvl==2) break; |
84 |
|
84 | pp=r2-1; continue; |
85 |
|
85 | } |
86 |
|
86 | } |
87 |
|
87 | if(!myisspace(*pp)) continue; |
88 |
|
88 | pp=find_word_start(pp); |
89 |
|
89 | if(gotl>3) { |
90 |
|
90 | if(pp[0]=='i' && pp[1]=='s') {k=2; neg=0; goto isnot;} |
91 |
|
91 | if(pp[0]=='n' && pp[1]=='o' && pp[2]=='t') {k=3; neg=1; goto isnot;} |
92 |
|
92 | goto rel; |
93 |
|
93 | isnot: |
94 |
|
94 | if(strchr("siwlv",pp[k])==NULL) goto rel; |
95 |
|
95 | pt=pp; pp+=k; l=0; |
96 |
|
96 | for(i=0;i<total_relations;i++) { |
97 |
|
97 | l=strlen(relation_type[i]); |
98 |
|
98 | if(strncmp(pp, relation_type[i], l)==0 && |
99 |
|
99 | ((!myisalnum(pp[l]) && pp[l]!='_') || pp[l]==0)) break; |
100 |
|
100 | } |
101 |
|
101 | if(i>=total_relations) {pp--; continue;} |
102 |
|
102 | gotl=3; r=i+1; pp+=l; r1=pt; r2=pp; |
103 |
|
103 | if(lvl==2) break; else {pp--; continue;} |
104 |
|
104 | } |
105 |
|
105 | rel: |
106 |
|
106 | if(*pp!='|' && *pp!='&' && *pp!='a' && *pp!='o') |
107 |
|
107 | {pp--; continue;} |
108 |
|
108 | if(gotl>2 && |
109 | ((myisspace(pp[3]) && strncmp(pp,"and",3)==0) || |
109 | ((myisspace(pp[3]) && strncmp(pp,"and",3)==0) || |
110 |
|
110 | (myisspace(pp[2]) && strncmp(pp,"&&",2)==0))) { |
111 |
|
111 | gotl=2; r1=pp; pp=r2=find_word_end(r1); |
112 |
|
112 | if(lvl==1) break; else {pp--;continue;} |
113 |
|
113 | } |
114 |
|
114 | if(gotl>1 && myisspace(pp[2]) && |
115 |
|
115 | (strncmp(pp,"or",2)==0 || strncmp(pp,"||",2)==0)) { |
116 |
|
116 | gotl=1; r1=pp; r2=pp=r1+2; break; |
117 |
|
117 | } |
118 |
|
118 | } |
119 |
|
119 | if(gotl>20) { |
120 |
|
120 | setvar(error_data_string,"relation not defined"); |
121 |
|
121 | module_error("comp_syntax"); return -1; |
122 |
|
122 | } |
123 | 123 | ||
124 |
|
124 | switch(gotl) { |
125 |
|
125 | case 1: { /* or */ |
126 |
|
126 | *r1=0; i=compare(p1,numeric,1); |
- | 127 | if(i) return i; |
|
127 |
|
128 | else return compare(r2,numeric,0); |
128 |
|
129 | } |
129 |
|
130 | case 2: { /* and */ |
130 |
|
131 | *r1=0; i=compare(p1,numeric,2); if(i<=0) return i; |
131 |
|
132 | else return compare(r2,numeric,1); |
132 |
|
133 | } |
133 |
|
134 | case 3: { /* atomic comparison */ |
134 |
|
135 | if(r<100) { /* textual comparison */ |
135 |
|
136 | static char buf1[MAX_LINELEN+1], buf2[MAX_LINELEN+1]; |
136 |
|
137 | while(r1>p1 && myisspace(r1[-1])) r1--; |
137 |
|
138 | memmove(buf1,p1,r1-p1); buf1[r1-p1]=0; |
138 |
|
139 | r2=find_word_start(r2); |
139 |
|
140 | while(p2>=r2 && myisspace(*p2)) p2--; |
140 |
|
141 | memmove(buf2,r2,p2+1-r2); buf2[p2+1-r2]=0; |
141 |
|
142 | substitute(buf1); substitute(buf2); |
142 |
|
143 | switch(r) { |
143 |
|
144 | case 0: { /* equal */ |
144 |
|
145 | if(strcmp(buf1,buf2)==0) return 1^neg; else return neg; |
145 |
|
146 | } |
146 |
|
147 | case 1: { /* sametext */ |
147 |
|
148 | deaccent(buf1); deaccent(buf2); |
148 |
|
149 | if(strcasecmp(bufprep(buf1),bufprep(buf2))==0) |
149 |
|
150 | return 1^neg; |
150 |
|
151 | else return neg; |
151 |
|
152 | } |
152 |
|
153 | case 2: { /* samecase */ |
153 |
|
154 | if(strcmp(bufprep(buf1),bufprep(buf2))==0) |
154 |
|
155 | return 1^neg; |
155 |
|
156 | else return neg; |
156 |
|
157 | } |
157 |
|
158 | case 3: { /* in */ |
158 |
|
159 | if(strstr(buf2,buf1)!=NULL) return 1^neg; else return neg; |
159 |
|
160 | } |
160 |
|
161 | case 4: { /* wordof */ |
161 |
|
162 | if(wordchr(buf2,buf1)!=NULL) return 1^neg; else return neg; |
162 |
|
163 | } |
163 |
|
164 | case 5: { /* itemof */ |
164 |
|
165 | if(itemchr(buf2,buf1)!=NULL) return 1^neg; else return neg; |
165 |
|
166 | } |
166 |
|
167 | case 6: { /* lineof */ |
167 |
|
168 | if(linechr(buf2,buf1)!=NULL) return 1^neg; else return neg; |
168 |
|
169 | } |
169 |
|
170 | case 7: |
170 |
|
171 | case 8: { /* varof */ |
171 |
|
172 | if(varchr(buf2,buf1)!=NULL) return 1^neg; else return neg; |
172 |
|
173 | } |
173 |
|
174 | } |
174 |
|
175 | } |
175 |
|
176 | else { /* numerical comparison */ |
176 |
|
177 | double d1, d2, sum, diff, prec; |
177 |
|
178 | *r1=0; |
178 |
|
179 | d1=evalue(p1); d2=evalue(r2); |
179 |
|
180 | sum=d1+d2; if(sum<0) sum=-sum; |
180 |
|
181 | diff=d1-d2; if(diff<0) diff=-diff; |
181 |
|
182 | prec=evalue(getvar("wims_compare_precision")); /* Move string name to header! */ |
182 |
|
183 | diff=diff*prec; |
183 |
|
184 | if(prec>0 && prec<1E10) sum=sum+1/prec; |
184 |
|
185 | switch(r) { |
185 |
|
186 | case 101: { /* = */ |
186 |
|
187 | if(sum>=diff) return 1^neg; else return neg; |
187 |
|
188 | } |
188 |
|
189 | case 102: { /* < */ |
189 |
|
190 | if(d1<d2) return 1^neg; else return neg; |
190 |
|
191 | } |
191 |
|
192 | case 103: { /* > */ |
192 |
|
193 | if(d1>d2) return 1^neg; else return neg; |
193 | } |
- | |
194 | default: break; /* should never occur */ |
- | |
195 | } |
194 | } |
- | 195 | default: break; /* should never occur */ |
|
196 |
|
196 | } |
197 | } |
197 | } |
198 | } |
198 | } |
- | 199 | } |
|
199 |
|
200 | internal_error("compare(): this should never happen."); |
200 |
|
201 | return -1; |
201 | } |
202 | } |
202 | - |