Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /trunk/src/tagging.c

Parent Directory Parent Directory | Revision Log 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)
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.