#!/usr/bin/env perl use strict; use FindBin '$Bin'; require "$Bin/gen-common.pm"; our %tlv_types; my $data = get_json(); sub gen_tlv_type($$$) { my $cname = shift; my $elem = shift; my $indent = shift; my $type = $elem->{"format"}; my $ptype = $elem->{"public-format"}; my $data; $type or return undef; $ptype or $ptype = $type; if ($type eq "guint-sized") { my $size = $elem->{"guint-size"}; if ($size > 4 and $size < 8) { $ptype = "guint64"; } elsif ($size > 2) { $ptype = "guint32"; } else { die "Invalid size for guint-sized"; } } if ($tlv_types{$ptype}) { return $indent.$tlv_types{$ptype}." $cname;"; } elsif ($tlv_types{$type}) { return $indent.$tlv_types{$type}." $cname;"; } elsif ($type eq "string") { return $indent."char *$cname;", 1; } elsif ($type eq "array") { if ($elem->{"fixed-size"}) { my $len_f = '['.$elem->{"fixed-size"}.']'; return gen_tlv_type("$cname$len_f", $elem->{"array-element"}, $indent); } my ($type, $no_set_field) = gen_tlv_type("*$cname", $elem->{"array-element"}, $indent); return undef if not defined $type; return $indent."unsigned int ".substr($cname,1)."\_i;$type", 1 if (!rindex($cname,"*",0)); return $indent."unsigned int $cname\_n;$type", 1; } elsif ($type eq "sequence" or $type eq "struct") { my $contents = $elem->{"contents"}; my $data = "struct {"; foreach my $field (@$contents) { $field = gen_common_ref($field); my $_cname = gen_cname($field->{name}); my ($_data, $no_set_field) = gen_tlv_type($_cname, $field, "$indent\t"); $data .= $_data; } return $indent.$data.$indent."} $cname;"; } else { die "Unknown type: $ptype\n"; } } sub gen_tlv_struct($$) { my $name = shift; my $data = shift; my $_set = ""; my $_data = ""; foreach my $field (@$data) { $field = gen_common_ref($field); my $cname = gen_cname($field->{name}); my ($data, $no_set_field) = gen_tlv_type($cname, $field, "\n\t\t"); next if not defined $data; $_data .= $data; next if $no_set_field; $_set .= "\n\t\tunsigned int $cname : 1;"; } $name = gen_cname($name); $_data or return; $_set .= "\n\t"; $_data .= "\n\t"; print <