Updated the README
[libs.git] / test / mktest.pl
blob5548268a4356daed5fe88bb9d064d908ec663c50
1 #!/usr/bin/perl -w
3 use strict;
4 use Switch;
5 use File::Basename;
7 my $_filename;
8 my $_lineno = 0;
9 my $_output;
10 my $_classname;
11 my $_buffer;
12 my $_funcbuffer = "";
13 my $_varbuffer = "";
14 my $_funclist = "";
15 my $_headerset = 0;
16 # 0 = default/reading, 1 = header, 2 = function/setup/teardown,
17 # 3 = vars
18 my $_state = 0;
19 # buffer to store everything in until state change
20 my $_smallbuf = "";
21 # list of acceptable commands
22 my @_commands = qw(.Header .SetUp .TearDown .Vars .End);
23 my %_declared = ();
25 sub error {
26 my $msg = shift;
27 print STDERR "error: $msg\n";
28 exit 1;
30 sub errorl {
31 my $lineno = shift;
32 my $msg = shift;
33 error("$_filename:$lineno: $msg");
36 sub warning {
37 my $msg = shift;
38 print STDERR "warning: $msg\n";
41 sub warningl {
42 my $lineno = shift;
43 my $msg = shift;
44 warning("$_filename:$lineno: $msg");
47 sub writebuffer {
48 open(COUT,">",$_output) or error $!;
49 print COUT $_buffer;
50 close(COUT);
53 sub flushsmallbuf {
54 switch($_state) {
55 # header
56 case 1 {
57 # append to buffer
58 $_buffer .= $_smallbuf;
60 # function
61 case 2 {
62 # append }
63 $_smallbuf .= "}\n\n";
64 # append to funcbuffer
65 $_funcbuffer .= $_smallbuf;
67 # variable
68 case 3 {
69 # append to varbuffer
70 $_varbuffer .= $_smallbuf;
73 # reset state and smallbuf
74 $_smallbuf = "";
75 $_state = 0;
78 sub special {
79 my $line = shift;
80 if($_state == 0 && $_smallbuf ne "") {
81 errorl($_lineno, "Filler not in section");
84 if(!($line =~ m/^@\.?[[:alnum:]_]+:.*$/) && !($line eq "@.End")) {
85 errorl($_lineno, "Invalid \@-section identifier: `$line'");
88 #my command is your line
89 $line =~ m/^@(\.?[[:alnum:]]+):?/;
90 my $command = $1;
92 #check for invalid command
93 if($command =~ m/^\./) {
94 my @match = grep { $_ eq $command } @_commands;
95 if(scalar @match != 1) {
96 errorl $_lineno, "Invalid command: `$command'";
100 #check for non-strict syntax
101 if($_state != 0) {
102 if($command ne ".End") {
103 warningl $_lineno, "New \@-section without closing \@.End";
104 warningl $_lineno, "Assuming implicit \@.End";
106 flushsmallbuf;
109 #find what command we're actually going to use...
110 switch ($command) {
111 case ".Header" {
112 if($_headerset) {
113 errorl $_lineno, "Double declaration of `\@.Header' section";
115 $_state = 1;
116 $_headerset = 1;
117 $_buffer .= "#line $_lineno \"$_filename\"\n";
118 return;
120 case ".SetUp" {
121 if($_declared{".SetUp"}) {
122 errorl $_lineno, "Double declaration of `\@.SetUp' section";
124 $_state = 2;
125 $_declared{".SetUp"} = 1;
126 $_funcbuffer .= "#line $_lineno \"$_filename\"\nvoid setUp() {\n";
127 return;
129 case ".TearDown" {
130 if($_declared{".TearDown"}) {
131 errorl $_lineno,"Double declaration of `\@.TearDown' section";
133 $_state = 2;
134 $_declared{".TearDown"} = 1;
135 $_funcbuffer .= "#line $_lineno \"$_filename\"\nvoid tearDown() {\n";
136 return;
138 case ".Vars" {
139 if($_varbuffer ne "") {
140 errorl $_lineno, "Double declaration of `\@.Vars' section";
142 $_state = 3;
143 $_varbuffer = "\n#line $_lineno \"$_filename\"\n";
144 return;
146 case ".End" {
147 #okay, done
148 return;
152 # no special command... Then it must be a function name...
153 if($_declared{$command}) {
154 errorl $_lineno, "Double declaration of `$command' testcase";
156 if($command eq "setUp") {
157 errorl $_lineno, "Tried to create a testcase with name `setUp'"
159 if($command eq "tearDown") {
160 errorl $_lineno, "Tried to create a testcase with name `tearDown'"
162 # everything OK!
163 $_state = 2;
164 $_declared{$command} = 1;
165 $_funcbuffer .= "#line $_lineno \"$_filename\"\nvoid $command() {\n";
167 # check for extra attrs...
168 if($line =~ m/:\s*throw\(\s*([[:alnum:]:_]+)\s*\)$/) {
169 $_funclist .= "CPPUNIT_TEST_EXCEPTION($command,$1);\n";
170 } else {
171 $_funclist .= "CPPUNIT_TEST($command);\n";
175 sub parse {
176 my $classname = $_classname;
177 $classname =~ s/\.cpp$//;
178 $classname = "Test" . ucfirst $classname;
180 $_buffer = <<"EOT";
181 /* Generated by mktest.pl. Do not modify by hand! */
183 // include CPPUnit header
184 #include <cppunit/extensions/HelperMacros.h>
186 // @.Header
189 open(CIN, "<", $_filename) or error $!;
190 while(my $line = <CIN>) {
191 $_lineno++;
192 #test if $line is a special marker
193 my $chompline = $line;
194 chomp $chompline;
195 if($chompline =~ m/^@.*/) {
196 special $chompline;
199 # nop, copy in to out.
200 else {
201 if(!($line eq "\n") || $_state != 0) {
202 $_smallbuf .= "$line";
206 #okay, so we are done. Now let's put everything togheter...
207 #$_buffer should contain the header...
208 #so, add the class declaration
209 $_buffer .= <<"EOT";
211 class $classname : public CppUnit::TestFixture {
212 // Function list
213 CPPUNIT_TEST_SUITE($classname);
215 #add the function lists
216 $_buffer .= $_funclist;
218 #add the functions
219 $_buffer .= <<"EOT";
220 CPPUNIT_TEST_SUITE_END();
222 // Test cases
223 public:
225 $_buffer .= $_funcbuffer;
227 #add the vars
228 $_buffer .= "// Variable list\nprivate:$_varbuffer";
230 #finish off...
231 $_buffer .= <<"EOT";
235 // register test suite with CppUnit
236 CPPUNIT_TEST_SUITE_REGISTRATION($classname);
238 #done!
239 close(CIN);
242 sub main {
243 #first check for args...
244 if($#ARGV != 1 or $ARGV[0] =~ m/^-{1,2}h(elp)?$/) {
245 printf STDERR "Usage: mktest.pl <in> <out>" ;
246 exit 1;
248 $_filename = $ARGV[0];
250 #check if filename is a testcase (tst)
251 if(not $_filename =~ m/.*\.tst$/) {
252 warning "$_filename does not have .tst extension -- is it testcase?" ;
255 #get the name of the output file
256 $_output = basename $_filename;
257 $_output =~ s/\..*?$/.cpp/;
258 $_classname = $_output;
259 $_output = $ARGV[1] . "/" . $_output;
260 parse();
261 writebuffer();
264 main;