#!/usr/bin/perl ################################################################################ # (C) COPYRIGHT 2000, Eric Busboom # # This library is free software; you can redistribute it and/or modify # it under the terms of either: # # The LGPL as published by the Free Software Foundation, version # 2.1, available at: https://www.gnu.org/licenses/lgpl-2.1.txt # # Or: # # The Mozilla Public License Version 2.0. You may obtain a copy of # the License at https://www.mozilla.org/MPL/ ################################################################################ use lib '.'; require 'readvaluesfile.pl'; use Getopt::Std; getopts('chi:'); #Options # c -> generate c code file # h-> generate header file # Open with value-types.txt my %h = read_values_file($ARGV[0]); # Write the file inline by copying everything before a demarcation # line, and putting the generated data after the demarcation if ($opt_i) { open(IN, $opt_i) || die "Can't open input file $opt_i"; while () { if (//) { insert_code(); } else { print; } } if ($opt_h) { print "#endif /*ICALVALUE_H*/\n"; } } sub insert_code { # Map type names to the value in the icalvalue_impl data union */ %union_map = ( BOOLEAN => 'int', CALADDRESS => 'string', DATE => 'time', DATETIME => 'time', DATETIMEDATE => 'time', DATETIMEPERIOD => 'period', DURATION => 'duration', INTEGER => 'int', TEXT => 'string', URI => 'string', UTCOFFSET => 'int', QUERY => 'string', X => 'string' ); if ($opt_h) { # First print out the value enumerations $idx = $h{'ANY'}->{"kindEnum"}; print "typedef enum icalvalue_kind {\n"; print " ICAL_ANY_VALUE=$idx,\n"; foreach $value (sort keys %h) { next if !$value; next if $value eq 'NO' or $value eq 'ANY'; my $ucv = join("", map {uc(lc($_));} split(/-/, $value)); $idx = $h{$value}->{"kindEnum"}; print " ICAL_${ucv}_VALUE=$idx,\n"; } $idx = $h{'NO'}->{"kindEnum"}; print " ICAL_NO_VALUE=$idx\n} icalvalue_kind ;\n\n"; # Now create enumerations for property values $lastidx = $idx = 10000; print "#define ICALPROPERTY_FIRST_ENUM $idx\n\n"; foreach $value (sort keys %h) { next if !$value; next if $value eq 'NO' or $value eq 'ANY'; my $ucv = join("", map {uc(lc($_));} split(/-/, $value)); my @enums = @{$h{$value}->{'enums'}}; if (@enums) { my ($c_autogen, $c_type) = @{$h{$value}->{'C'}}; print "typedef $c_type {\n"; my $first = 1; foreach $e (@enums) { if (!$first) { print ",\n"; } else { $first = 0; } $e =~ /([a-zA-Z0-9\-]+)=?([0-9]+)?/; $e = $1; if ($2) { $idx = $2; } else { $idx++; } if ($idx > $lastidx) { $lastidx = $idx; } my $uce = join("", map {uc(lc($_));} split(/-/, $e)); print " ICAL_${ucv}_${uce} = $idx"; } $c_type =~ s/enum //; print "\n} $c_type;\n\n"; } } $lastidx++; print "#define ICALPROPERTY_LAST_ENUM $lastidx\n"; } if ($opt_c) { # print out the value to string map my $count = scalar(keys %h) + 1; print "static const struct icalvalue_kind_map value_map[$count]={\n"; foreach $value (sort keys %h) { next if $value eq 'NO' or $value eq 'ANY'; my $ucv = join("", map {uc(lc($_));} split(/-/, $value)); print " {ICAL_${ucv}_VALUE,\"$value\"},\n"; } print " {ICAL_NO_VALUE,\"\"}\n};"; } foreach $value (sort keys %h) { next if $value eq 'ANY'; my $autogen = $h{$value}->{C}->[0]; my $type = $h{$value}->{C}->[1]; $type =~ s/char\*/char \*/; my $ucf = join("", map {ucfirst(lc($_));} split(/-/, $value)); my $lc = lc($ucf); my $uc = uc($lc); my $pointer_check = " icalerror_check_arg_rz((v != 0), \"v\");\n" if $type =~ /\*/; my $pointer_check_rv = " icalerror_check_arg_rv((v != 0), \"v\");\n" if $type =~ /\*/; my $assign; if ($type =~ /char/) { $assign = "icalmemory_strdup(v);\n\n if (impl->data.v_string == 0) {\n errno = ENOMEM;\n }\n"; } else { $assign = "v;"; } my $union_data; if (@{$h{$value}->{'enums'}}) { $union_data = 'enum'; } elsif (exists $union_map{$uc}) { $union_data = $union_map{$uc}; } else { $union_data = $lc; } if ($opt_c && $autogen) { print "\ icalvalue *icalvalue_new_${lc}($type v)\ {\ struct icalvalue_impl *impl;\ $pointer_check\ impl = icalvalue_new_impl(ICAL_${uc}_VALUE);\ icalvalue_set_${lc}((icalvalue *)impl, v);\ return (icalvalue*)impl;\ }\ \ void icalvalue_set_${lc}(icalvalue *value, $type v)\ {\ struct icalvalue_impl *impl;\ icalerror_check_arg_rv((value != 0), \"value\");\ $pointer_check_rv\ icalerror_check_value_type(value, ICAL_${uc}_VALUE);\ impl = (struct icalvalue_impl *)value;\n"; if ($union_data eq 'string') { print " if (impl->data.v_${union_data} != 0) {\n free((void *)impl->data.v_${union_data});\n }\n"; } print "\ impl->data.v_$union_data = $assign\ icalvalue_reset_kind(impl);\n}\n\n"; print "$type\ icalvalue_get_${lc}(const icalvalue *value)\n{\n"; if ($union_data eq 'string') { print " icalerror_check_arg_rz((value != 0), \"value\");\n"; } else { print " icalerror_check_arg((value != 0), \"value\");\n"; if ($union_data eq 'enum') { print " if (!value) {\n return ICAL_${uc}_NONE;\n }\n"; } elsif ($union_data eq 'int') { print " if (!value) {\n return 0;\n }\n"; } elsif ($union_data eq 'float') { print " if (!value) {\n return 0.0;\n }\n"; } elsif ($union_data eq 'time') { print " if (!value) {\n return icaltime_null_time();\n }\n"; } elsif ($union_data eq 'duration') { print " if (!value) {\n return icaldurationtype_null_duration();\n }\n"; } elsif ($union_data eq 'period') { print " if (!value) {\n return icalperiodtype_null_period();\n }\n"; } elsif ($union_data eq 'requeststatus') { print " if (!value) {\n return icalreqstattype_from_string(\"0.0\");\n }\n"; } } print " icalerror_check_value_type(value, ICAL_${uc}_VALUE);\ return ((struct icalvalue_impl *)value)->data.v_${union_data};\n}\n"; } elsif ($opt_h && $autogen) { print "\n/* $value */\ LIBICAL_ICAL_EXPORT icalvalue *icalvalue_new_${lc}($type v);\ LIBICAL_ICAL_EXPORT $type icalvalue_get_${lc}(const icalvalue *value);\ LIBICAL_ICAL_EXPORT void icalvalue_set_${lc}(icalvalue *value, ${type} v);\n"; } } }