Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/tagging.c
Parent Directory
|
Revision Log
Revision 797 -
(hide annotations)
(download)
(as text)
Sat Jun 25 18:21:19 2011 UTC (13 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 16769 byte(s)
Sat Jun 25 18:21:19 2011 UTC (13 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 16769 byte(s)
Add some functions to free the tagging rules when they have been used.
1 | amb | 393 | /*************************************** |
2 | amb | 494 | $Header: /home/amb/CVS/routino/src/tagging.c,v 1.5 2010-09-17 17:40:41 amb Exp $ |
3 | amb | 393 | |
4 | Load the tagging rules from a file and the functions for handling them. | ||
5 | |||
6 | Part of the Routino routing software. | ||
7 | ******************/ /****************** | ||
8 | amb | 754 | This file Copyright 2010, 2011 Andrew M. Bishop |
9 | amb | 393 | |
10 | This program is free software: you can redistribute it and/or modify | ||
11 | it under the terms of the GNU Affero General Public License as published by | ||
12 | the Free Software Foundation, either version 3 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU Affero General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU Affero General Public License | ||
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | ***************************************/ | ||
23 | |||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include <stdlib.h> | ||
28 | |||
29 | amb | 449 | #include "files.h" |
30 | amb | 393 | #include "tagging.h" |
31 | #include "xmlparse.h" | ||
32 | |||
33 | |||
34 | /* Global variables */ | ||
35 | |||
36 | TaggingRuleList NodeRules={NULL,0}; | ||
37 | TaggingRuleList WayRules={NULL,0}; | ||
38 | TaggingRuleList RelationRules={NULL,0}; | ||
39 | |||
40 | |||
41 | /* Local variables */ | ||
42 | |||
43 | TaggingRuleList *current_list=NULL; | ||
44 | TaggingRule *current_rule=NULL; | ||
45 | |||
46 | |||
47 | /* Local functions */ | ||
48 | |||
49 | static void apply_actions(TaggingRule *rule,int match,TagList *input,TagList *output); | ||
50 | |||
51 | |||
52 | /* The XML tag processing function prototypes */ | ||
53 | |||
54 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); | ||
55 | //static int RoutinoTaggingType_function(const char *_tag_,int _type_); | ||
56 | static int WayType_function(const char *_tag_,int _type_); | ||
57 | amb | 469 | static int NodeType_function(const char *_tag_,int _type_); |
58 | static int RelationType_function(const char *_tag_,int _type_); | ||
59 | amb | 393 | static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v); |
60 | static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v); | ||
61 | static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v); | ||
62 | |||
63 | |||
64 | /* The XML tag definitions */ | ||
65 | |||
66 | /*+ The SetType type tag. +*/ | ||
67 | static xmltag SetType_tag= | ||
68 | {"set", | ||
69 | 2, {"k","v"}, | ||
70 | SetType_function, | ||
71 | {NULL}}; | ||
72 | |||
73 | /*+ The OutputType type tag. +*/ | ||
74 | static xmltag OutputType_tag= | ||
75 | {"output", | ||
76 | 2, {"k","v"}, | ||
77 | OutputType_function, | ||
78 | {NULL}}; | ||
79 | |||
80 | amb | 469 | /*+ The IfType type tag. +*/ |
81 | static xmltag IfType_tag= | ||
82 | {"if", | ||
83 | 2, {"k","v"}, | ||
84 | IfType_function, | ||
85 | {&SetType_tag,&OutputType_tag,NULL}}; | ||
86 | |||
87 | amb | 393 | /*+ The RelationType type tag. +*/ |
88 | static xmltag RelationType_tag= | ||
89 | {"relation", | ||
90 | 0, {NULL}, | ||
91 | RelationType_function, | ||
92 | amb | 494 | {&IfType_tag,NULL}}; |
93 | amb | 393 | |
94 | amb | 469 | /*+ The NodeType type tag. +*/ |
95 | static xmltag NodeType_tag= | ||
96 | {"node", | ||
97 | 0, {NULL}, | ||
98 | NodeType_function, | ||
99 | {&IfType_tag,NULL}}; | ||
100 | amb | 393 | |
101 | /*+ The WayType type tag. +*/ | ||
102 | static xmltag WayType_tag= | ||
103 | {"way", | ||
104 | 0, {NULL}, | ||
105 | WayType_function, | ||
106 | {&IfType_tag,NULL}}; | ||
107 | |||
108 | /*+ The RoutinoTaggingType type tag. +*/ | ||
109 | static xmltag RoutinoTaggingType_tag= | ||
110 | {"routino-tagging", | ||
111 | 0, {NULL}, | ||
112 | NULL, | ||
113 | {&NodeType_tag,&WayType_tag,&RelationType_tag,NULL}}; | ||
114 | |||
115 | /*+ The xmlDeclaration type tag. +*/ | ||
116 | static xmltag xmlDeclaration_tag= | ||
117 | {"xml", | ||
118 | 2, {"version","encoding"}, | ||
119 | NULL, | ||
120 | {NULL}}; | ||
121 | |||
122 | |||
123 | /*+ The complete set of tags at the top level. +*/ | ||
124 | static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTaggingType_tag,NULL}; | ||
125 | |||
126 | |||
127 | /* The XML tag processing functions */ | ||
128 | |||
129 | |||
130 | /*++++++++++++++++++++++++++++++++++++++ | ||
131 | amb | 469 | The function that is called when the SetType XSD type is seen |
132 | amb | 393 | |
133 | amb | 469 | int SetType_function Returns 0 if no error occured or something else otherwise. |
134 | amb | 393 | |
135 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
136 | |||
137 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
138 | amb | 469 | |
139 | const char *k The contents of the 'k' attribute (or NULL if not defined). | ||
140 | |||
141 | const char *v The contents of the 'v' attribute (or NULL if not defined). | ||
142 | amb | 393 | ++++++++++++++++++++++++++++++++++++++*/ |
143 | |||
144 | amb | 469 | static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v) |
145 | amb | 393 | { |
146 | if(_type_&XMLPARSE_TAG_START) | ||
147 | amb | 469 | AppendTaggingAction(current_rule,k,v,0); |
148 | amb | 393 | |
149 | return(0); | ||
150 | } | ||
151 | |||
152 | |||
153 | /*++++++++++++++++++++++++++++++++++++++ | ||
154 | amb | 469 | The function that is called when the OutputType XSD type is seen |
155 | amb | 393 | |
156 | amb | 469 | int OutputType_function Returns 0 if no error occured or something else otherwise. |
157 | amb | 393 | |
158 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
159 | |||
160 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
161 | |||
162 | const char *k The contents of the 'k' attribute (or NULL if not defined). | ||
163 | |||
164 | const char *v The contents of the 'v' attribute (or NULL if not defined). | ||
165 | ++++++++++++++++++++++++++++++++++++++*/ | ||
166 | |||
167 | amb | 469 | static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v) |
168 | amb | 393 | { |
169 | if(_type_&XMLPARSE_TAG_START) | ||
170 | amb | 469 | AppendTaggingAction(current_rule,k,v,1); |
171 | amb | 393 | |
172 | return(0); | ||
173 | } | ||
174 | |||
175 | |||
176 | /*++++++++++++++++++++++++++++++++++++++ | ||
177 | amb | 469 | The function that is called when the IfType XSD type is seen |
178 | amb | 393 | |
179 | amb | 469 | int IfType_function Returns 0 if no error occured or something else otherwise. |
180 | amb | 393 | |
181 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
182 | |||
183 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
184 | |||
185 | const char *k The contents of the 'k' attribute (or NULL if not defined). | ||
186 | |||
187 | const char *v The contents of the 'v' attribute (or NULL if not defined). | ||
188 | ++++++++++++++++++++++++++++++++++++++*/ | ||
189 | |||
190 | amb | 469 | static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v) |
191 | amb | 393 | { |
192 | if(_type_&XMLPARSE_TAG_START) | ||
193 | amb | 469 | { |
194 | current_rule=AppendTaggingRule(current_list,k,v); | ||
195 | } | ||
196 | amb | 393 | |
197 | return(0); | ||
198 | } | ||
199 | |||
200 | |||
201 | /*++++++++++++++++++++++++++++++++++++++ | ||
202 | The function that is called when the RelationType XSD type is seen | ||
203 | |||
204 | int RelationType_function Returns 0 if no error occured or something else otherwise. | ||
205 | |||
206 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
207 | |||
208 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
209 | ++++++++++++++++++++++++++++++++++++++*/ | ||
210 | |||
211 | static int RelationType_function(const char *_tag_,int _type_) | ||
212 | { | ||
213 | if(_type_&XMLPARSE_TAG_START) | ||
214 | current_list=&RelationRules; | ||
215 | |||
216 | return(0); | ||
217 | } | ||
218 | |||
219 | |||
220 | /*++++++++++++++++++++++++++++++++++++++ | ||
221 | amb | 469 | The function that is called when the NodeType XSD type is seen |
222 | amb | 393 | |
223 | amb | 469 | int NodeType_function Returns 0 if no error occured or something else otherwise. |
224 | amb | 393 | |
225 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
226 | |||
227 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
228 | ++++++++++++++++++++++++++++++++++++++*/ | ||
229 | |||
230 | amb | 469 | static int NodeType_function(const char *_tag_,int _type_) |
231 | amb | 393 | { |
232 | if(_type_&XMLPARSE_TAG_START) | ||
233 | amb | 469 | current_list=&NodeRules; |
234 | amb | 393 | |
235 | return(0); | ||
236 | } | ||
237 | |||
238 | |||
239 | /*++++++++++++++++++++++++++++++++++++++ | ||
240 | The function that is called when the WayType XSD type is seen | ||
241 | |||
242 | int WayType_function Returns 0 if no error occured or something else otherwise. | ||
243 | |||
244 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
245 | |||
246 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
247 | ++++++++++++++++++++++++++++++++++++++*/ | ||
248 | |||
249 | static int WayType_function(const char *_tag_,int _type_) | ||
250 | { | ||
251 | if(_type_&XMLPARSE_TAG_START) | ||
252 | current_list=&WayRules; | ||
253 | |||
254 | return(0); | ||
255 | } | ||
256 | |||
257 | |||
258 | /*++++++++++++++++++++++++++++++++++++++ | ||
259 | The function that is called when the RoutinoTaggingType XSD type is seen | ||
260 | |||
261 | int RoutinoTaggingType_function Returns 0 if no error occured or something else otherwise. | ||
262 | |||
263 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
264 | |||
265 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
266 | ++++++++++++++++++++++++++++++++++++++*/ | ||
267 | |||
268 | //static int RoutinoTaggingType_function(const char *_tag_,int _type_) | ||
269 | //{ | ||
270 | // return(0); | ||
271 | //} | ||
272 | |||
273 | |||
274 | /*++++++++++++++++++++++++++++++++++++++ | ||
275 | The function that is called when the XML declaration is seen | ||
276 | |||
277 | int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. | ||
278 | |||
279 | const char *_tag_ Set to the name of the element tag that triggered this function call. | ||
280 | |||
281 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
282 | |||
283 | const char *version The contents of the 'version' attribute (or NULL if not defined). | ||
284 | |||
285 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). | ||
286 | ++++++++++++++++++++++++++++++++++++++*/ | ||
287 | |||
288 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) | ||
289 | //{ | ||
290 | // return(0); | ||
291 | //} | ||
292 | |||
293 | |||
294 | /*++++++++++++++++++++++++++++++++++++++ | ||
295 | The XML tagging rules parser. | ||
296 | |||
297 | int ParseXMLTaggingRules Returns 0 if OK or something else in case of an error. | ||
298 | |||
299 | const char *filename The name of the file to read. | ||
300 | ++++++++++++++++++++++++++++++++++++++*/ | ||
301 | |||
302 | int ParseXMLTaggingRules(const char *filename) | ||
303 | { | ||
304 | amb | 754 | FILE *file; |
305 | amb | 393 | int retval; |
306 | |||
307 | if(!ExistsFile(filename)) | ||
308 | { | ||
309 | fprintf(stderr,"Error: Specified tagging rules file '%s' does not exist.\n",filename); | ||
310 | return(1); | ||
311 | } | ||
312 | |||
313 | amb | 754 | file=fopen(filename,"r"); |
314 | amb | 393 | |
315 | if(!file) | ||
316 | { | ||
317 | fprintf(stderr,"Error: Cannot open tagging rules file '%s' for reading.\n",filename); | ||
318 | return(1); | ||
319 | } | ||
320 | |||
321 | retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME); | ||
322 | |||
323 | fclose(file); | ||
324 | |||
325 | if(retval) | ||
326 | return(1); | ||
327 | |||
328 | return(0); | ||
329 | } | ||
330 | |||
331 | |||
332 | /*++++++++++++++++++++++++++++++++++++++ | ||
333 | amb | 797 | Delete the tagging rules loaded from the XML file. |
334 | ++++++++++++++++++++++++++++++++++++++*/ | ||
335 | |||
336 | void DeleteXMLTaggingRules(void) | ||
337 | { | ||
338 | DeleteTaggingRuleList(&NodeRules); | ||
339 | DeleteTaggingRuleList(&WayRules); | ||
340 | DeleteTaggingRuleList(&RelationRules); | ||
341 | } | ||
342 | |||
343 | |||
344 | /*++++++++++++++++++++++++++++++++++++++ | ||
345 | amb | 393 | Append a tagging rule to the list of rules. |
346 | |||
347 | TaggingRule *AppendTaggingRule Returns the latest rule (the just added one). | ||
348 | |||
349 | TaggingRuleList *rules The list of rules to add to. | ||
350 | |||
351 | const char *k The tag key. | ||
352 | |||
353 | const char *v The tag value. | ||
354 | ++++++++++++++++++++++++++++++++++++++*/ | ||
355 | |||
356 | TaggingRule *AppendTaggingRule(TaggingRuleList *rules,const char *k,const char *v) | ||
357 | { | ||
358 | if((rules->nrules%16)==0) | ||
359 | rules->rules=(TaggingRule*)realloc((void*)rules->rules,(rules->nrules+16)*sizeof(TaggingRule)); | ||
360 | |||
361 | rules->nrules++; | ||
362 | |||
363 | if(k) | ||
364 | rules->rules[rules->nrules-1].k=strcpy(malloc(strlen(k)+1),k); | ||
365 | else | ||
366 | rules->rules[rules->nrules-1].k=NULL; | ||
367 | |||
368 | if(v) | ||
369 | rules->rules[rules->nrules-1].v=strcpy(malloc(strlen(v)+1),v); | ||
370 | else | ||
371 | rules->rules[rules->nrules-1].v=NULL; | ||
372 | |||
373 | rules->rules[rules->nrules-1].nactions=0; | ||
374 | rules->rules[rules->nrules-1].actions=NULL; | ||
375 | |||
376 | return(&rules->rules[rules->nrules-1]); | ||
377 | } | ||
378 | |||
379 | |||
380 | /*++++++++++++++++++++++++++++++++++++++ | ||
381 | Append a tagging action to a tagging rule. | ||
382 | |||
383 | TaggingRule *rule The rule to add the action to. | ||
384 | |||
385 | const char *k The tag key. | ||
386 | |||
387 | const char *v The tag value. | ||
388 | |||
389 | int output Set to 1 if this is an output rule. | ||
390 | ++++++++++++++++++++++++++++++++++++++*/ | ||
391 | |||
392 | void AppendTaggingAction(TaggingRule *rule,const char *k,const char *v,int output) | ||
393 | { | ||
394 | if((rule->nactions%16)==0) | ||
395 | rule->actions=(TaggingAction*)realloc((void*)rule->actions,(rule->nactions+16)*sizeof(TaggingAction)); | ||
396 | |||
397 | rule->nactions++; | ||
398 | |||
399 | rule->actions[rule->nactions-1].output=output; | ||
400 | |||
401 | if(k) | ||
402 | rule->actions[rule->nactions-1].k=strcpy(malloc(strlen(k)+1),k); | ||
403 | else | ||
404 | rule->actions[rule->nactions-1].k=NULL; | ||
405 | |||
406 | if(v) | ||
407 | rule->actions[rule->nactions-1].v=strcpy(malloc(strlen(v)+1),v); | ||
408 | else | ||
409 | rule->actions[rule->nactions-1].v=NULL; | ||
410 | } | ||
411 | |||
412 | |||
413 | /*++++++++++++++++++++++++++++++++++++++ | ||
414 | amb | 797 | Delete a tagging rule. |
415 | |||
416 | TaggingRuleList *rules The list of rules to be deleted. | ||
417 | ++++++++++++++++++++++++++++++++++++++*/ | ||
418 | |||
419 | void DeleteTaggingRuleList(TaggingRuleList *rules) | ||
420 | { | ||
421 | int i,j; | ||
422 | |||
423 | for(i=0;i<rules->nrules;i++) | ||
424 | { | ||
425 | if(rules->rules[i].k) | ||
426 | free(rules->rules[i].k); | ||
427 | if(rules->rules[i].v) | ||
428 | free(rules->rules[i].v); | ||
429 | |||
430 | for(j=0;j<rules->rules[i].nactions;j++) | ||
431 | { | ||
432 | if(rules->rules[i].actions[j].k) | ||
433 | free(rules->rules[i].actions[j].k); | ||
434 | if(rules->rules[i].actions[j].v) | ||
435 | free(rules->rules[i].actions[j].v); | ||
436 | } | ||
437 | |||
438 | if(rules->rules[i].actions) | ||
439 | free(rules->rules[i].actions); | ||
440 | } | ||
441 | |||
442 | if(rules->rules) | ||
443 | free(rules->rules); | ||
444 | } | ||
445 | |||
446 | |||
447 | /*++++++++++++++++++++++++++++++++++++++ | ||
448 | amb | 401 | Create a new TagList structure. |
449 | |||
450 | TagList *NewTagList Returns the new allocated TagList. | ||
451 | ++++++++++++++++++++++++++++++++++++++*/ | ||
452 | |||
453 | TagList *NewTagList(void) | ||
454 | { | ||
455 | return((TagList*)calloc(sizeof(TagList),1)); | ||
456 | } | ||
457 | |||
458 | |||
459 | /*++++++++++++++++++++++++++++++++++++++ | ||
460 | amb | 393 | Append a tag to the list of tags. |
461 | |||
462 | TagList *tags The list of tags to add to. | ||
463 | |||
464 | const char *k The tag key. | ||
465 | |||
466 | const char *v The tag value. | ||
467 | ++++++++++++++++++++++++++++++++++++++*/ | ||
468 | |||
469 | void AppendTag(TagList *tags,const char *k,const char *v) | ||
470 | { | ||
471 | if((tags->ntags%16)==0) | ||
472 | { | ||
473 | amb | 401 | int i; |
474 | |||
475 | tags->k=(char**)realloc((void*)tags->k,(tags->ntags+16)*sizeof(char*)); | ||
476 | tags->v=(char**)realloc((void*)tags->v,(tags->ntags+16)*sizeof(char*)); | ||
477 | |||
478 | for(i=tags->ntags;i<(tags->ntags+16);i++) | ||
479 | tags->k[i]=tags->v[i]=NULL; | ||
480 | amb | 393 | } |
481 | |||
482 | amb | 401 | tags->k[tags->ntags]=strcpy(realloc(tags->k[tags->ntags],strlen(k)+1),k); |
483 | tags->v[tags->ntags]=strcpy(realloc(tags->v[tags->ntags],strlen(v)+1),v); | ||
484 | |||
485 | amb | 393 | tags->ntags++; |
486 | } | ||
487 | |||
488 | |||
489 | /*++++++++++++++++++++++++++++++++++++++ | ||
490 | Modify an existing tag or append a new tag to the list of tags. | ||
491 | |||
492 | TagList *tags The list of tags to modify. | ||
493 | |||
494 | const char *k The tag key. | ||
495 | |||
496 | const char *v The tag value. | ||
497 | ++++++++++++++++++++++++++++++++++++++*/ | ||
498 | |||
499 | void ModifyTag(TagList *tags,const char *k,const char *v) | ||
500 | { | ||
501 | int i; | ||
502 | |||
503 | for(i=0;i<tags->ntags;i++) | ||
504 | if(!strcmp(tags->k[i],k)) | ||
505 | { | ||
506 | amb | 401 | tags->v[i]=strcpy(realloc(tags->v[i],strlen(v)+1),v); |
507 | amb | 393 | return; |
508 | } | ||
509 | |||
510 | AppendTag(tags,k,v); | ||
511 | } | ||
512 | |||
513 | |||
514 | /*++++++++++++++++++++++++++++++++++++++ | ||
515 | Delete a tag list and the contents. | ||
516 | |||
517 | TagList *tags The list of tags to delete. | ||
518 | ++++++++++++++++++++++++++++++++++++++*/ | ||
519 | |||
520 | void DeleteTagList(TagList *tags) | ||
521 | { | ||
522 | int i; | ||
523 | |||
524 | for(i=0;i<tags->ntags;i++) | ||
525 | { | ||
526 | if(tags->k[i]) free(tags->k[i]); | ||
527 | if(tags->v[i]) free(tags->v[i]); | ||
528 | } | ||
529 | |||
530 | amb | 401 | if(tags->ntags) |
531 | { | ||
532 | free(tags->k); | ||
533 | free(tags->v); | ||
534 | } | ||
535 | |||
536 | amb | 393 | free(tags); |
537 | } | ||
538 | |||
539 | |||
540 | /*++++++++++++++++++++++++++++++++++++++ | ||
541 | Apply a set of tagging rules to a set of tags. | ||
542 | |||
543 | TagList *ApplyTaggingRules Returns the list of output tags after modification. | ||
544 | |||
545 | TaggingRuleList *rules The tagging rules to apply. | ||
546 | |||
547 | TagList *tags The tags to be modified. | ||
548 | ++++++++++++++++++++++++++++++++++++++*/ | ||
549 | |||
550 | TagList *ApplyTaggingRules(TaggingRuleList *rules,TagList *tags) | ||
551 | { | ||
552 | amb | 401 | TagList *result=NewTagList(); |
553 | amb | 393 | int i,j; |
554 | |||
555 | for(i=0;i<rules->nrules;i++) | ||
556 | { | ||
557 | if(rules->rules[i].k && rules->rules[i].v) | ||
558 | { | ||
559 | for(j=0;j<tags->ntags;j++) | ||
560 | if(!strcmp(tags->k[j],rules->rules[i].k) && !strcmp(tags->v[j],rules->rules[i].v)) | ||
561 | apply_actions(&rules->rules[i],j,tags,result); | ||
562 | } | ||
563 | else if(rules->rules[i].k && !rules->rules[i].v) | ||
564 | { | ||
565 | for(j=0;j<tags->ntags;j++) | ||
566 | if(!strcmp(tags->k[j],rules->rules[i].k)) | ||
567 | apply_actions(&rules->rules[i],j,tags,result); | ||
568 | } | ||
569 | else if(!rules->rules[i].k && rules->rules[i].v) | ||
570 | { | ||
571 | for(j=0;j<tags->ntags;j++) | ||
572 | if(!strcmp(tags->v[j],rules->rules[i].v)) | ||
573 | apply_actions(&rules->rules[i],j,tags,result); | ||
574 | } | ||
575 | else /* if(!rules->rules[i].k && !rules->rules[i].v) */ | ||
576 | { | ||
577 | for(j=0;j<tags->ntags;j++) | ||
578 | apply_actions(&rules->rules[i],j,tags,result); | ||
579 | } | ||
580 | } | ||
581 | |||
582 | return(result); | ||
583 | } | ||
584 | |||
585 | |||
586 | /*++++++++++++++++++++++++++++++++++++++ | ||
587 | Apply a set of actions to a matching tag. | ||
588 | |||
589 | TaggingRule *rule The rule that matched (containing the actions). | ||
590 | |||
591 | int match The matching tag number. | ||
592 | |||
593 | TagList *input The input tags. | ||
594 | |||
595 | TagList *output The output tags. | ||
596 | ++++++++++++++++++++++++++++++++++++++*/ | ||
597 | |||
598 | static void apply_actions(TaggingRule *rule,int match,TagList *input,TagList *output) | ||
599 | { | ||
600 | int i; | ||
601 | |||
602 | for(i=0;i<rule->nactions;i++) | ||
603 | { | ||
604 | char *k,*v; | ||
605 | |||
606 | if(rule->actions[i].k) | ||
607 | k=rule->actions[i].k; | ||
608 | else | ||
609 | k=input->k[match]; | ||
610 | |||
611 | if(rule->actions[i].v) | ||
612 | v=rule->actions[i].v; | ||
613 | else | ||
614 | v=input->v[match]; | ||
615 | |||
616 | if(rule->actions[i].output) | ||
617 | ModifyTag(output,k,v); | ||
618 | else | ||
619 | ModifyTag(input,k,v); | ||
620 | } | ||
621 | } |
Properties
Name | Value |
---|---|
cvs:description | Functions for reading the tag transformation rules and applying them. |