#! /usr/local/bin/perl use strict; use Getopt::Long; use XML::Parser; (my $progname = $0) =~ s!^.*/!!; sub usage { my $errstr = "@_"; while (chomp($errstr)) {} print <$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 < 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: