1#!/usr/bin/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### END ###
63# End of temporary fix.
64###
65
66use Getopt::Std;
67getopts('chi:');
68
69 #Options
70 # c -> generate c code file
71 # h-> generate header file
72
73 # Open with value-types.txt
74
75my %h = read_values_file($ARGV[0]);
76
77
78 # Write the file inline by copying everything before a demarcation
79 # line, and putting the generated data after the demarcation
80
81if ($opt_i) {
82
83  open(IN,$opt_i) || die "Can't open input file $opt_i";
84
85  while(<IN>){
86    if (/<insert_code_here>/){
87      insert_code();
88    } else {
89      print;
90   }
91
92
93  }
94}
95
96sub insert_code
97{
98 # Map type names to the value in the icalvalue_impl data union */
99
100%union_map = (
101	      BOOLEAN => 'int',
102	      CALADDRESS=>'string',
103	      DATE=>'time',
104	      DATETIME=>'time',
105	      DATETIMEDATE=>'time',
106	      DATETIMEPERIOD=>'period',
107	      DURATION=>'duration',
108	      INTEGER=>'int',
109	      TEXT=>'string',
110	      URI=>'string',
111	      UTCOFFSET=>'int',
112	      QUERY=>'string',
113	      BINARY=>'string',
114	      X=>'string'
115	     );
116
117
118if($opt_h){
119
120  # First print out the value enumerations
121  $idx = 5000;
122  print "typedef enum icalvalue_kind {\n";
123  print "   ICAL_ANY_VALUE=$idx,\n";
124
125  foreach $value  (sort keys %h) {
126
127    $idx++;
128    my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));
129
130    next if $value eq "NO";
131
132    print "    ICAL_${ucv}_VALUE=$idx,\n";
133  }
134
135  $idx++;
136  print "   ICAL_NO_VALUE=$idx\n} icalvalue_kind ;\n\n";
137
138  # Now create enumerations for property values
139  $idx = 10000;
140
141  print "#define ICALPROPERTY_FIRST_ENUM $idx\n\n";
142
143  foreach $value (sort keys %h) {
144
145    next if !$value;
146
147    next if $value eq 'NO' or $prop eq 'ANY';
148
149    my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));
150    my @enums = @{$h{$value}->{'enums'}};
151
152    if(@enums){
153
154      my ($c_autogen,$c_type) = @{$h{$value}->{'C'}};
155      print "typedef $c_type {\n";
156      my $first = 1;
157
158      unshift(@enums,"X");
159
160      push(@enums,"NONE");
161
162      foreach $e (@enums) {
163	if (!$first){
164	  print ",\n";
165	} else {
166	  $first = 0;
167	}
168
169	my $uce = join("",map {uc(lc($_));}  split(/-/,$e));
170
171	print "    ICAL_${ucv}_${uce} = $idx";
172
173	$idx++;
174      }
175
176      $c_type =~ s/enum //;
177
178      print "\n} $c_type;\n\n";
179    }
180  }
181
182  print "#define ICALPROPERTY_LAST_ENUM $idx\n\n";
183
184}
185
186
187if($opt_c){
188
189  # print out the value to string map
190
191  my $count = scalar(keys %h) + 1;
192  print "static const struct icalvalue_kind_map value_map[$count]={\n";
193
194  foreach $value  (sort keys %h) {
195
196    $idx++;
197    my $ucv = join("",map {uc(lc($_));}  split(/-/,$value));
198
199    next if $value eq "NO";
200
201    print "    {ICAL_${ucv}_VALUE,\"$value\"},\n";
202  }
203
204
205  print "    {ICAL_NO_VALUE,\"\"}\n};";
206
207}
208
209
210foreach $value  (sort keys %h) {
211
212  my $autogen = $h{$value}->{C}->[0];
213  my $type = $h{$value}->{C}->[1];
214
215  my $ucf = join("",map {ucfirst(lc($_));}  split(/-/,$value));
216
217  my $lc = lc($ucf);
218  my $uc = uc($lc);
219
220  my $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");\n" if $type =~ /\*/;
221  my $pointer_check_rv = "icalerror_check_arg_rv( (v!=0),\"v\");\n" if $type =~ /\*/;
222
223  my $assign;
224
225  if ($type =~ /char/){
226    $assign = "icalmemory_strdup(v);\n\n    if (impl->data.v_string == 0){\n      errno = ENOMEM;\n    }\n";
227  } else {
228    $assign = "v;";
229  }
230
231  my $union_data;
232
233  if(@{$h{$value}->{'enums'}}){
234    $union_data = 'enum';
235
236  } elsif (exists $union_map{$uc} ){
237    $union_data=$union_map{$uc};
238  } else {
239    $union_data = $lc;
240  }
241
242  if ($opt_c && $autogen) {
243
244    print "\n\n\
245icalvalue* icalvalue_new_${lc} ($type v){\
246   struct icalvalue_impl* impl;\
247   $pointer_check\
248   impl = icalvalue_new_impl(ICAL_${uc}_VALUE);\
249   icalvalue_set_${lc}((icalvalue*)impl,v);\
250   return (icalvalue*)impl;\
251}\
252void icalvalue_set_${lc}(icalvalue* value, $type v) {\
253    struct icalvalue_impl* impl; \
254    icalerror_check_arg_rv( (value!=0),\"value\");\
255    $pointer_check_rv\
256    icalerror_check_value_type(value, ICAL_${uc}_VALUE);\
257    impl = (struct icalvalue_impl*)value;\n";
258
259    if( $union_data eq 'string') {
260
261      print "    if(impl->data.v_${union_data}!=0) {free((void*)impl->data.v_${union_data});}\n";
262    }
263
264
265    print "\n\
266    impl->data.v_$union_data = $assign \n\
267    icalvalue_reset_kind(impl);\n}\n";
268
269    print "$type\ icalvalue_get_${lc} (const icalvalue* value) {\n\n";
270    if( $union_data eq 'string') {
271	print "    icalerror_check_arg_rz ((value!=0),\"value\");\n";
272    }
273    else {
274	print "    icalerror_check_arg ((value!=0),\"value\");\n";
275    }
276    print "    icalerror_check_value_type (value, ICAL_${uc}_VALUE);\
277    return ((struct icalvalue_impl*)value)->data.v_${union_data};\n}\n";
278
279
280  } elsif($opt_h && $autogen) {
281
282    print "\n /* $value */ \
283icalvalue* icalvalue_new_${lc}($type v); \
284$type icalvalue_get_${lc}(const icalvalue* value); \
285void icalvalue_set_${lc}(icalvalue* value, ${type} v);\n\n";
286
287  }
288
289}
290
291
292if ($opt_h){
293    print "#endif /*ICALVALUE_H*/\n";
294  }
295
296
297}
298