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