source: box/trunk/lib/common/makeexception.pl.in @ 2399

Revision 2399, 5.2 KB checked in by chris, 3 years ago (diff)

Allow exceptions to contain a message string.

  • Property svn:eol-style set to native
Line 
1#!@PERL@
2
3# global exception list file
4my $global_list = '../../ExceptionCodes.txt';
5
6
7my @exception;
8my @exception_desc;
9my $class;
10my $class_number;
11
12# read the description!
13
14open EXCEPTION_DESC,$ARGV[0] or die "Can't open $ARGV[0]";
15
16while(<EXCEPTION_DESC>)
17{
18        chomp; s/\A\s+//; s/#.+\Z//; s/\s+\Z//; s/\s+/ /g;
19        next unless m/\S/;
20
21        if(m/\AEXCEPTION\s+(.+)\s+(\d+)\Z/)
22        {
23                $class = $1;
24                $class_number = $2;
25        }
26        else
27        {
28                my ($name,$number,$description) = split /\s+/,$_,3;
29                if($name eq '' || $number =~ m/\D/)
30                {
31                        die "Bad line '$_'";
32                }
33                if($exception[$number] ne '')
34                {
35                        die "Duplicate exception number $number";
36                }
37                $exception[$number] = $name;
38                $exception_desc[$number] = $description;
39        }
40}
41
42die "Exception class and number not specified" unless $class ne '' && $class_number ne '';
43
44close EXCEPTION_DESC;
45
46# write the code
47print "Generating $class exception...\n";
48
49open CPP,">autogen_${class}Exception.cpp" or die "Can't open cpp file for writing";
50open H,">autogen_${class}Exception.h" or die "Can't open h file for writing";
51
52# write header file
53my $guardname = uc 'AUTOGEN_'.$class.'EXCEPTION_H';
54print H <<__E;
55
56// Auto-generated file -- do not edit
57
58#ifndef $guardname
59#define $guardname
60
61#include "BoxException.h"
62
63// --------------------------------------------------------------------------
64//
65// Class
66//              Name:    ${class}Exception
67//              Purpose: Exception
68//              Created: autogen
69//
70// --------------------------------------------------------------------------
71class ${class}Exception : public BoxException
72{
73public:
74        ${class}Exception(unsigned int SubType,
75                const std::string& rMessage = "")
76        : mSubType(SubType), mMessage(rMessage)
77        {
78        }
79       
80        ${class}Exception(const ${class}Exception &rToCopy)
81        : mSubType(rToCopy.mSubType), mMessage(rToCopy.mMessage)
82        {
83        }
84       
85        ~${class}Exception() throw ()
86        {
87        }
88       
89        enum
90        {
91                ExceptionType = $class_number
92        };
93
94        enum
95        {
96__E
97
98for(my $e = 0; $e <= $#exception; $e++)
99{
100        if($exception[$e] ne '')
101        {
102                print H "\t\t".$exception[$e].' = '.$e.(($e==$#exception)?'':',')."\n"
103        }
104}
105
106print H <<__E;
107        };
108       
109        virtual unsigned int GetType() const throw();
110        virtual unsigned int GetSubType() const throw();
111        virtual const char *what() const throw();
112        virtual const std::string& GetMessage() const
113        {
114                return mMessage;
115        }
116
117private:
118        unsigned int mSubType;
119        std::string mMessage;
120};
121
122#endif // $guardname
123__E
124
125# -----------------------------------------------------------------------------------------------------------
126
127print CPP <<__E;
128
129// Auto-generated file -- do not edit
130
131#include "Box.h"
132#include "autogen_${class}Exception.h"
133
134#include "MemLeakFindOn.h"
135
136#ifdef EXCEPTION_CODENAMES_EXTENDED
137        #ifdef EXCEPTION_CODENAMES_EXTENDED_WITH_DESCRIPTION
138static const char *whats[] = {
139__E
140
141my $last_seen = -1;
142for(my $e = 0; $e <= $#exception; $e++)
143{
144        if($exception[$e] ne '')
145        {
146                for(my $s = $last_seen + 1; $s < $e; $s++)
147                {
148                        print CPP "\t\"UNUSED\",\n"
149                }
150                my $ext = ($exception_desc[$e] ne '')?" ($exception_desc[$e])":'';
151                print CPP "\t\"${class} ".$exception[$e].$ext.'"'.(($e==$#exception)?'':',')."\n";
152                $last_seen = $e;
153        }
154}
155
156print CPP <<__E;
157};
158        #else
159static const char *whats[] = {
160__E
161
162$last_seen = -1;
163for(my $e = 0; $e <= $#exception; $e++)
164{
165        if($exception[$e] ne '')
166        {
167                for(my $s = $last_seen + 1; $s < $e; $s++)
168                {
169                        print CPP "\t\"UNUSED\",\n"
170                }
171                print CPP "\t\"${class} ".$exception[$e].'"'.(($e==$#exception)?'':',')."\n";
172                $last_seen = $e;
173        }
174}
175
176print CPP <<__E;
177};
178        #endif
179#endif
180
181unsigned int ${class}Exception::GetType() const throw()
182{
183        return ${class}Exception::ExceptionType;
184}
185
186unsigned int ${class}Exception::GetSubType() const throw()
187{
188        return mSubType;
189}
190
191const char *${class}Exception::what() const throw()
192{
193#ifdef EXCEPTION_CODENAMES_EXTENDED
194        if(mSubType < 0 || mSubType > (sizeof(whats) / sizeof(whats[0])))
195        {
196                return "${class}";
197        }
198        return whats[mSubType];
199#else
200        return "${class}";
201#endif
202}
203
204__E
205
206close H;
207close CPP;
208
209# update the global exception list
210my $list_before;
211my $list_after;
212my $is_after = 0;
213if(open CURRENT,$global_list)
214{
215        while(<CURRENT>)
216        {
217                next if m/\A#/;
218               
219                if(m/\AEXCEPTION TYPE (\w+) (\d+)/)
220                {
221                        # check that the number isn't being reused
222                        if($2 == $class_number && $1 ne $class)
223                        {
224                                die "Class number $class_number is being used by $class and $1 -- correct this.\n";
225                        }
226                        if($2 > $class_number)
227                        {
228                                # This class comes after the current one (ensures numerical ordering)
229                                $is_after = 1;
230                        }
231                        if($1 eq $class)
232                        {
233                                # skip this entry
234                                while(<CURRENT>)
235                                {
236                                        last if m/\AEND TYPE/;
237                                }
238                                $_ = '';
239                        }
240                }
241               
242                if($is_after)
243                {
244                        $list_after .= $_;
245                }
246                else
247                {
248                        $list_before .= $_;
249                }
250        }
251
252        close CURRENT;
253}
254
255open GLOBAL,">$global_list" or die "Can't open global exception code listing for writing";
256
257print GLOBAL <<__E;
258#
259# automatically generated file, do not edit.
260#
261# This file lists all the exception codes used by the system.
262# Use to look up more detailed descriptions of meanings of errors.
263#
264__E
265
266print GLOBAL $list_before;
267
268print GLOBAL "EXCEPTION TYPE $class $class_number\n";
269for(my $e = 0; $e <= $#exception; $e++)
270{
271        if($exception[$e] ne '')
272        {
273                my $ext = ($exception_desc[$e] ne '')?" - $exception_desc[$e]":'';
274                print GLOBAL "($class_number/$e) - ${class} ".$exception[$e].$ext."\n";
275        }
276}
277print GLOBAL "END TYPE\n";
278
279print GLOBAL $list_after;
280
281close GLOBAL;
282
283
Note: See TracBrowser for help on using the repository browser.