Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 144 lines (116 sloc) 5.119 kb
df7b968d »
2012-02-15 Print pretty names for flags, pretty documentation, allow a user spec…
1 #!/usr/local/bin/perl
2
3 #
4 # Copyright (c) 2012, Yahoo! Inc All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 #
9 # Redistributions of source code must retain the above copyright notice,
10 # this list of conditions and the following disclaimer. Redistributions
11 # in binary form must reproduce the above copyright notice, this list
12 # of conditions and the following disclaimer in the documentation and/or
13 # other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20 # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 # THE POSSIBILITY OF SUCH DAMAGE.
26 #
27 # Author: John Eaglesham
28 #
29 # This file is meant to parse the output of:
30 # http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml
31 # And turn it into a semi-useful C code.
32 #
33
34 use warnings;
35 use strict;
36
37 use XML::XPath;
38 use Data::Dumper;
39
40 # If we get a description that matches one of these regular expressions, we
41 # will ignore it. That way we avoid bloat in our output code because the
42 # default description is "Unassigned".
43 my $treat_as_unassigned_type = qr/unassigned/i;
44 my $treat_as_unassigned_code = qr/no code/i;
45
46 my %icmp_codes;
47 my $xp = XML::XPath->new(filename => 'icmp-parameters.xml');
48
49 my $registry = $xp->find('/registry/registry[@id="icmp-parameters-types"]');
50 if ( $registry->size() != 1 ) {
51 die "Don't know how to parse this file.";
52 }
53
54 my $nodeset = $registry->pop()->find('record');
55
56 foreach my $node ($nodeset->get_nodelist()) {
57 my $value = $node->find('value');
58 if ( $value->size() != 1 ) { next; }
59 $value = $value->pop()->string_value;
60
61 my $descr = $node->find('description');
62 if ( $descr->size() != 1 ) { next; }
63 $descr = $descr->pop()->string_value;
64
65 if ( $value !~ /^\d+$/ || !$descr || $descr =~ $treat_as_unassigned_type ) { next; }
66 $descr =~ s/\n+//g;
67 $descr =~ s/[^[:print:]]//;
68 $descr =~ s/ +/ /g;
69 $icmp_codes{$value} = { descr => $descr };
70 }
71
72 undef $nodeset;
73 $registry = $xp->find('/registry/registry[@id="icmp-parameters-codes"]/registry');
74
75 if ( $registry->size() < 1 ) {
76 die "Don't know how to parse this file.";
77 }
78
79 foreach my $code_node ($registry->get_nodelist()) {
80 my $id = $code_node->getAttribute('id');
81
82 if ( !defined $id || $id !~ /^icmp-parameters-codes-/ ) {
83 die "Don't know how to parse this file.";
84 }
85
86 # Skip the codes that give a range.
87 if ( $id !~ /^icmp-parameters-codes-(\d+)$/ ) {
88 next;
89 }
90 $id = $1;
91
92 $nodeset = $code_node->find('record');
93 foreach my $node ($nodeset->get_nodelist()) {
94 my $value = $node->find('value');
95 if ( $value->size() != 1 ) { next; }
96 $value = $value->pop()->string_value;
97
98 my $descr = $node->find('description');
99 if ( $descr->size() != 1 ) { next; }
100 $descr = $descr->pop()->string_value;
101
102 if ( $value !~ /^\d+$/ || !$descr || $descr =~ $treat_as_unassigned_code ) { next; }
103 $descr =~ s/\n+//g;
104 $descr =~ s/ +/ /g;
105
106 if ( !exists $icmp_codes{$id} ) { next; }
107 $icmp_codes{$id}->{codes}->{$value} = $descr;
108 }
109 }
110
111 # It would be possible to create an array, but the array would have a lot of
112 # "holes", meaning you would have to allocate 255 entries but the vast
113 # majority would be set to NULL. The problem would be worse for the codes.
114 #foreach my $type ( sort{ $a <=> $b } ( keys( %icmp_codes ) ) ) {
115 # my $name = $icmp_codes{$type}->{descr};
116 # print qq{icmp_type_names[$type] = "$name"\n};
117 #}
118
119 # Instead we generate functions.
120 print qq#char *icmp_type_to_name( unsigned char type )\n{\n#;
121
122 foreach my $type ( sort{ $a <=> $b } ( keys( %icmp_codes ) ) ) {
123 my $name = $icmp_codes{$type}->{descr};
124 print qq# if ( type == $type ) return "$name";\n#;
125 }
126
013e89b1 »
2012-02-15 Update flag types, update documentation.
127 print qq# return "Unassigned";\n}\n\n#;
df7b968d »
2012-02-15 Print pretty names for flags, pretty documentation, allow a user spec…
128
013e89b1 »
2012-02-15 Update flag types, update documentation.
129 print qq#char *icmp_code_to_name( unsigned char type, unsigned char code )\n{\n#;
df7b968d »
2012-02-15 Print pretty names for flags, pretty documentation, allow a user spec…
130
131 foreach my $type ( sort{ $a <=> $b } ( keys( %icmp_codes ) ) ) {
132 if ( !exists $icmp_codes{$type}->{codes} ) { next; }
133 print qq# if ( type == $type ) {\n#;
134 foreach my $code ( sort{ $a <=> $b } ( keys( %{ $icmp_codes{$type}->{codes} } ) ) ) {
135 my $name = $icmp_codes{$type}->{codes}->{$code};
136 print qq# if ( code == $code ) return "$name";\n#;
137 }
138 print qq# }\n#;
139 }
140
013e89b1 »
2012-02-15 Update flag types, update documentation.
141 print qq# return "Unassigned";\n}\n\n#;
df7b968d »
2012-02-15 Print pretty names for flags, pretty documentation, allow a user spec…
142
143 #die Dumper \%icmp_codes;
Something went wrong with that request. Please try again.