require db4-devel
[platform/upstream/libical.git] / scripts / mkderivedvalues.pl
1 #!/usr/bin/perl 
2
3 use lib '.';
4
5 require 'readvaluesfile.pl';
6
7 use Getopt::Std;
8 getopts('chi:');
9
10  #Options
11  # c -> generate c code file
12  # h-> generate header file   
13
14  # Open with value-types.txt
15
16 my %h = read_values_file($ARGV[0]);
17
18
19  # Write the file inline by copying everything before a demarcation
20  # line, and putting the generated data after the demarcation
21
22 if ($opt_i) {
23   
24   open(IN,$opt_i) || die "Can't open input file $opt_i";
25   
26   while(<IN>){
27     if (/<insert_code_here>/){
28       insert_code();
29     } else {
30       print;
31    }
32
33
34   }
35 }
36
37 sub insert_code
38 {
39  # Map type names to the value in the icalvalue_impl data union */
40
41 %union_map = (
42               BOOLEAN => 'int',
43               CALADDRESS=>'string',
44               DATE=>'time',
45               DATETIME=>'time',
46               DATETIMEDATE=>'time',
47               DATETIMEPERIOD=>'period',
48               DURATION=>'duration',
49               INTEGER=>'int',
50               TEXT=>'string',
51               URI=>'string',
52               UTCOFFSET=>'int',
53               QUERY=>'string',
54               BINARY=>'string',
55               X=>'string'
56              );
57
58
59 if($opt_h){
60
61   # First print out the value enumerations
62   $idx = 5000;
63   print "typedef enum icalvalue_kind {\n";
64   print "   ICAL_ANY_VALUE=$idx,\n";
65
66   foreach $value  (keys %h) {
67     
68     $idx++;
69     my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));
70     
71     next if $value eq "NO";
72     
73     print "    ICAL_${ucv}_VALUE=$idx,\n";
74   }
75   
76   $idx++;
77   print "   ICAL_NO_VALUE=$idx\n} icalvalue_kind ;\n\n";
78   
79   # Now create enumerations for property values
80   $idx = 10000;
81   
82   print "#define ICALPROPERTY_FIRST_ENUM $idx\n\n";
83   
84   foreach $value (sort keys %h) {
85     
86     next if !$value;
87     
88     next if $value eq 'NO' or $prop eq 'ANY';
89
90     my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));    
91     my @enums = @{$h{$value}->{'enums'}};
92
93     if(@enums){
94
95       my ($c_autogen,$c_type) = @{$h{$value}->{'C'}};
96       print "typedef $c_type {\n";
97       my $first = 1;
98
99       unshift(@enums,"X");
100
101       push(@enums,"NONE");
102
103       foreach $e (@enums) {
104         if (!$first){
105           print ",\n";
106         } else {
107           $first = 0;
108         }
109         
110         my $uce = join("",map {uc(lc($_));}  split(/-/,$e));    
111         
112         print "    ICAL_${ucv}_${uce} = $idx";
113         
114         $idx++;
115       }  
116
117       $c_type =~ s/enum //;
118
119       print "\n} $c_type;\n\n";
120     }
121   }
122
123   print "#define ICALPROPERTY_LAST_ENUM $idx\n\n";
124
125 }
126
127
128 if($opt_c){
129
130   # print out the value to string map
131
132   my $count = scalar(keys %h) + 1;
133   print "static const struct icalvalue_kind_map value_map[$count]={\n"; 
134
135   foreach $value  (keys %h) {
136
137     $idx++;
138     my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));
139     
140     next if $value eq "NO";
141     
142     print "    {ICAL_${ucv}_VALUE,\"$value\"},\n";
143   }
144
145     
146   print "    {ICAL_NO_VALUE,\"\"}\n};";
147
148 }
149
150
151 foreach $value  (keys %h) {
152
153   my $autogen = $h{$value}->{C}->[0];
154   my $type = $h{$value}->{C}->[1];
155
156   my $ucf = join("",map {ucfirst(lc($_));}  split(/-/,$value));
157   
158   my $lc = lc($ucf);
159   my $uc = uc($lc);
160   
161   my $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");\n" if $type =~ /\*/;
162   my $pointer_check_rv = "icalerror_check_arg_rv( (v!=0),\"v\");\n" if $type =~ /\*/;
163   
164   my $assign;
165   
166   if ($type =~ /char/){
167     $assign = "icalmemory_strdup(v);\n\n    if (impl->data.v_string == 0){\n      errno = ENOMEM;\n    }\n";
168   } else {
169     $assign = "v;";
170   }
171   
172   my $union_data;
173   
174   if(@{$h{$value}->{'enums'}}){
175     $union_data = 'enum';
176
177   } elsif (exists $union_map{$uc} ){
178     $union_data=$union_map{$uc};
179   } else {
180     $union_data = $lc;
181   }
182   
183   if ($opt_c && $autogen) {
184     
185     print "\n\n\
186 icalvalue* icalvalue_new_${lc} ($type v){\
187    struct icalvalue_impl* impl;\
188    $pointer_check\
189    impl = icalvalue_new_impl(ICAL_${uc}_VALUE);\
190    icalvalue_set_${lc}((icalvalue*)impl,v);\
191    return (icalvalue*)impl;\
192 }\
193 void icalvalue_set_${lc}(icalvalue* value, $type v) {\
194     struct icalvalue_impl* impl; \
195     icalerror_check_arg_rv( (value!=0),\"value\");\
196     $pointer_check_rv\
197     icalerror_check_value_type(value, ICAL_${uc}_VALUE);\
198     impl = (struct icalvalue_impl*)value;\n";
199     
200     if( $union_data eq 'string') {
201       
202       print "    if(impl->data.v_${union_data}!=0) {free((void*)impl->data.v_${union_data});}\n";
203     }
204     
205
206     print "\n\
207     impl->data.v_$union_data = $assign \n\
208     icalvalue_reset_kind(impl);\n}\n";
209
210     print "$type\ icalvalue_get_${lc} (const icalvalue* value) {\n\n";
211     if( $union_data eq 'string') {
212         print "    icalerror_check_arg_rz ((value!=0),\"value\");\n";
213     }
214     else {
215         print "    icalerror_check_arg ((value!=0),\"value\");\n";
216     }
217     print "    icalerror_check_value_type (value, ICAL_${uc}_VALUE);\
218     return ((struct icalvalue_impl*)value)->data.v_${union_data};\n}\n";
219
220     
221   } elsif($opt_h && $autogen) {
222     
223     print "\n /* $value */ \
224 icalvalue* icalvalue_new_${lc}($type v); \
225 $type icalvalue_get_${lc}(const icalvalue* value); \
226 void icalvalue_set_${lc}(icalvalue* value, ${type} v);\n\n";
227
228   } 
229
230 }
231   
232   
233 if ($opt_h){
234     print "#endif /*ICALVALUE_H*/\n";
235   }
236   
237
238 }