#!@PERL@ # global exception list file my $global_list = '../../ExceptionCodes.txt'; my @exception; my @exception_desc; my $class; my $class_number; # read the description! open EXCEPTION_DESC,$ARGV[0] or die "Can't open $ARGV[0]"; while() { chomp; s/\A\s+//; s/#.+\Z//; s/\s+\Z//; s/\s+/ /g; next unless m/\S/; if(m/\AEXCEPTION\s+(.+)\s+(\d+)\Z/) { $class = $1; $class_number = $2; } else { my ($name,$number,$description) = split /\s+/,$_,3; if($name eq '' || $number =~ m/\D/) { die "Bad line '$_'"; } if($exception[$number] ne '') { die "Duplicate exception number $number"; } $exception[$number] = $name; $exception_desc[$number] = $description; } } die "Exception class and number not specified" unless $class ne '' && $class_number ne ''; close EXCEPTION_DESC; # write the code print "Generating $class exception...\n"; open CPP,">autogen_${class}Exception.cpp" or die "Can't open cpp file for writing"; open H,">autogen_${class}Exception.h" or die "Can't open h file for writing"; # write header file my $guardname = uc 'AUTOGEN_'.$class.'EXCEPTION_H'; print H <<__E; // Auto-generated file -- do not edit #ifndef $guardname #define $guardname #include "BoxException.h" // -------------------------------------------------------------------------- // // Class // Name: ${class}Exception // Purpose: Exception // Created: autogen // // -------------------------------------------------------------------------- class ${class}Exception : public BoxException { public: ${class}Exception(unsigned int SubType, const std::string& rMessage = "") : mSubType(SubType), mMessage(rMessage), mWhat(GetMessage(SubType) + std::string(rMessage.empty() ? "" : ": ") + rMessage) { } ${class}Exception(const ${class}Exception &rToCopy) : mSubType(rToCopy.mSubType), mMessage(rToCopy.mMessage), mWhat(rToCopy.mWhat) { } ~${class}Exception() throw () { } enum { ExceptionType = $class_number }; enum { __E for(my $e = 0; $e <= $#exception; $e++) { if($exception[$e] ne '') { print H "\t\t".$exception[$e].' = '.$e.(($e==$#exception)?'':',')."\n" } } print H <<__E; }; virtual unsigned int GetType() const throw(); virtual unsigned int GetSubType() const throw(); virtual const char *what() const throw(); virtual const std::string& GetMessage() const { return mMessage; } static const char* GetMessage(int SubType); private: unsigned int mSubType; std::string mMessage; std::string mWhat; }; #endif // $guardname __E # ----------------------------------------------------------------------------------------------------------- print CPP <<__E; // Auto-generated file -- do not edit #include "Box.h" #include "autogen_${class}Exception.h" #include "MemLeakFindOn.h" unsigned int ${class}Exception::GetType() const throw() { return ${class}Exception::ExceptionType; } unsigned int ${class}Exception::GetSubType() const throw() { return mSubType; } const char * ${class}Exception::what() const throw() { return mWhat.c_str(); } const char * ${class}Exception::GetMessage(int SubType) { switch(SubType) { __E for(my $e = 0; $e <= $#exception; $e++) { if($exception[$e] ne '') { print CPP "\t\tcase ".$exception[$e].': return "'.$exception[$e].'";'."\n"; } } print CPP <<__E; default: return "Unknown"; } } __E close H; close CPP; # update the global exception list my $list_before; my $list_after; my $is_after = 0; if(open CURRENT,$global_list) { while() { next if m/\A#/; if(m/\AEXCEPTION TYPE (\w+) (\d+)/) { # check that the number isn't being reused if($2 == $class_number && $1 ne $class) { die "Class number $class_number is being used by $class and $1 -- correct this.\n"; } if($2 > $class_number) { # This class comes after the current one (ensures numerical ordering) $is_after = 1; } if($1 eq $class) { # skip this entry while() { last if m/\AEND TYPE/; } $_ = ''; } } if($is_after) { $list_after .= $_; } else { $list_before .= $_; } } close CURRENT; } open GLOBAL,">$global_list" or die "Can't open global exception code listing for writing"; print GLOBAL <<__E; # # automatically generated file, do not edit. # # This file lists all the exception codes used by the system. # Use to look up more detailed descriptions of meanings of errors. # __E print GLOBAL $list_before; print GLOBAL "EXCEPTION TYPE $class $class_number\n"; for(my $e = 0; $e <= $#exception; $e++) { if($exception[$e] ne '') { my $ext = ($exception_desc[$e] ne '')?" - $exception_desc[$e]":''; print GLOBAL "($class_number/$e) - ${class} ".$exception[$e].$ext."\n"; } } print GLOBAL "END TYPE\n"; print GLOBAL $list_after; close GLOBAL;