16 $s =~ s/([\"\'\\])/\\$1/g;
22 my @comp = split(/-/, $a);
26 # All names are prefixes in their own right, although we only
27 # list the ones that are either prefixes of "proper names" or
28 # the complete alias name.
29 for (my $i = ($a eq $this->{name
}) ?
0 : $#comp; $i <= $#comp; $i++) {
30 my $prefix = join('-', @comp[0..$i]);
31 $prefixes{$prefix} = [] unless defined($prefixes{$prefix});
32 push(@
{$prefixes{$prefix}}, $a);
39 return unless (basename
($infile) =~ /^\w.*\.[ch]$/i);
40 open(my $in, '<', $infile)
41 or die "$0: cannot open input file $infile: $!\n";
48 while (defined(my $l = <$in>)) {
53 $l =~ s/^.*?\/\*.*?\*\///g; # Remove single-line comments
55 if ($l =~ /^.*?(\/\
*.*)$/) {
67 } elsif ($l =~ /^\s*\/?\
*\
!(\
-|\
=|\s
*)(.*?
)\s
*$/) {
71 if ($opr eq '' && $str eq '') {
73 } elsif ((!defined($this) || ($opr eq '')) &&
74 ($str =~ /^([\w\-]+)\s+\[(\w+)\]\s(.*\S)\s*$/)) {
79 my $cname = uc($name);
80 $cname =~ s/[^A-Z0-9_]+/_/g;
82 $this = {name
=> $name, cname
=> $cname,
83 def
=> $def, help
=> $help,
84 doc
=> [], file
=> $infile, line
=> $nline};
86 if (defined(my $that = $aliases{$name})) {
87 # Duplicate defintion?!
88 printf STDERR
"%s:%s: warning %s previously defined at %s:%s\n",
89 $infile, $nline, $name, $that->{file
}, $that->{line
};
91 push(@warnings, $this);
92 # Every warning name is also a valid warning alias
93 add_alias
($name, $this);
96 } elsif ($opr eq '=') {
97 # Alias names for warnings
98 for my $a (split(/,+/, $str)) {
101 } elsif ($opr =~ /^[\-\s]/) {
102 push(@
{$this->{doc
}}, "$str\n");
104 print STDERR
"$infile:$nline: malformed warning definition\n";
105 print STDERR
" $l\n";
116 my($what, $outfile, @indirs) = @ARGV;
118 if (!defined($outfile)) {
119 die "$0: usage: [c|h|doc] outfile indir...\n";
122 find
({ wanted
=> \
&find_warnings
, no_chdir
=> 1, follow
=> 1 }, @indirs);
126 my %sort_special = ( 'other' => 1, 'all' => 2 );
130 return ($sort_special{$an} <=> $sort_special{$bn}) || ($an cmp $bn);
133 @warnings = sort sort_warnings
@warnings;
134 my @warn_noall = @warnings;
135 pop @warn_noall if ($warn_noall[$#warn_noall]->{name
} eq 'all');
137 open(my $out, '>', $outfile)
138 or die "$0: cannot open output file $outfile: $!\n";
141 print $out "#include \"error.h\"\n\n";
142 printf $out "const char * const warning_name[%d] = {\n",
145 foreach my $warn (@warnings) {
146 print $out ",\n\t\"", $warn->{name
}, "\"";
148 print $out "\n};\n\n";
149 printf $out "const struct warning_alias warning_alias[%d] = {",
150 scalar(keys %aliases);
152 foreach my $alias (sort { $a cmp $b } keys(%aliases)) {
153 printf $out "%s\n\t{ %-27s WARN_IDX_%s }",
154 $sep, "\"$alias\",", $aliases{$alias}->{cname
};
157 print $out "\n};\n\n";
159 printf $out "const char * const warning_help[%d] = {\n",
162 foreach my $warn (@warnings) {
163 my $help = quote_for_c
($warn->{help
});
164 print $out ",\n\t\"", $help, "\"";
166 print $out "\n};\n\n";
167 printf $out "const uint8_t warning_default[%d] = {\n",
169 print $out "\tWARN_INIT_ON"; # for entry 0
170 foreach my $warn (@warn_noall) {
171 print $out ",\n\tWARN_INIT_", uc($warn->{def
});
173 print $out "\n};\n\n";
174 printf $out "uint8_t warning_state[%d];\t/* Current state */\n",
176 } elsif ($what eq 'h') {
177 my $filename = basename
($outfile);
178 my $guard = $filename;
179 $guard =~ s/[^A-Za-z0-9_]+/_/g;
180 $guard = "NASM_\U$guard";
182 print $out "#ifndef $guard\n";
183 print $out "#define $guard\n";
185 print $out "#ifndef WARN_SHR\n";
186 print $out "# error \"$filename should only be included from within error.h\"\n";
187 print $out "#endif\n\n";
188 print $out "enum warn_index {\n";
189 printf $out "\tWARN_IDX_%-23s = %3d, /* not suppressible */\n", 'NONE', 0;
191 foreach my $warn (@warnings) {
192 printf $out "\tWARN_IDX_%-23s = %3d%s /* %s */\n",
194 ($n == $#warnings + 1) ?
" " : ",",
200 print $out "enum warn_const {\n";
201 printf $out "\tWARN_%-27s = %3d << WARN_SHR", 'NONE', 0;
203 foreach my $warn (@warn_noall) {
204 printf $out ",\n\tWARN_%-27s = %3d << WARN_SHR", $warn->{cname
}, $n++;
206 print $out "\n};\n\n";
208 print $out "struct warning_alias {\n";
209 print $out "\tconst char *name;\n";
210 print $out "\tenum warn_index warning;\n";
212 printf $out "#define NUM_WARNING_ALIAS %d\n", scalar(keys %aliases);
214 printf $out "extern const char * const warning_name[%d];\n",
216 printf $out "extern const char * const warning_help[%d];\n",
218 print $out "extern const struct warning_alias warning_alias[NUM_WARNING_ALIAS];\n";
219 printf $out "extern const uint8_t warning_default[%d];\n",
221 printf $out "extern uint8_t warning_state[%d];\n",
223 print $out "\n#endif /* $guard */\n";
224 } elsif ($what eq 'doc') {
225 my %whatdef = ( 'on' => 'Enabled',
227 'err' => 'Enabled and promoted to error' );
229 foreach my $pfx (sort { $a cmp $b } keys(%prefixes)) {
230 my $warn = $aliases{$pfx};
233 if (!defined($warn)) {
234 my @plist = sort { $a cmp $b } @
{$prefixes{$pfx}};
235 next if ( $#plist < 1 );
237 @doc = ("is a group alias for all warning classes prefixed by ".
238 "\\c{".$pfx."-}; currently\n");
239 for (my $i = 0; $i <= $#plist; $i++) {
244 push(@doc, ($i == 1) ?
" and " : ", and ");
247 push(@doc, '\c{'.$plist[$i].'}');
250 } elsif ($pfx ne $warn->{name
}) {
251 @doc = ("is a backwards compatibility alias for \\c{",
252 $warn->{name
}, "}.\n");
254 my $docdef = $whatdef{$warn->{def
}};
257 foreach my $l (@
{$warn->{doc
}}) {
261 if ($newpara && $l !~ /^\\c\s+/) {
268 if (defined($docdef)) {
269 push(@doc, "\n", "\\> $docdef by default.\n");
273 print $out "\\b \\i\\c{", $pfx, "} ", @doc, "\n";