Subversion Repositories wimsdev

Rev

Rev 11119 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11119 Rev 12260
Line 20... Line 20...
20
char maskbuf[MAX_LINELEN+1];
20
char maskbuf[MAX_LINELEN+1];
21
 
21
 
22
/* internal routine. */
22
/* internal routine. */
23
void _text_cut(char *p, char *w)
23
void _text_cut(char *p, char *w)
24
{
24
{
25
    char *p1, *p2;
25
  char *p1, *p2;
26
    p1=wordchr(p,w); if(p1==NULL) error("syntax_error");
26
  p1=wordchr(p,w); if(p1==NULL) error("syntax_error");
27
    *p1=0; p2=find_word_start(p1+strlen(w));
27
  *p1=0; p2=find_word_start(p1+strlen(w));
28
    ovlstrcpy(t_buf[0],p); ovlstrcpy(t_buf[1],p2);
28
  ovlstrcpy(t_buf[0],p); ovlstrcpy(t_buf[1],p2);
29
    strip_trailing_spaces(t_buf[0]);
29
  strip_trailing_spaces(t_buf[0]);
30
    substitute(t_buf[0]); substitute(t_buf[1]);
30
  substitute(t_buf[0]); substitute(t_buf[1]);
31
}
31
}
32
 
32
 
33
/* Extract characters in buf[0] which are identical to
33
/* Extract characters in buf[0] which are identical to
34
 * corresponding characters in buf[1]. */
34
 * corresponding characters in buf[1]. */
35
void text_common(char *p)
35
void text_common(char *p)
36
{
36
{
37
    int i,j,n1,n2;
37
  int i,j,n1,n2;
38
    _text_cut(p,"and");
38
  _text_cut(p,"and");
39
    n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
39
  n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
40
    if(n2<n1) n1=n2;
40
  if(n2<n1) n1=n2;
41
    for(i=j=0;i<n1;i++) {
41
  for(i=j=0;i<n1;i++) {
42
      if(t_buf[0][i]==t_buf[1][i] && maskbuf[i]!='0') p[j++]=t_buf[0][i];
42
    if(t_buf[0][i]==t_buf[1][i] && maskbuf[i]!='0') p[j++]=t_buf[0][i];
43
    }
43
  }
44
    p[j]=0;
44
  p[j]=0;
45
}
45
}
46
 
46
 
47
/* Returns a mask string composed of '0's and '1's, where
47
/* Returns a mask string composed of '0's and '1's, where
48
 * '0' means corresponding positions of buf[0] and buf[1] are
48
 * '0' means corresponding positions of buf[0] and buf[1] are
49
 * equal.
49
 * equal.
50
 */
50
 */
51
void text_compare(char *p)
51
void text_compare(char *p)
52
{
52
{
53
    int min,max, i;
53
  int min,max, i;
54
    _text_cut(p,"and");
54
  _text_cut(p,"and");
55
    min=strlen(t_buf[0]); max=strlen(t_buf[1]);
55
  min=strlen(t_buf[0]); max=strlen(t_buf[1]);
56
    if(min>max) {
56
  if(min>max) {
57
      i=min; min=max; max=i;
57
    i=min; min=max; max=i;
58
    }
58
  }
59
    for(i=0; i<min; i++) {
59
  for(i=0; i<min; i++) {
60
      if(t_buf[0][i]==t_buf[1][i]) p[i]='0'; else p[i]='1';
60
    if(t_buf[0][i]==t_buf[1][i]) p[i]='0'; else p[i]='1';
61
    }
61
  }
62
    for(; i<max; i++) p[i]='1';
62
  for(; i<max; i++) p[i]='1';
63
    p[max]=0;
63
  p[max]=0;
64
}
64
}
65
 
65
 
66
/* copy text according to mask. */
66
/* copy text according to mask. */
67
void text_copy(char *p)
67
void text_copy(char *p)
68
{
68
{
69
    int i, j, n;
69
  int i, j, n;
70
 
70
 
71
    snprintf(t_buf[0],MAX_LINELEN,"%s",p);
71
  snprintf(t_buf[0],MAX_LINELEN,"%s",p);
72
    strip_trailing_spaces(t_buf[0]); substitute(t_buf[0]);
72
  strip_trailing_spaces(t_buf[0]); substitute(t_buf[0]);
73
    n=strlen(t_buf[0]);
73
  n=strlen(t_buf[0]);
74
    for(i=j=0;i<n;i++) {
74
  for(i=j=0;i<n;i++) {
75
      if(maskbuf[i]!='0') p[j++]=t_buf[0][i];
75
    if(maskbuf[i]!='0') p[j++]=t_buf[0][i];
76
    }
76
  }
77
    p[j]=0;
77
  p[j]=0;
78
}
78
}
79
 
79
 
80
/* returns count of characters in buf[1] which appear in buf[0]. */
80
/* returns count of characters in buf[1] which appear in buf[0]. */
81
void text_count(char *p)
81
void text_count(char *p)
82
{
82
{
83
    int i, n, c;
83
  int i, n, c;
84
    _text_cut(p,"in");
84
  _text_cut(p,"in");
85
    n=strlen(t_buf[1]);
85
  n=strlen(t_buf[1]);
86
    for(i=c=0;i<n;i++) {
86
  for(i=c=0;i<n;i++) {
87
      if(strchr(t_buf[0],t_buf[1][i])!=NULL && maskbuf[i]!='0') c++;
87
    if(strchr(t_buf[0],t_buf[1][i])!=NULL && maskbuf[i]!='0') c++;
88
    }
88
  }
89
    snprintf(p,MAX_LINELEN,"%d",c);
89
  snprintf(p,MAX_LINELEN,"%d",c);
90
}
90
}
91
 
91
 
92
/* Extract characters in buf[0] which are different than
92
/* Extract characters in buf[0] which are different than
93
 * corresponding characters in buf[1].
93
 * corresponding characters in buf[1].
94
 */
94
 */
95
void text_diff(char *p)
95
void text_diff(char *p)
96
{
96
{
97
    int i,j,n1,n2;
97
  int i,j,n1,n2;
98
    _text_cut(p,"from");
98
  _text_cut(p,"from");
99
    n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
99
  n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
100
    if(n2<n1) n1=n2;
100
  if(n2<n1) n1=n2;
101
    for(i=j=0;i<n1;i++) {
101
  for(i=j=0;i<n1;i++) {
102
      if(t_buf[0][i]!=t_buf[1][i] && maskbuf[i]!='0') p[j++]=t_buf[0][i];
102
    if(t_buf[0][i]!=t_buf[1][i] && maskbuf[i]!='0') p[j++]=t_buf[0][i];
103
    }
103
  }
104
    p[j]=0;
104
  p[j]=0;
105
}
105
}
106
 
106
 
107
/* put chars in buf[0] in a new string, into positions
107
/* put chars in buf[0] in a new string, into positions
108
 * corresponding to '1's in the mask buf[1].
108
 * corresponding to '1's in the mask buf[1].
109
 * Positions corresponding to '0's are filled by space.
109
 * Positions corresponding to '0's are filled by space.
110
 * Fill stops at the end of buf[0]. If buf[1] is
110
 * Fill stops at the end of buf[0]. If buf[1] is
111
 * too short, it is reused from the start.
111
 * too short, it is reused from the start.
112
 * FIXME: using 0 as a mask gives a bug
112
 * FIXME: using 0 as a mask gives a bug
113
 */
113
 */
114
/*
114
/*
115
   @@ !text expand abcdef mask 01
115
   @@ !text expand abcdef mask 01
116
   @@ a b c d e f
116
   @@ a b c d e f
117
   @@ !text expand abcdef mask 011
117
   @@ !text expand abcdef mask 011
118
   @@ ab cd e
118
   @@ ab cd e
119
   @@ !text expand abcdefg using 101110
119
   @@ !text expand abcdefg using 101110
120
   @@ a bcd e fg
120
   @@ a bcd e fg
121
 */
121
 */
122
void text_expand(char *p)
122
void text_expand(char *p)
123
{
123
{
124
    int i,j,k,n1,n2;
124
  int i,j,k,n1,n2;
125
    _text_cut(p,"using");
125
  _text_cut(p,"using");
126
    n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
126
  n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
127
    if(n2==0) {p[0]=0; return;}
127
  if(n2==0) {p[0]=0; return;}
128
    for(i=j=k=0;i<n1 && j<MAX_LINELEN;j++,k=j%n2) {
128
  for(i=j=k=0;i<n1 && j<MAX_LINELEN;j++,k=j%n2) {
129
      if(t_buf[1][k]=='0') p[j]=' ';
129
    if(t_buf[1][k]=='0') p[j]=' ';
130
      else p[j]=t_buf[0][i++];
130
    else p[j]=t_buf[0][i++];
131
    }
131
  }
132
    p[j]=0;
132
  p[j]=0;
133
}
133
}
134
 
134
 
135
/* character by character replacement of buf[1] by buf[0],
135
/* character by character replacement of buf[1] by buf[0],
136
 * replacing only mask-effective chars.
136
 * replacing only mask-effective chars.
137
 * The resulting string is as long as buf[1], and the replacement
137
 * The resulting string is as long as buf[1], and the replacement
138
 * stops when chars buf[0] has run out.
138
 * stops when chars buf[0] has run out.
139
 */
139
 */
140
/*
140
/*
141
  @@ !text insert abcefg into hijkl mask 10100
141
  @@ !text insert abcefg into hijkl mask 10100
142
  @@ aibkl
142
  @@ aibkl
143
 */
143
 */
144
void text_insert(char *p)
144
void text_insert(char *p)
145
{
145
{
146
    int i,j,n1,n2;
146
  int i,j,n1,n2;
147
    _text_cut(p,"into");
147
  _text_cut(p,"into");
148
    n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
148
  n1=strlen(t_buf[0]);n2=strlen(t_buf[1]);
149
    for(i=j=0; i<n2 && j<n1; i++) {
149
  for(i=j=0; i<n2 && j<n1; i++) {
150
      if(maskbuf[i]!='0') t_buf[1][i]=t_buf[0][j++];
150
    if(maskbuf[i]!='0') t_buf[1][i]=t_buf[0][j++];
151
    }
151
  }
152
    snprintf(p,MAX_LINELEN,"%s",t_buf[1]);
152
  snprintf(p,MAX_LINELEN,"%s",t_buf[1]);
153
}
153
}
154
 
154
 
155
#define MAX_TLEN 96
155
#define MAX_TLEN 96
156
 
156
 
157
/* interact of two strings according to rules
157
/* interact of two strings according to rules
158
 * defined a table.
158
 * defined a table.
159
 */
159
 */
160
void text_interact(char *p)
160
void text_interact(char *p)
161
{
161
{
162
    char *table, *dline, *tline[MAX_TLEN];
162
  char *table, *dline, *tline[MAX_TLEN];
163
    char *p1, *p2;
163
  char *p1, *p2;
164
    int i,j1,j2,k,l,l2,n;
164
  int i,j1,j2,k,l,l2,n;
165
 
165
 
166
    table=wordchr(p,"table");
166
  table=wordchr(p,"table");
167
    if(table==NULL) error("syntax_error");
167
  if(table==NULL) error("syntax_error");
168
    *table=0; strip_trailing_spaces(p);
168
  *table=0; strip_trailing_spaces(p);
169
    table=find_word_start(table+strlen("table"));
169
  table=find_word_start(table+strlen("table"));
170
    snprintf(t_buf[2],MAX_LINELEN,"%s",table);
170
  snprintf(t_buf[2],MAX_LINELEN,"%s",table);
171
    _text_cut(p,"and");
171
  _text_cut(p,"and");
172
    strip_trailing_spaces(t_buf[2]); substitute(t_buf[2]);
172
  strip_trailing_spaces(t_buf[2]); substitute(t_buf[2]);
173
    n=linenum(t_buf[2])-1;
173
  n=linenum(t_buf[2])-1;
174
    if(n>=MAX_TLEN) error("text_bad_table");
174
  if(n>=MAX_TLEN) error("text_bad_table");
175
    p2=strchr(t_buf[2],'\n'); if(p2!=NULL) *p2++=0;
175
  p2=strchr(t_buf[2],'\n'); if(p2!=NULL) *p2++=0;
176
    if(strlen(t_buf[2])!=n) error("text_bad_table");
176
  if(strlen(t_buf[2])!=n) error("text_bad_table");
177
    dline=t_buf[2];
177
  dline=t_buf[2];
178
    for(i=0,p1=p2;i<n;i++,p1=p2) {
178
  for(i=0,p1=p2;i<n;i++,p1=p2) {
179
      if(p1==NULL) error("text_bad_table");
179
    if(p1==NULL) error("text_bad_table");
180
      p2=strchr(p1,'\n');
180
    p2=strchr(p1,'\n');
181
      if(p2!=NULL) *p2++=0;
181
    if(p2!=NULL) *p2++=0;
182
      if(strlen(p1)!=n) error("text_bad_table");
182
    if(strlen(p1)!=n) error("text_bad_table");
183
      tline[i]=p1;
183
    tline[i]=p1;
184
    }
184
  }
185
    l=strlen(t_buf[0]); l2=strlen(t_buf[1]); if(l2<l) l=l2;
185
  l=strlen(t_buf[0]); l2=strlen(t_buf[1]); if(l2<l) l=l2;
186
    for(i=k=0;i<l;i++) {
186
  for(i=k=0;i<l;i++) {
187
      if(maskbuf[i]!='0') {
187
    if(maskbuf[i]!='0') {
188
          p1=strchr(dline,t_buf[0][i]);
188
      p1=strchr(dline,t_buf[0][i]);
189
          p2=strchr(dline,t_buf[1][i]);
189
      p2=strchr(dline,t_buf[1][i]);
190
          if(p1==NULL || p2==NULL) continue;
190
      if(p1==NULL || p2==NULL) continue;
191
          j1=p1-dline; j2=p2-dline;
191
      j1=p1-dline; j2=p2-dline;
192
          if(j1>=n || j2>=n) continue; /* should not occur */
192
      if(j1>=n || j2>=n) continue; /* should not occur */
193
          p[k++]=tline[j1][j2];
193
      p[k++]=tline[j1][j2];
194
      }
194
    }
195
    }
195
  }
196
    p[k]=0;
196
  p[k]=0;
197
}
197
}
198
 
198
 
199
/* returns a mask string composed of '0's and '1's, where
199
/* returns a mask string composed of '0's and '1's, where
200
 * '0' means corresponding char in buf[1] appears in buf[0].
200
 * '0' means corresponding char in buf[1] appears in buf[0].
201
 */
201
 */
202
/*
202
/*
203
   @@ !text mark a in abcaefa
203
   @@ !text mark a in abcaefa
204
   @@ 001001
204
   @@ 001001
205
 */
205
 */
206
void text_mark(char *p)
206
void text_mark(char *p)
207
{
207
{
208
    int i, n;
208
  int i, n;
209
    _text_cut(p,"in");
209
  _text_cut(p,"in");
210
    n=strlen(t_buf[1]);
210
  n=strlen(t_buf[1]);
211
    for(i=0;i<n;i++) {
211
  for(i=0;i<n;i++) {
212
      if(strchr(t_buf[0],t_buf[1][i])!=NULL) p[i]='1';
212
    if(strchr(t_buf[0],t_buf[1][i])!=NULL) p[i]='1';
213
      else p[i]='0';
213
    else p[i]='0';
214
    }
214
  }
215
    p[i]=0;
215
  p[i]=0;
216
}
216
}
217
 
217
 
218
/* Returns a string whose characters are the maximum
218
/* Returns a string whose characters are the maximum
219
 * of the two corresponding chars in buf[0] and buf[1].
219
 * of the two corresponding chars in buf[0] and buf[1].
220
 * Length of the string is the longuest one.
220
 * Length of the string is the longuest one.
221
 */
221
 */
222
void text_max(char *p)
222
void text_max(char *p)
223
{
223
{
224
    int min,max, i, j, k;
224
  int min,max, i, j, k;
225
    _text_cut(p,"and");
225
  _text_cut(p,"and");
226
    min=strlen(t_buf[0]); max=strlen(t_buf[1]);
226
  min=strlen(t_buf[0]); max=strlen(t_buf[1]);
227
    if(min>max) {
227
  if(min>max) {
228
      i=min; min=max; max=i; j=0;
228
    i=min; min=max; max=i; j=0;
229
    }
229
  }
230
    else j=1;
230
  else j=1;
231
    for(i=k=0; i<min; i++) {
231
  for(i=k=0; i<min; i++) {
232
      if(maskbuf[i]=='0') continue;
232
    if(maskbuf[i]=='0') continue;
233
      if((unsigned char)t_buf[0][i]>(unsigned char)t_buf[1][i])
233
    if((unsigned char)t_buf[0][i]>(unsigned char)t_buf[1][i])
234
          p[k++]=t_buf[0][i];
234
      p[k++]=t_buf[0][i];
235
      else p[k++]=t_buf[1][i];
235
    else p[k++]=t_buf[1][i];
236
    }
236
  }
237
    for(;i<max;i++) {
237
  for(;i<max;i++) {
238
      if(maskbuf[i]!='0') p[k++]=t_buf[j][i];
238
    if(maskbuf[i]!='0') p[k++]=t_buf[j][i];
239
    }
239
  }
240
    p[k]=0;
240
  p[k]=0;
241
}
241
}
242
 
242
 
243
/* Returns a string whose characters are the minimum
243
/* Returns a string whose characters are the minimum
244
 * of the two corresponding chars in buf[0] and buf[1].
244
 * of the two corresponding chars in buf[0] and buf[1].
245
 * Length of the string is the shortest one.
245
 * Length of the string is the shortest one.
246
 */
246
 */
247
void text_min(char *p)
247
void text_min(char *p)
248
{
248
{
249
    int min,max, i,k;
249
  int min,max, i,k;
250
    _text_cut(p,"and");
250
  _text_cut(p,"and");
251
    min=strlen(t_buf[0]); max=strlen(t_buf[1]);
251
  min=strlen(t_buf[0]); max=strlen(t_buf[1]);
252
    if(min>max) {
252
  if(min>max) {
253
      i=min; min=max; max=i;
253
    i=min; min=max; max=i;
254
    }
254
  }
255
    for(i=k=0; i<min; i++) {
255
  for(i=k=0; i<min; i++) {
256
      if(maskbuf[i]=='0') continue;
256
    if(maskbuf[i]=='0') continue;
257
      if((unsigned char)t_buf[0][i]< (unsigned char)t_buf[1][i])
257
    if((unsigned char)t_buf[0][i]< (unsigned char)t_buf[1][i])
258
          p[k++]=t_buf[0][i];
258
      p[k++]=t_buf[0][i];
259
      else p[k++]=t_buf[1][i];
259
    else p[k++]=t_buf[1][i];
260
    }
260
  }
261
    p[k]=0;
261
  p[k]=0;
262
}
262
}
263
 
263
 
264
/* extract chars in buf[0] which occur in buf[1]. */
264
/* extract chars in buf[0] which occur in buf[1]. */
265
void text_occur(char *p)
265
void text_occur(char *p)
266
{
266
{
267
    int i,j,n;
267
  int i,j,n;
268
    char buf[MAX_LINELEN+1];
268
  char buf[MAX_LINELEN+1];
269
    memset(buf,0,sizeof(buf));
269
  memset(buf,0,sizeof(buf));
270
    _text_cut(p,"in");
270
  _text_cut(p,"in");
271
    n=strlen(t_buf[1]);
271
  n=strlen(t_buf[1]);
272
    for(i=0;i<n;i++) {
272
  for(i=0;i<n;i++) {
273
      char *pp;
273
    char *pp;
274
      if(maskbuf[i]=='0') continue;
274
    if(maskbuf[i]=='0') continue;
275
      pp=strchr(t_buf[0],t_buf[1][i]);
275
    pp=strchr(t_buf[0],t_buf[1][i]);
276
      if(pp!=NULL) buf[pp - t_buf[0]]=1;
276
    if(pp!=NULL) buf[pp - t_buf[0]]=1;
277
    }
277
  }
278
    n=strlen(t_buf[0]);
278
  n=strlen(t_buf[0]);
279
    for(i=j=0;i<n;i++) {
279
  for(i=j=0;i<n;i++) {
280
      if(buf[i]) p[j++]=t_buf[0][i];
280
    if(buf[i]) p[j++]=t_buf[0][i];
281
    }
281
  }
282
    p[j]=0;
282
  p[j]=0;
283
}
283
}
284
 
284
 
285
/* remove characters of buf[1] in buf[0]. */
285
/* remove characters of buf[1] in buf[0]. */
286
void text_remove(char *p)
286
void text_remove(char *p)
287
{
287
{
288
    int i, j, n;
288
  int i, j, n;
289
    _text_cut(p,"in");
289
  _text_cut(p,"in");
290
    n=strlen(t_buf[1]);
290
  n=strlen(t_buf[1]);
291
    for(i=j=0;i<n;i++) {
291
  for(i=j=0;i<n;i++) {
292
      if(strchr(t_buf[0],t_buf[1][i])==NULL
292
    if(strchr(t_buf[0],t_buf[1][i])==NULL
293
         && maskbuf[i]!='0') p[j++]=t_buf[1][i];
293
       && maskbuf[i]!='0') p[j++]=t_buf[1][i];
294
    }
294
  }
295
    p[j]=0;
295
  p[j]=0;
296
}
296
}
297
 
297
 
298
/* Cyclic reordering of text. */
298
/* Cyclic reordering of text. */
299
void text_reorder(char *p)
299
void text_reorder(char *p)
300
{
300
{
301
    int i,j,k,l,n,t;
301
  int i,j,k,l,n,t;
302
    int list[10240];
302
  int list[10240];
303
    char buf[MAX_LINELEN+1];
303
  char buf[MAX_LINELEN+1];
304
    _text_cut(p,"by"); *p=0;
304
  _text_cut(p,"by"); *p=0;
305
    n=itemnum(t_buf[1]); if(n<=0 || n>=10240) return;
305
  n=itemnum(t_buf[1]); if(n<=0 || n>=10240) return;
306
    for(i=0;i<n;i++) {
306
  for(i=0;i<n;i++) {
307
        buf[0]=0; fnd_item(t_buf[1],i+1,buf);
307
    buf[0]=0; fnd_item(t_buf[1],i+1,buf);
308
      j=atoi(buf); if(j<=0 || j>n) return;
308
    j=atoi(buf); if(j<=0 || j>n) return;
309
      list[i]=j;
309
    list[i]=j;
310
    }
310
  }
311
    t=strlen(t_buf[0]);
311
  t=strlen(t_buf[0]);
312
    for(i=l=0;l<t && i<t+n;i++) {
312
  for(i=l=0;l<t && i<t+n;i++) {
313
      j=i/n; k=j*n+list[i%n];
313
    j=i/n; k=j*n+list[i%n];
314
      if(k>t || k<=0) continue;
314
    if(k>t || k<=0) continue;
315
      p[l++]=t_buf[0][k-1];
315
    p[l++]=t_buf[0][k-1];
316
    }
316
  }
317
    p[l]=0;
317
  p[l]=0;
318
}
318
}
319
 
319
 
320
/* repeat a string to a given length. */
320
/* repeat a string to a given length. */
321
void text_repeat(char *p)
321
void text_repeat(char *p)
322
{
322
{
323
    int n,i,k;
323
  int n,i,k;
324
    _text_cut(p,"to");
324
  _text_cut(p,"to");
325
    n=strevalue(t_buf[1]); if(n>MAX_LINELEN) n=MAX_LINELEN;
325
  n=strevalue(t_buf[1]); if(n>MAX_LINELEN) n=MAX_LINELEN;
326
    if(n<0) n=0;
326
  if(n<0) n=0;
327
    k=strlen(t_buf[0]); if(k<=0) {*p=0; return;}
327
  k=strlen(t_buf[0]); if(k<=0) {*p=0; return;}
328
    for(i=0;i<n;i++) {
328
  for(i=0;i<n;i++) {
329
      p[i]=t_buf[0][i%k];
329
    p[i]=t_buf[0][i%k];
330
    }
330
  }
331
    p[i]=0;
331
  p[i]=0;
332
}
332
}
333
 
333
 
334
/* reverse a string */
334
/* reverse a string */
335
void text_reverse(char *p)
335
void text_reverse(char *p)
336
{
336
{
337
    int i,n;
337
  int i,n;
338
    char buf[MAX_LINELEN+1];
338
  char buf[MAX_LINELEN+1];
339
    snprintf(t_buf[0],sizeof(t_buf[0]),"%s",p);
339
  snprintf(t_buf[0],sizeof(t_buf[0]),"%s",p);
340
    substitute(t_buf[0]);
340
  substitute(t_buf[0]);
341
    n=strlen(t_buf[0]); if(n>MAX_LINELEN) n=MAX_LINELEN;
341
  n=strlen(t_buf[0]); if(n>MAX_LINELEN) n=MAX_LINELEN;
342
    for(i=0;i<n;i++) buf[i]=t_buf[0][n-1-i];
342
  for(i=0;i<n;i++) buf[i]=t_buf[0][n-1-i];
343
    buf[n]=0;
343
  buf[n]=0;
344
    ovlstrcpy(p,buf);
344
  ovlstrcpy(p,buf);
345
}
345
}
346
 
346
 
347
/* remove characters of buf[1] not in buf[0]. */
347
/* remove characters of buf[1] not in buf[0]. */
348
void text_select(char *p)
348
void text_select(char *p)
349
{
349
{
350
    int i, j, n;
350
  int i, j, n;
351
    _text_cut(p,"in");
351
  _text_cut(p,"in");
352
    n=strlen(t_buf[1]);
352
  n=strlen(t_buf[1]);
353
    for(i=j=0;i<n;i++) {
353
  for(i=j=0;i<n;i++) {
354
      if(strchr(t_buf[0],t_buf[1][i])!=NULL
354
    if(strchr(t_buf[0],t_buf[1][i])!=NULL
355
         && maskbuf[i]!='0') p[j++]=t_buf[1][i];
355
       && maskbuf[i]!='0') p[j++]=t_buf[1][i];
356
    }
356
  }
357
    p[j]=0;
357
  p[j]=0;
358
}
358
}
359
 
359
 
360
/* tag: bit 0 is mask. */
360
/* tag: bit 0 is mask. */
361
struct {
361
struct {
362
    char *name;
362
  char *name;
363
    int tag;
363
  int tag;
364
    void (*routine) (char *p);
364
  void (*routine) (char *p);
365
} text_proc[]={
365
} text_proc[]={
366
      {"appear",    1,  text_occur},
366
  {"appear",    1,  text_occur},
367
      {"common",    1,  text_common},
367
  {"common",    1,  text_common},
368
      {"compare",   0,  text_compare},
368
  {"compare",   0,  text_compare},
369
      {"copy",      1,  text_copy},
369
  {"copy",      1,  text_copy},
370
      {"count",     1,  text_count},
370
  {"count",     1,  text_count},
371
      {"delete",    1,  text_remove},
371
  {"delete",    1,  text_remove},
372
      {"diff",      1,  text_diff},
372
  {"diff",      1,  text_diff},
373
      {"differ",    1,  text_diff},
373
  {"differ",    1,  text_diff},
374
      {"drop",      1,  text_remove},
374
  {"drop",      1,  text_remove},
375
      {"expand",    0,  text_expand},
375
  {"expand",    0,  text_expand},
376
      {"extract",   1,  text_select},
376
  {"extract",   1,  text_select},
377
      {"insert",    1,  text_insert},
377
  {"insert",    1,  text_insert},
378
      {"interact",  1,  text_interact},
378
  {"interact",  1,  text_interact},
379
      {"mark",      0,  text_mark},
379
  {"mark",      0,  text_mark},
380
      {"max",       1,  text_max},
380
  {"max",       1,  text_max},
381
      {"min",       1,  text_min},
381
  {"min",       1,  text_min},
382
      {"occur",     1,  text_occur},
382
  {"occur",     1,  text_occur},
383
      {"occurrence",1,  text_occur},
383
  {"occurrence",1,  text_occur},
384
      {"pick",      1,  text_select},
384
  {"pick",      1,  text_select},
385
      {"pickup",    1,  text_select},
385
  {"pickup",    1,  text_select},
386
      {"remove",    1,  text_remove},
386
  {"remove",    1,  text_remove},
387
      {"reorder",   0,  text_reorder},
387
  {"reorder",   0,  text_reorder},
388
      {"repeat",    0,  text_repeat},
388
  {"repeat",    0,  text_repeat},
389
      {"reverse",   0,  text_reverse},
389
  {"reverse",   0,  text_reverse},
390
      {"select",    1,  text_select}
390
  {"select",    1,  text_select}
391
};
391
};
392
#define TEXT_PROC_NO (sizeof(text_proc)/sizeof(text_proc[0]))
392
#define TEXT_PROC_NO (sizeof(text_proc)/sizeof(text_proc[0]))
393
 
393
 
394
int textab_verify(void) {
394
int textab_verify(void)
-
 
395
{
395
    return verify_order(text_proc,TEXT_PROC_NO,sizeof(text_proc[0]));
396
  return verify_order(text_proc,TEXT_PROC_NO,sizeof(text_proc[0]));
396
}
397
}
397
 
398
 
398
/* main entry point for text routines */
399
/* main entry point for text routines */
399
void text(char *p)
400
void text(char *p)
400
{
401
{
401
    int i,j,n;
402
  int i,j,n;
402
    char *p1, *p2;
403
  char *p1, *p2;
403
    char c,cc;
404
  char c,cc;
404
    char buf[MAX_LINELEN+1];
405
  char buf[MAX_LINELEN+1];
405
    p1=find_word_start(p); p2=find_word_end(p1);
406
  p1=find_word_start(p); p2=find_word_end(p1);
406
    if(p2<=p1 || *p2==0) error("syntax_error");
407
  if(p2<=p1 || *p2==0) error("syntax_error");
407
    *p2=0;
408
  *p2=0;
408
    i=search_list(text_proc,TEXT_PROC_NO,sizeof(text_proc[0]),p1);
409
  i=search_list(text_proc,TEXT_PROC_NO,sizeof(text_proc[0]),p1);
409
    if(i<0) error("syntax_error");
410
  if(i<0) error("syntax_error");
410
    snprintf(buf,sizeof(buf),"%s",find_word_start(p2+1));
411
  snprintf(buf,sizeof(buf),"%s",find_word_start(p2+1));
411
    if((text_proc[i].tag&1)!=0 && (p1=wordchr(buf,"mask"))!=NULL) {
412
  if((text_proc[i].tag&1)!=0 && (p1=wordchr(buf,"mask"))!=NULL) {
412
      *p1=0; strip_trailing_spaces(buf);
413
    *p1=0; strip_trailing_spaces(buf);
413
      p2=find_word_start(p1+strlen("mask"));
414
    p2=find_word_start(p1+strlen("mask"));
414
      strip_trailing_spaces(p2);
415
    strip_trailing_spaces(p2);
415
      snprintf(maskbuf,sizeof(maskbuf),"%s",p2);
416
    snprintf(maskbuf,sizeof(maskbuf),"%s",p2);
416
      substitute(maskbuf);
417
    substitute(maskbuf);
417
      n=strlen(maskbuf); if(n==0) goto zeromask;
418
    n=strlen(maskbuf); if(n==0) goto zeromask;
418
      c=maskbuf[n-1]; cc=0;
419
    c=maskbuf[n-1]; cc=0;
419
      if(c=='+') cc='1';
420
    if(c=='+') cc='1';
420
      if(c=='-') cc='0';
421
    if(c=='-') cc='0';
421
      if(cc!=0) memset(maskbuf+n-1,cc,sizeof(maskbuf)-n);
422
    if(cc!=0) memset(maskbuf+n-1,cc,sizeof(maskbuf)-n);
422
      else for(j=n;j<MAX_LINELEN;j++) maskbuf[j]=maskbuf[j%n];
423
    else for(j=n;j<MAX_LINELEN;j++) maskbuf[j]=maskbuf[j%n];
423
      maskbuf[sizeof(maskbuf)-1]=0;
424
    maskbuf[sizeof(maskbuf)-1]=0;
424
    }
425
  }
425
    else zeromask: memset(maskbuf,0,sizeof(maskbuf));
426
  else zeromask: memset(maskbuf,0,sizeof(maskbuf));
426
    text_proc[i].routine(buf);
427
  text_proc[i].routine(buf);
427
    buf[MAX_LINELEN]=0;ovlstrcpy(p,buf);
428
  buf[MAX_LINELEN]=0;ovlstrcpy(p,buf);
428
}
429
}