| #!/usr/bin/perl -l |
| ## Copyright (C) 2017 Intel Corporation |
| ## |
| ## Permission is hereby granted, free of charge, to any person obtaining a copy |
| ## of this software and associated documentation files (the "Software"), to deal |
| ## in the Software without restriction, including without limitation the rights |
| ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| ## copies of the Software, and to permit persons to whom the Software is |
| ## furnished to do so, subject to the following conditions: |
| ## |
| ## The above copyright notice and this permission notice shall be included in |
| ## all copies or substantial portions of the Software. |
| ## |
| ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| ## THE SOFTWARE. |
| ## |
| use strict; |
| my $fname = shift @ARGV |
| or die("Usage: parsetags.pl tags.txt"); |
| open TAGS, "<", $fname |
| or die("Cannot open $fname: $!"); |
| |
| my %typedescriptions = ( |
| "Integer" => "integer", |
| "ByteString" => "byte string", |
| "TextString" => "UTF-8 text string", |
| "Array" => "array", |
| "Map" => "map", |
| "Tag" => "tag", # shouldn't happen |
| "Simple" => "any simple type", |
| "Boolean" => "boolean", |
| "Null" => "null", |
| "Undefined" => "undefined", |
| "HalfFloat" => "IEEE 754 half-precision floating point", |
| "Float" => "IEEE 754 single-precision floating point", |
| "Double" => "IEEE 754 double-precision floating point" |
| ); |
| |
| my %tags; |
| while (<TAGS>) { |
| s/\s*#.*$//; |
| next if /^$/; |
| chomp; |
| |
| die("Could not parse line \"$_\"") |
| unless /^(\d+);(\w+);([\w,]*);(.*)$/; |
| $tags{$1}{id} = $2; |
| $tags{$1}{semantic} = $4; |
| my @types = split(',', $3); |
| $tags{$1}{types} = \@types; |
| } |
| close TAGS or die; |
| |
| my @tagnumbers = sort { $a <=> $b } keys %tags; |
| |
| print "==== HTML listing ===="; |
| print "<table>\n <tr>\n <th>Tag</th>\n <th>Data Item</th>\n <th>Semantics</th>\n </tr>"; |
| for my $n (@tagnumbers) { |
| print " <tr>"; |
| print " <td>$n</td>"; |
| |
| my @types = @{$tags{$n}{types}}; |
| @types = map { $typedescriptions{$_}; } @types; |
| unshift @types, "any" |
| if (scalar @types == 0); |
| printf " <td>%s</td>\n", join(', ', @types); |
| printf " <td>%s</td>\n", $tags{$n}{semantic}; |
| print " </td>"; |
| } |
| print "</table>"; |
| |
| print "\n==== enum listing for cbor.h ====\n"; |
| printf "typedef enum CborKnownTags {"; |
| my $comma = ""; |
| for my $n (@tagnumbers) { |
| printf "%s\n Cbor%sTag%s = %d", $comma, |
| $tags{$n}{id}, |
| ' ' x (23 - length($tags{$n}{id})), |
| $n; |
| $comma = ","; |
| } |
| print "\n} CborKnownTags;"; |
| print "\n/* #define the constants so we can check with #ifdef */"; |
| for my $n (@tagnumbers) { |
| printf "#define Cbor%sTag Cbor%sTag\n", $tags{$n}{id}, $tags{$n}{id}; |
| } |
| |
| print "\n==== search table ====\n"; |
| print "struct KnownTagData { uint32_t tag; uint32_t types; };"; |
| printf "static const struct KnownTagData knownTagData[] = {"; |
| $comma = ""; |
| for my $n (@tagnumbers) { |
| my @types = @{$tags{$n}{types}}; |
| |
| my $typemask; |
| my $shift = 0; |
| for my $type (@types) { |
| die("Too many match types for tag $n") if $shift == 32; |
| my $actualtype = "Cbor${type}Type"; |
| $actualtype = "($actualtype+1)" if $type eq "Integer"; |
| $typemask .= " | " if $typemask ne ""; |
| $typemask .= "((uint32_t)$actualtype << $shift)" if $shift; |
| $typemask .= "(uint32_t)$actualtype" unless $shift; |
| $shift += 8; |
| } |
| $typemask = "0U" if $typemask eq ""; |
| |
| printf "%s\n { %d, %s }", $comma, $n, $typemask; |
| $comma = ","; |
| } |
| print "\n};"; |