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 449 - (hide annotations) (download) (as text)
Mon Jul 12 17:59:42 2010 UTC (14 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 15704 byte(s)
Create a files.h header and put some of the most heavily used files.c functions
into it and make them inline.

1 amb 393 /***************************************
2 amb 449 $Header: /home/amb/CVS/routino/src/tagging.c,v 1.3 2010-07-12 17:59:42 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     This file Copyright 2010 Andrew M. Bishop
9    
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     static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v);
58     static int RelationType_function(const char *_tag_,int _type_);
59     static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v);
60     static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v);
61     static int NodeType_function(const char *_tag_,int _type_);
62    
63    
64     /* The XML tag definitions */
65    
66     /*+ The NodeType type tag. +*/
67     static xmltag NodeType_tag=
68     {"node",
69     0, {NULL},
70     NodeType_function,
71     {NULL}};
72    
73     /*+ The SetType type tag. +*/
74     static xmltag SetType_tag=
75     {"set",
76     2, {"k","v"},
77     SetType_function,
78     {NULL}};
79    
80     /*+ The OutputType type tag. +*/
81     static xmltag OutputType_tag=
82     {"output",
83     2, {"k","v"},
84     OutputType_function,
85     {NULL}};
86    
87     /*+ The RelationType type tag. +*/
88     static xmltag RelationType_tag=
89     {"relation",
90     0, {NULL},
91     RelationType_function,
92     {NULL}};
93    
94     /*+ The IfType type tag. +*/
95     static xmltag IfType_tag=
96     {"if",
97     2, {"k","v"},
98     IfType_function,
99     {&SetType_tag,&OutputType_tag,NULL}};
100    
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     The function that is called when the NodeType XSD type is seen
132    
133     int NodeType_function Returns 0 if no error occured or something else otherwise.
134    
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     ++++++++++++++++++++++++++++++++++++++*/
139    
140     static int NodeType_function(const char *_tag_,int _type_)
141     {
142     if(_type_&XMLPARSE_TAG_START)
143     current_list=&NodeRules;
144    
145     return(0);
146     }
147    
148    
149     /*++++++++++++++++++++++++++++++++++++++
150     The function that is called when the SetType XSD type is seen
151    
152     int SetType_function Returns 0 if no error occured or something else otherwise.
153    
154     const char *_tag_ Set to the name of the element tag that triggered this function call.
155    
156     int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
157    
158     const char *k The contents of the 'k' attribute (or NULL if not defined).
159    
160     const char *v The contents of the 'v' attribute (or NULL if not defined).
161     ++++++++++++++++++++++++++++++++++++++*/
162    
163     static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v)
164     {
165     if(_type_&XMLPARSE_TAG_START)
166     AppendTaggingAction(current_rule,k,v,0);
167    
168     return(0);
169     }
170    
171    
172     /*++++++++++++++++++++++++++++++++++++++
173     The function that is called when the OutputType XSD type is seen
174    
175     int OutputType_function Returns 0 if no error occured or something else otherwise.
176    
177     const char *_tag_ Set to the name of the element tag that triggered this function call.
178    
179     int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
180    
181     const char *k The contents of the 'k' attribute (or NULL if not defined).
182    
183     const char *v The contents of the 'v' attribute (or NULL if not defined).
184     ++++++++++++++++++++++++++++++++++++++*/
185    
186     static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v)
187     {
188     if(_type_&XMLPARSE_TAG_START)
189     AppendTaggingAction(current_rule,k,v,1);
190    
191     return(0);
192     }
193    
194    
195     /*++++++++++++++++++++++++++++++++++++++
196     The function that is called when the RelationType XSD type is seen
197    
198     int RelationType_function Returns 0 if no error occured or something else otherwise.
199    
200     const char *_tag_ Set to the name of the element tag that triggered this function call.
201    
202     int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
203     ++++++++++++++++++++++++++++++++++++++*/
204    
205     static int RelationType_function(const char *_tag_,int _type_)
206     {
207     if(_type_&XMLPARSE_TAG_START)
208     current_list=&RelationRules;
209    
210     return(0);
211     }
212    
213    
214     /*++++++++++++++++++++++++++++++++++++++
215     The function that is called when the IfType XSD type is seen
216    
217     int IfType_function Returns 0 if no error occured or something else otherwise.
218    
219     const char *_tag_ Set to the name of the element tag that triggered this function call.
220    
221     int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
222    
223     const char *k The contents of the 'k' attribute (or NULL if not defined).
224    
225     const char *v The contents of the 'v' attribute (or NULL if not defined).
226     ++++++++++++++++++++++++++++++++++++++*/
227    
228     static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v)
229     {
230     if(_type_&XMLPARSE_TAG_START)
231     {
232     current_rule=AppendTaggingRule(current_list,k,v);
233     }
234    
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     int retval;
305    
306     if(!ExistsFile(filename))
307     {
308     fprintf(stderr,"Error: Specified tagging rules file '%s' does not exist.\n",filename);
309     return(1);
310     }
311    
312     FILE *file=fopen(filename,"r");
313    
314     if(!file)
315     {
316     fprintf(stderr,"Error: Cannot open tagging rules file '%s' for reading.\n",filename);
317     return(1);
318     }
319    
320     retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME);
321    
322     fclose(file);
323    
324     if(retval)
325     return(1);
326    
327     return(0);
328     }
329    
330    
331     /*++++++++++++++++++++++++++++++++++++++
332     Append a tagging rule to the list of rules.
333    
334     TaggingRule *AppendTaggingRule Returns the latest rule (the just added one).
335    
336     TaggingRuleList *rules The list of rules to add to.
337    
338     const char *k The tag key.
339    
340     const char *v The tag value.
341     ++++++++++++++++++++++++++++++++++++++*/
342    
343     TaggingRule *AppendTaggingRule(TaggingRuleList *rules,const char *k,const char *v)
344     {
345     if((rules->nrules%16)==0)
346     rules->rules=(TaggingRule*)realloc((void*)rules->rules,(rules->nrules+16)*sizeof(TaggingRule));
347    
348     rules->nrules++;
349    
350     if(k)
351     rules->rules[rules->nrules-1].k=strcpy(malloc(strlen(k)+1),k);
352     else
353     rules->rules[rules->nrules-1].k=NULL;
354    
355     if(v)
356     rules->rules[rules->nrules-1].v=strcpy(malloc(strlen(v)+1),v);
357     else
358     rules->rules[rules->nrules-1].v=NULL;
359    
360     rules->rules[rules->nrules-1].nactions=0;
361     rules->rules[rules->nrules-1].actions=NULL;
362    
363     return(&rules->rules[rules->nrules-1]);
364     }
365    
366    
367     /*++++++++++++++++++++++++++++++++++++++
368     Append a tagging action to a tagging rule.
369    
370     TaggingRule *rule The rule to add the action to.
371    
372     const char *k The tag key.
373    
374     const char *v The tag value.
375    
376     int output Set to 1 if this is an output rule.
377     ++++++++++++++++++++++++++++++++++++++*/
378    
379     void AppendTaggingAction(TaggingRule *rule,const char *k,const char *v,int output)
380     {
381     if((rule->nactions%16)==0)
382     rule->actions=(TaggingAction*)realloc((void*)rule->actions,(rule->nactions+16)*sizeof(TaggingAction));
383    
384     rule->nactions++;
385    
386     rule->actions[rule->nactions-1].output=output;
387    
388     if(k)
389     rule->actions[rule->nactions-1].k=strcpy(malloc(strlen(k)+1),k);
390     else
391     rule->actions[rule->nactions-1].k=NULL;
392    
393     if(v)
394     rule->actions[rule->nactions-1].v=strcpy(malloc(strlen(v)+1),v);
395     else
396     rule->actions[rule->nactions-1].v=NULL;
397     }
398    
399    
400     /*++++++++++++++++++++++++++++++++++++++
401 amb 401 Create a new TagList structure.
402    
403     TagList *NewTagList Returns the new allocated TagList.
404     ++++++++++++++++++++++++++++++++++++++*/
405    
406     TagList *NewTagList(void)
407     {
408     return((TagList*)calloc(sizeof(TagList),1));
409     }
410    
411    
412     /*++++++++++++++++++++++++++++++++++++++
413 amb 393 Append a tag to the list of tags.
414    
415     TagList *tags The list of tags to add to.
416    
417     const char *k The tag key.
418    
419     const char *v The tag value.
420     ++++++++++++++++++++++++++++++++++++++*/
421    
422     void AppendTag(TagList *tags,const char *k,const char *v)
423     {
424     if((tags->ntags%16)==0)
425     {
426 amb 401 int i;
427    
428     tags->k=(char**)realloc((void*)tags->k,(tags->ntags+16)*sizeof(char*));
429     tags->v=(char**)realloc((void*)tags->v,(tags->ntags+16)*sizeof(char*));
430    
431     for(i=tags->ntags;i<(tags->ntags+16);i++)
432     tags->k[i]=tags->v[i]=NULL;
433 amb 393 }
434    
435 amb 401 tags->k[tags->ntags]=strcpy(realloc(tags->k[tags->ntags],strlen(k)+1),k);
436     tags->v[tags->ntags]=strcpy(realloc(tags->v[tags->ntags],strlen(v)+1),v);
437    
438 amb 393 tags->ntags++;
439     }
440    
441    
442     /*++++++++++++++++++++++++++++++++++++++
443     Modify an existing tag or append a new tag to the list of tags.
444    
445     TagList *tags The list of tags to modify.
446    
447     const char *k The tag key.
448    
449     const char *v The tag value.
450     ++++++++++++++++++++++++++++++++++++++*/
451    
452     void ModifyTag(TagList *tags,const char *k,const char *v)
453     {
454     int i;
455    
456     for(i=0;i<tags->ntags;i++)
457     if(!strcmp(tags->k[i],k))
458     {
459 amb 401 tags->v[i]=strcpy(realloc(tags->v[i],strlen(v)+1),v);
460 amb 393 return;
461     }
462    
463     AppendTag(tags,k,v);
464     }
465    
466    
467     /*++++++++++++++++++++++++++++++++++++++
468     Delete a tag list and the contents.
469    
470     TagList *tags The list of tags to delete.
471     ++++++++++++++++++++++++++++++++++++++*/
472    
473     void DeleteTagList(TagList *tags)
474     {
475     int i;
476    
477     for(i=0;i<tags->ntags;i++)
478     {
479     if(tags->k[i]) free(tags->k[i]);
480     if(tags->v[i]) free(tags->v[i]);
481     }
482    
483 amb 401 if(tags->ntags)
484     {
485     free(tags->k);
486     free(tags->v);
487     }
488    
489 amb 393 free(tags);
490     }
491    
492    
493     /*++++++++++++++++++++++++++++++++++++++
494     Apply a set of tagging rules to a set of tags.
495    
496     TagList *ApplyTaggingRules Returns the list of output tags after modification.
497    
498     TaggingRuleList *rules The tagging rules to apply.
499    
500     TagList *tags The tags to be modified.
501     ++++++++++++++++++++++++++++++++++++++*/
502    
503     TagList *ApplyTaggingRules(TaggingRuleList *rules,TagList *tags)
504     {
505 amb 401 TagList *result=NewTagList();
506 amb 393 int i,j;
507    
508     for(i=0;i<rules->nrules;i++)
509     {
510     if(rules->rules[i].k && rules->rules[i].v)
511     {
512     for(j=0;j<tags->ntags;j++)
513     if(!strcmp(tags->k[j],rules->rules[i].k) && !strcmp(tags->v[j],rules->rules[i].v))
514     apply_actions(&rules->rules[i],j,tags,result);
515     }
516     else if(rules->rules[i].k && !rules->rules[i].v)
517     {
518     for(j=0;j<tags->ntags;j++)
519     if(!strcmp(tags->k[j],rules->rules[i].k))
520     apply_actions(&rules->rules[i],j,tags,result);
521     }
522     else if(!rules->rules[i].k && rules->rules[i].v)
523     {
524     for(j=0;j<tags->ntags;j++)
525     if(!strcmp(tags->v[j],rules->rules[i].v))
526     apply_actions(&rules->rules[i],j,tags,result);
527     }
528     else /* if(!rules->rules[i].k && !rules->rules[i].v) */
529     {
530     for(j=0;j<tags->ntags;j++)
531     apply_actions(&rules->rules[i],j,tags,result);
532     }
533     }
534    
535     return(result);
536     }
537    
538    
539     /*++++++++++++++++++++++++++++++++++++++
540     Apply a set of actions to a matching tag.
541    
542     TaggingRule *rule The rule that matched (containing the actions).
543    
544     int match The matching tag number.
545    
546     TagList *input The input tags.
547    
548     TagList *output The output tags.
549     ++++++++++++++++++++++++++++++++++++++*/
550    
551     static void apply_actions(TaggingRule *rule,int match,TagList *input,TagList *output)
552     {
553     int i;
554    
555     for(i=0;i<rule->nactions;i++)
556     {
557     char *k,*v;
558    
559     if(rule->actions[i].k)
560     k=rule->actions[i].k;
561     else
562     k=input->k[match];
563    
564     if(rule->actions[i].v)
565     v=rule->actions[i].v;
566     else
567     v=input->v[match];
568    
569     if(rule->actions[i].output)
570     ModifyTag(output,k,v);
571     else
572     ModifyTag(input,k,v);
573     }
574     }

Properties

Name Value
cvs:description Functions for reading the tag transformation rules and applying them.