mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
6386c55cee
BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
181 lines
4.1 KiB
Perl
181 lines
4.1 KiB
Perl
#! /usr/local/bin/perl
|
|
|
|
use strict;
|
|
use Getopt::Long;
|
|
use XML::Parser;
|
|
|
|
(my $progname = $0) =~ s!^.*/!!;
|
|
|
|
sub usage {
|
|
my $errstr = "@_";
|
|
while (chomp($errstr)) {}
|
|
print <<END;
|
|
$progname: $errstr
|
|
$progname -- read codes.xml and write codes.hpp and codes.cpp
|
|
usage: $progname [options] codes.xml
|
|
-c check xml file only
|
|
-d check xml file and show diff against old hpp and cpp
|
|
END
|
|
exit(1);
|
|
}
|
|
|
|
my $opts = {};
|
|
opts: {
|
|
local $SIG{__WARN__} = \&usage;
|
|
GetOptions($opts, qw(c d));
|
|
}
|
|
@ARGV == 1 or usage("one filename argument expected");
|
|
my $filexml = shift;
|
|
$filexml =~ /^(.*)\.xml$/ or usage("$filexml does not end in .xml");
|
|
my $filehpp = "$1.hpp";
|
|
my $filecpp = "$1.cpp";
|
|
|
|
my $temphpp = "$filehpp-new";
|
|
my $tempcpp = "$filecpp-new";
|
|
unlink $temphpp, $tempcpp;
|
|
open(HPP, ">$temphpp") or die "$temphpp: $!\n";
|
|
open(CPP, ">$tempcpp") or die "$tempcpp: $!\n";
|
|
|
|
my $i2 = " " x 2;
|
|
my $i4 = " " x 4;
|
|
my $lb = "{";
|
|
my $rb = "}";
|
|
|
|
sub disclaimer {
|
|
my $filename = shift;
|
|
return <<END;
|
|
/*
|
|
* $filename -- DO NOT EDIT !!
|
|
*
|
|
* To create a new version (both *.hpp and *.cpp):
|
|
*
|
|
* 1) edit $filexml
|
|
* 2) perl tools/$progname $filexml
|
|
* 3) check all files (*.xml *.hpp *.cpp) into CVS
|
|
*
|
|
* On RedHat linux requires perl-XML-Parser package.
|
|
*/
|
|
END
|
|
}
|
|
|
|
my $classname = $filehpp;
|
|
$classname =~ s!^.*/!!;
|
|
$classname =~ s/\.hpp$//;
|
|
|
|
sub handle_init {
|
|
my($parser) = @_;
|
|
my $guard = $filehpp;
|
|
$guard =~ s!^.*/!!;
|
|
$guard =~ s!([a-z])([A-Z])!${1}_${2}!g;
|
|
$guard =~ s!\.!_!g;
|
|
$guard = uc($guard);
|
|
print HPP "#ifndef $guard\n#define $guard\n\n";
|
|
print HPP disclaimer($filehpp), "\n";
|
|
print HPP "class $classname $lb\n";
|
|
print HPP "${i2}enum Value $lb\n";
|
|
print CPP disclaimer($filecpp), "\n";
|
|
print CPP "/* included in Ndberror.cpp */\n\n";
|
|
}
|
|
|
|
my %classhash = (
|
|
ApplicationError => 1,
|
|
NoDataFound => 1,
|
|
ConstraintViolation => 1,
|
|
SchemaError => 1,
|
|
UserDefinedError => 1,
|
|
InsufficientSpace => 1,
|
|
TemporaryResourceError => 1,
|
|
NodeRecoveryError => 1,
|
|
OverloadError => 1,
|
|
TimeoutExpired => 1,
|
|
UnknownResultError => 1,
|
|
InternalError => 1,
|
|
FunctionNotImplemented => 1,
|
|
UnknownErrorCode => 1,
|
|
NodeShutdown => 1,
|
|
);
|
|
|
|
my $section = undef;
|
|
my %codehash = ();
|
|
my %namehash = ();
|
|
|
|
sub handle_start {
|
|
my($parser, $tag, %attr) = @_;
|
|
if ($tag eq 'Error') {
|
|
return;
|
|
}
|
|
if ($tag eq 'Section') {
|
|
$section = $attr{name};
|
|
$section =~ /^\w+$/ or
|
|
$parser->xpcroak("invalid or missing section name");
|
|
return;
|
|
}
|
|
if ($tag eq 'Code') {
|
|
print HPP ",\n" if %codehash;
|
|
print CPP ",\n" if %codehash;
|
|
my $name = $attr{name};
|
|
my $class = $attr{class};
|
|
my $code = $attr{code};
|
|
my $message = $attr{message};
|
|
$name =~ /^\w+$/ or
|
|
$parser->xpcroak("invalid or missing error name '$name'");
|
|
$namehash{$name}++ and
|
|
$parser->xpcroak("duplicate error name '$name'");
|
|
$classhash{$class} or
|
|
$parser->xpcroak("invalid or missing error class '$class'");
|
|
$code =~ /^\d+$/ or
|
|
$parser->xpcroak("invalid or missing error code '$code'");
|
|
$codehash{$code}++ and
|
|
$parser->xpcroak("duplicate error code '$code'");
|
|
$message =~ /\S/ or
|
|
$parser->xpcroak("invalid or missing error message '$message'");
|
|
$message =~ s/^\s+|\s+$//g;
|
|
my $enum = "${section}_${name}";
|
|
print HPP "${i4}$enum = $code";
|
|
print CPP "${i2}$lb ${classname}::$enum,\n";
|
|
print CPP "${i4}NdbError::$class,\n";
|
|
print CPP "${i4}\"$message\"\n";
|
|
print CPP "${i2}$rb";
|
|
return;
|
|
}
|
|
$parser->xpcroak("unknown tag $tag");
|
|
}
|
|
|
|
sub handle_end {
|
|
my($parser, $tag) = @_;
|
|
}
|
|
|
|
sub handle_final {
|
|
print HPP "\n" if %codehash;
|
|
print HPP "${i2}$rb;\n";
|
|
print HPP "$rb;\n\n#endif\n";
|
|
print CPP ",\n" if 1;
|
|
return 1;
|
|
}
|
|
|
|
my $parser = new XML::Parser(
|
|
ParseParamEnt => 1,
|
|
Handlers => {
|
|
Init => \&handle_init,
|
|
Start => \&handle_start,
|
|
End => \&handle_end,
|
|
Final => \&handle_final,
|
|
},
|
|
ErrorContext => 0,
|
|
);
|
|
eval {
|
|
$parser->parsefile($filexml);
|
|
};
|
|
if ($@) {
|
|
my $errstr = join("\n", grep(m!\S! && ! m!^\s*at\s!, split(/\n/, $@)));
|
|
die "$filexml:\n$errstr\n";
|
|
}
|
|
|
|
close(HPP);
|
|
close(CPP);
|
|
rename($temphpp, $filehpp);
|
|
rename($tempcpp, $filecpp);
|
|
|
|
1;
|
|
|
|
# vim:set sw=4:
|