Imported Upstream version 0.48
[platform/upstream/libical.git] / scripts / mkderivedproperties.pl
1 #!/usr/bin/env perl
2
3 require "readvaluesfile.pl";
4
5 use Getopt::Std;
6 getopts('chspmi:');
7
8 # ARG 0 is properties.csv
9 %propmap  = read_properties_file($ARGV[0]);
10
11 # ARG 1 is value-types.txt
12 %valuemap  = read_values_file($ARGV[1]);
13
14
15 $include_vanew = 1;
16
17 # Write the file inline by copying everything before a demarcation
18 # line, and putting the generated data after the demarcation
19
20 if ($opt_i) {
21
22   open(IN,$opt_i) || die "Can't open input file $opt_i";
23
24   while(<IN>){
25
26     if (/<insert_code_here>/){
27       insert_code();
28     } else {
29       print;
30    }
31  
32   }    
33  
34 }
35
36 sub fudge_data {
37   my $prop = shift;
38
39   my $value = $propmap{$prop}->{'lic_value'};
40
41   if (!$value){
42     die "Can't find value for property \"$prop\"\n";
43   }
44   my $ucf = join("",map {ucfirst(lc($_));}  split(/-/,$prop));
45   my $lc = lc($ucf);
46   my $uc = uc($lc);
47
48   my $ucfvalue = join("",map {ucfirst(lc($_));}  split(/-/,$value));
49   my $lcvalue = lc($ucfvalue);
50   my $ucvalue = uc($lcvalue);
51
52   my $type = $valuemap{$value}->{C}->[1];
53
54   return ($uc,$lc,$lcvalue,$ucvalue,$type);
55
56 }  
57
58 sub insert_code {
59
60 # Create the property map data
61 if($opt_c){
62
63
64   my @props = sort keys %propmap;
65   my $count = scalar(@props);
66   
67
68   print "static const struct icalproperty_map property_map[$count] = {\n";
69   
70   foreach $prop (@props) {
71     
72     next if !$prop;
73     
74     next if $prop eq 'NO';
75     
76     my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop);
77     
78     print "{ICAL_${uc}_PROPERTY,\"$prop\",ICAL_${ucvalue}_VALUE},\n";
79     
80   }
81   
82   $prop = "NO";
83   
84   my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop);
85   
86   print "{ICAL_${uc}_PROPERTY,\"\",ICAL_NO_VALUE}};\n\n";
87
88   $idx = 10000;
89   $count = 1;
90   my $out = "";
91
92   foreach $value (sort keys %valuemap) {
93     
94     next if !$value;    
95     next if $value eq 'NO' or $prop eq 'ANY';
96
97     my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));    
98     my @enums = @{$valuemap{$value}->{'enums'}};
99
100     if(@enums){
101
102       my ($c_autogen,$c_type) = @{$valuemap{$value}->{'C'}};
103       
104       unshift(@enums,"X");
105       push(@enums,"NONE");
106
107       foreach $e (@enums) {
108
109         my $uce = join("",map {uc(lc($_));}  split(/-/,$e));
110         
111         if($e ne "X" and $e ne "NONE"){
112           $str = $e;
113         } else {
114           $str = "";
115         }
116
117         $out.="    {ICAL_${ucv}_PROPERTY,ICAL_${ucv}_${uce},\"$str\" }, /*$idx*/\n";
118
119         $idx++;
120         $count++;
121       }
122       
123     }
124   }
125
126   $count++;
127   print "static const struct icalproperty_enum_map enum_map[$count] = {\n";
128   print $out;
129   print "    {ICAL_NO_PROPERTY,0,\"\"}\n};\n\n";
130   
131
132
133 }
134
135
136 if($opt_h){
137
138   # Create the property enumerations list
139   print "typedef enum icalproperty_kind {\n    ICAL_ANY_PROPERTY = 0,\n";
140   foreach $prop (sort keys %propmap) {
141     
142     next if !$prop;
143     
144     next if $prop eq 'NO' or $prop eq 'ANY';
145     
146     my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop);
147     
148     print "    ICAL_${uc}_PROPERTY, \n";
149     
150   }  
151   print "    ICAL_NO_PROPERTY\n} icalproperty_kind;\n\n";
152
153
154 }
155
156
157 foreach $prop (sort keys %propmap) {
158
159   next if !$prop;
160
161   next if $prop eq 'NO' or $prop eq 'ANY';
162
163   my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop);
164
165   
166   my $pointer_check;
167   if ($type =~ /\*/){
168     $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");\n" if $type =~ /\*/;
169   } elsif ( $type eq "void" ){
170     $pointer_check = "icalerror_check_arg_rv( (v!=0),\"v\");\n" if $type =~ /\*/;
171
172   }    
173
174   my $set_pointer_check = "icalerror_check_arg_rv( (v!=0),\"v\");\n" if $type =~ /\*/;
175
176   if($opt_c) { # Generate C source
177
178    if ($include_vanew) {
179      print<<EOM;
180 icalproperty* icalproperty_vanew_${lc}($type v, ...){
181    va_list args;
182    struct icalproperty_impl *impl;
183    $pointer_check
184    impl= icalproperty_new_impl(ICAL_${uc}_PROPERTY);
185    icalproperty_set_${lc}((icalproperty*)impl,v);
186    va_start(args,v);
187    icalproperty_add_parameters(impl, args);
188    va_end(args);
189    return (icalproperty*)impl;
190 }
191 EOM
192 }
193         print<<EOM;
194
195 /* $prop */
196 icalproperty* icalproperty_new_${lc}($type v) {
197    struct icalproperty_impl *impl;
198    $pointer_check
199    impl = icalproperty_new_impl(ICAL_${uc}_PROPERTY);
200    icalproperty_set_${lc}((icalproperty*)impl,v);
201    return (icalproperty*)impl;
202 }
203
204 EOM
205     # Allow DTSTART, DTEND, DUE, EXDATE and RECURRENCE-ID to take DATE values.
206     if ($lc eq "dtstart" || $lc eq "dtend" || $lc eq "due" || $lc eq "exdate"
207         || $lc eq "recurrenceid") {
208         print<<EOM;
209 void icalproperty_set_${lc}(icalproperty* prop, $type v){
210     icalvalue *value;
211     $set_pointer_check
212     icalerror_check_arg_rv( (prop!=0),"prop");
213     if (v.is_date)
214         value = icalvalue_new_date(v);
215     else
216         value = icalvalue_new_datetime(v);
217     icalproperty_set_value(prop,value);
218 }
219 EOM
220     } else {
221
222         print<<EOM;
223 void icalproperty_set_${lc}(icalproperty* prop, $type v){
224     $set_pointer_check
225     icalerror_check_arg_rv( (prop!=0),"prop");
226     icalproperty_set_value(prop,icalvalue_new_${lcvalue}(v));
227 }
228 EOM
229         }
230 # Dirk Theisen pointed out, exdate needs to match TZID parameters in EXDATE
231     if ($lc eq "exdate") {
232         print<<EOM;
233 $type icalproperty_get_${lc}(const icalproperty* prop){
234 #ifndef _MSC_VER
235         struct icaltimetype itt;
236         icalparameter* param;
237         icaltimezone *zone;
238 #endif
239         icalerror_check_arg( (prop!=0),"prop");
240 #ifndef _MSC_VER
241         /*
242          * Code by dirk\@objectpark.net:
243          * Set the time zone manually. I am really puzzled that 
244          * it doesnot work automatically like in the other functions 
245          * like icalproperty_get_dtstart().
246          */
247         itt = icalvalue_get_datetime(icalproperty_get_value(prop));
248         param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
249         if (param) {
250                 zone = icaltimezone_get_builtin_timezone(icalparameter_get_tzid(param));
251                 icaltime_set_timezone(&itt, zone);
252         }
253         return itt;
254 #else
255     return icalvalue_get_datetime(icalproperty_get_value(prop));
256 #endif
257 }
258 EOM
259     } else {
260         print<<EOM;
261 $type icalproperty_get_${lc}(const icalproperty* prop){
262     icalerror_check_arg( (prop!=0),"prop");
263     return icalvalue_get_${lcvalue}(icalproperty_get_value(prop));
264 }
265 EOM
266     }
267   } elsif ($opt_h) { # Generate C Header file
268
269
270  print "\
271 /* $prop */\
272 icalproperty* icalproperty_new_${lc}($type v);\
273 void icalproperty_set_${lc}(icalproperty* prop, $type v);\
274 $type icalproperty_get_${lc}(const icalproperty* prop);";
275   
276
277 if ($include_vanew){
278   print "icalproperty* icalproperty_vanew_${lc}($type v, ...);\n";
279 }
280
281
282
283
284 } # This brace terminates the main loop
285
286
287
288 if ($opt_h){
289
290 print "\n\n#endif /*ICALPROPERTY_H*/\n"
291 }
292
293 }