1#!/usr/bin/perl -l 2## Copyright (C) 2017 Intel Corporation 3## 4## Permission is hereby granted, free of charge, to any person obtaining a copy 5## of this software and associated documentation files (the "Software"), to deal 6## in the Software without restriction, including without limitation the rights 7## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8## copies of the Software, and to permit persons to whom the Software is 9## furnished to do so, subject to the following conditions: 10## 11## The above copyright notice and this permission notice shall be included in 12## all copies or substantial portions of the Software. 13## 14## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20## THE SOFTWARE. 21## 22use strict; 23my $fname = shift @ARGV 24 or die("Usage: parsetags.pl tags.txt"); 25open TAGS, "<", $fname 26 or die("Cannot open $fname: $!"); 27 28my %typedescriptions = ( 29 "Integer" => "integer", 30 "ByteString" => "byte string", 31 "TextString" => "UTF-8 text string", 32 "Array" => "array", 33 "Map" => "map", 34 "Tag" => "tag", # shouldn't happen 35 "Simple" => "any simple type", 36 "Boolean" => "boolean", 37 "Null" => "null", 38 "Undefined" => "undefined", 39 "HalfFloat" => "IEEE 754 half-precision floating point", 40 "Float" => "IEEE 754 single-precision floating point", 41 "Double" => "IEEE 754 double-precision floating point" 42); 43 44my %tags; 45while (<TAGS>) { 46 s/\s*#.*$//; 47 next if /^$/; 48 chomp; 49 50 die("Could not parse line \"$_\"") 51 unless /^(\d+);(\w+);([\w,]*);(.*)$/; 52 $tags{$1}{id} = $2; 53 $tags{$1}{semantic} = $4; 54 my @types = split(',', $3); 55 $tags{$1}{types} = \@types; 56} 57close TAGS or die; 58 59my @tagnumbers = sort { $a <=> $b } keys %tags; 60 61print "==== HTML listing ===="; 62print "<table>\n <tr>\n <th>Tag</th>\n <th>Data Item</th>\n <th>Semantics</th>\n </tr>"; 63for my $n (@tagnumbers) { 64 print " <tr>"; 65 print " <td>$n</td>"; 66 67 my @types = @{$tags{$n}{types}}; 68 @types = map { $typedescriptions{$_}; } @types; 69 unshift @types, "any" 70 if (scalar @types == 0); 71 printf " <td>%s</td>\n", join(', ', @types); 72 printf " <td>%s</td>\n", $tags{$n}{semantic}; 73 print " </td>"; 74} 75print "</table>"; 76 77print "\n==== enum listing for cbor.h ====\n"; 78printf "typedef enum CborKnownTags {"; 79my $comma = ""; 80for my $n (@tagnumbers) { 81 printf "%s\n Cbor%sTag%s = %d", $comma, 82 $tags{$n}{id}, 83 ' ' x (23 - length($tags{$n}{id})), 84 $n; 85 $comma = ","; 86} 87print "\n} CborKnownTags;"; 88print "\n/* #define the constants so we can check with #ifdef */"; 89for my $n (@tagnumbers) { 90 printf "#define Cbor%sTag Cbor%sTag\n", $tags{$n}{id}, $tags{$n}{id}; 91} 92 93print "\n==== search table ====\n"; 94print "struct KnownTagData { uint32_t tag; uint32_t types; };"; 95printf "static const struct KnownTagData knownTagData[] = {"; 96$comma = ""; 97for my $n (@tagnumbers) { 98 my @types = @{$tags{$n}{types}}; 99 100 my $typemask; 101 my $shift = 0; 102 for my $type (@types) { 103 die("Too many match types for tag $n") if $shift == 32; 104 my $actualtype = "Cbor${type}Type"; 105 $actualtype = "($actualtype+1)" if $type eq "Integer"; 106 $typemask .= " | " if $typemask ne ""; 107 $typemask .= "((uint8_t)$actualtype << $shift)" if $shift; 108 $typemask .= "(uint8_t)$actualtype" unless $shift; 109 $shift += 8; 110 } 111 $typemask = "0U" if $typemask eq ""; 112 113 printf "%s\n { %d, %s }", $comma, $n, $typemask; 114 $comma = ","; 115} 116print "\n};"; 117