blob: 318629fe1b849a3a7e9a44084452fe498efe1e09 [file] [log] [blame] [raw]
Markus Pfeiffera26a0052014-04-22 20:16:15 +00001#!/usr/bin/env perl
Paul Bakker367dae42009-06-28 21:50:27 +00002#
3
4use strict;
5
6my $suite_dir = shift or die "Missing suite directory";
7my $suite_name = shift or die "Missing suite name";
Paul Bakker46c17942011-07-13 14:54:54 +00008my $data_name = shift or die "Missing data name";
9my $test_file = $data_name.".c";
Paul Bakker367dae42009-06-28 21:50:27 +000010my $test_helper_file = $suite_dir."/helpers.function";
11my $test_case_file = $suite_dir."/".$suite_name.".function";
Paul Bakker19343182013-08-16 13:31:10 +020012my $test_case_data = $suite_dir."/".$data_name.".data";
13my $test_main_file = $suite_dir."/main_test.function";
Paul Bakker367dae42009-06-28 21:50:27 +000014
15my $line_separator = $/;
16undef $/;
17
18open(TEST_HELPERS, "$test_helper_file") or die "Opening test helpers '$test_helper_file': $!";
19my $test_helpers = <TEST_HELPERS>;
20close(TEST_HELPERS);
21
Paul Bakker19343182013-08-16 13:31:10 +020022open(TEST_MAIN, "$test_main_file") or die "Opening test main '$test_main_file': $!";
23my $test_main = <TEST_MAIN>;
24close(TEST_MAIN);
25
Paul Bakker367dae42009-06-28 21:50:27 +000026open(TEST_CASES, "$test_case_file") or die "Opening test cases '$test_case_file': $!";
27my $test_cases = <TEST_CASES>;
28close(TEST_CASES);
Paul Bakker19343182013-08-16 13:31:10 +020029
30open(TEST_DATA, "$test_case_data") or die "Opening test data '$test_case_data': $!";
31my $test_data = <TEST_DATA>;
32close(TEST_DATA);
33
Paul Bakker33b43f12013-08-20 11:48:36 +020034my ( $suite_header ) = $test_cases =~ /\/\* BEGIN_HEADER \*\/\n(.*?)\n\/\* END_HEADER \*\//s;
35my ( $suite_defines ) = $test_cases =~ /\/\* BEGIN_DEPENDENCIES\n \* (.*?)\n \* END_DEPENDENCIES/s;
Paul Bakker5690efc2011-05-26 13:16:06 +000036
37my $requirements;
38if ($suite_defines =~ /^depends_on:/)
39{
40 ( $requirements ) = $suite_defines =~ /^depends_on:(.*)$/;
41}
Paul Bakker19343182013-08-16 13:31:10 +020042
Paul Bakker5690efc2011-05-26 13:16:06 +000043my @var_req_arr = split(/:/, $requirements);
44my $suite_pre_code;
45my $suite_post_code;
Paul Bakker19343182013-08-16 13:31:10 +020046my $dispatch_code;
47my $mapping_code;
48my %mapping_values;
Paul Bakker5690efc2011-05-26 13:16:06 +000049
50while (@var_req_arr)
51{
52 my $req = shift @var_req_arr;
53
54 $suite_pre_code .= "#ifdef $req\n";
55 $suite_post_code .= "#endif /* $req */\n";
56}
Paul Bakker367dae42009-06-28 21:50:27 +000057
58$/ = $line_separator;
59
60open(TEST_FILE, ">$test_file") or die "Opening destination file '$test_file': $!";
61print TEST_FILE << "END";
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020062#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker28837ff2013-06-24 19:17:50 +020063#include <polarssl/config.h>
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020064#else
65#include POLARSSL_CONFIG_FILE
66#endif
Paul Bakker5690efc2011-05-26 13:16:06 +000067
Paul Bakkerde56ca12013-09-15 17:05:21 +020068$suite_pre_code
Paul Bakker367dae42009-06-28 21:50:27 +000069$suite_header
Paul Bakkerde56ca12013-09-15 17:05:21 +020070$suite_post_code
Paul Bakker367dae42009-06-28 21:50:27 +000071
72$test_helpers
73
Paul Bakker367dae42009-06-28 21:50:27 +000074END
Paul Bakkerb34fef22013-08-20 12:06:33 +020075
76$test_main =~ s/SUITE_PRE_DEP/$suite_pre_code/;
77$test_main =~ s/SUITE_POST_DEP/$suite_post_code/;
Paul Bakker367dae42009-06-28 21:50:27 +000078
Paul Bakker33b43f12013-08-20 11:48:36 +020079while($test_cases =~ /\/\* BEGIN_CASE *([\w:]*) \*\/\n(.*?)\n\/\* END_CASE \*\//msg)
Paul Bakker367dae42009-06-28 21:50:27 +000080{
Paul Bakker19343182013-08-16 13:31:10 +020081 my $function_deps = $1;
Paul Bakker33b43f12013-08-20 11:48:36 +020082 my $function_decl = $2;
83
84 # Sanity checks of function
85 if ($function_decl !~ /^void /)
86 {
87 die "Test function does not have 'void' as return type\n";
88 }
Paul Bakker318d0fe2014-07-10 14:59:25 +020089 if ($function_decl !~ /^void (\w+)\(\s*(.*?)\s*\)\s*{(.*)}/ms)
Paul Bakker33b43f12013-08-20 11:48:36 +020090 {
91 die "Function declaration not in expected format\n";
92 }
93 my $function_name = $1;
94 my $function_params = $2;
Paul Bakker19343182013-08-16 13:31:10 +020095 my $function_pre_code;
96 my $function_post_code;
Paul Bakker19343182013-08-16 13:31:10 +020097 my $param_defs;
98 my $param_checks;
99 my @dispatch_params;
Paul Bakker33b43f12013-08-20 11:48:36 +0200100 my @var_def_arr = split(/,\s*/, $function_params);
Paul Bakker19343182013-08-16 13:31:10 +0200101 my $i = 1;
102 my $mapping_regex = "".$function_name;
103 my $mapping_count = 0;
Paul Bakker33b43f12013-08-20 11:48:36 +0200104
105 $function_decl =~ s/^void /void test_suite_/;
Paul Bakker367dae42009-06-28 21:50:27 +0000106
Paul Bakker318d0fe2014-07-10 14:59:25 +0200107 # Add exit label if not present
108 if ($function_decl !~ /^exit:$/m)
109 {
110 $function_decl =~ s/}\s*$/\nexit:\n return;\n}/;
111 }
112
Paul Bakker19343182013-08-16 13:31:10 +0200113 if ($function_deps =~ /^depends_on:/)
Paul Bakkerccff1672009-10-03 19:57:10 +0000114 {
Paul Bakker19343182013-08-16 13:31:10 +0200115 ( $function_deps ) = $function_deps =~ /^depends_on:(.*)$/;
Paul Bakkerccff1672009-10-03 19:57:10 +0000116 }
117
Paul Bakker19343182013-08-16 13:31:10 +0200118 foreach my $req (split(/:/, $function_deps))
Paul Bakker367dae42009-06-28 21:50:27 +0000119 {
Paul Bakker19343182013-08-16 13:31:10 +0200120 $function_pre_code .= "#ifdef $req\n";
121 $function_post_code .= "#endif /* $req */\n";
Paul Bakker367dae42009-06-28 21:50:27 +0000122 }
Paul Bakker367dae42009-06-28 21:50:27 +0000123
Paul Bakker19343182013-08-16 13:31:10 +0200124 foreach my $def (@var_def_arr)
125 {
126 # Handle the different parameter types
Paul Bakker33b43f12013-08-20 11:48:36 +0200127 if( substr($def, 0, 4) eq "int " )
Paul Bakker19343182013-08-16 13:31:10 +0200128 {
129 $param_defs .= " int param$i;\n";
130 $param_checks .= " if( verify_int( params[$i], &param$i ) != 0 ) return( 2 );\n";
131 push @dispatch_params, "param$i";
Paul Bakker367dae42009-06-28 21:50:27 +0000132
Paul Bakker19343182013-08-16 13:31:10 +0200133 $mapping_regex .= ":([\\d\\w |\\+\\-\\(\\)]+)";
134 $mapping_count++;
135 }
Paul Bakker33b43f12013-08-20 11:48:36 +0200136 elsif( substr($def, 0, 6) eq "char *" )
Paul Bakker19343182013-08-16 13:31:10 +0200137 {
138 $param_defs .= " char *param$i = params[$i];\n";
139 $param_checks .= " if( verify_string( &param$i ) != 0 ) return( 2 );\n";
140 push @dispatch_params, "param$i";
Paul Bakker19343182013-08-16 13:31:10 +0200141 $mapping_regex .= ":[^:]+";
Paul Bakker33b43f12013-08-20 11:48:36 +0200142 }
143 else
144 {
145 die "Parameter declaration not of supported type (int, char *)\n";
Paul Bakker19343182013-08-16 13:31:10 +0200146 }
147 $i++;
Paul Bakker367dae42009-06-28 21:50:27 +0000148
Paul Bakker19343182013-08-16 13:31:10 +0200149 }
150
151 # Find non-integer values we should map for this function
152 if( $mapping_count)
153 {
154 my @res = $test_data =~ /^$mapping_regex/msg;
155 foreach my $value (@res)
156 {
Manuel Pégourié-Gonnard18c443d2013-10-17 14:58:24 +0200157 next unless ($value !~ /^\d+$/);
158 if ( $mapping_values{$value} ) {
159 ${ $mapping_values{$value} }{$function_pre_code} = 1;
160 } else {
161 $mapping_values{$value} = { $function_pre_code => 1 };
162 }
Paul Bakker19343182013-08-16 13:31:10 +0200163 }
164 }
165
166 my $call_params = join ", ", @dispatch_params;
167 my $param_count = @var_def_arr + 1;
168 $dispatch_code .= << "END";
169if( strcmp( params[0], "$function_name" ) == 0 )
170{
171$function_pre_code
172$param_defs
173 if( cnt != $param_count )
174 {
175 fprintf( stderr, "\\nIncorrect argument count (%d != %d)\\n", cnt, $param_count );
176 return( 2 );
177 }
178
179$param_checks
Paul Bakker33b43f12013-08-20 11:48:36 +0200180 test_suite_$function_name( $call_params );
181 return ( 0 );
Paul Bakker19343182013-08-16 13:31:10 +0200182$function_post_code
183 return ( 3 );
184}
185else
186END
187
Paul Bakker33b43f12013-08-20 11:48:36 +0200188 my $function_code = $function_pre_code . $function_decl . "\n" . $function_post_code;
189 $test_main =~ s/FUNCTION_CODE/$function_code\nFUNCTION_CODE/;
Paul Bakker19343182013-08-16 13:31:10 +0200190}
191
192# Find specific case dependencies that we should be able to check
193# and make check code
194my $dep_check_code;
195
196my @res = $test_data =~ /^depends_on:([\w:]+)/msg;
197my %case_deps;
198foreach my $deps (@res)
199{
200 foreach my $dep (split(/:/, $deps))
201 {
202 $case_deps{$dep} = 1;
203 }
204}
205while( my ($key, $value) = each(%case_deps) )
206{
207 $dep_check_code .= << "END";
208 if( strcmp( str, "$key" ) == 0 )
209 {
210#if defined($key)
211 return( 0 );
212#else
213 return( 1 );
214#endif
215 }
Paul Bakker367dae42009-06-28 21:50:27 +0000216END
217}
Paul Bakker19343182013-08-16 13:31:10 +0200218
219# Make mapping code
220while( my ($key, $value) = each(%mapping_values) )
221{
Manuel Pégourié-Gonnard18c443d2013-10-17 14:58:24 +0200222 my $key_mapping_code = << "END";
Paul Bakker19343182013-08-16 13:31:10 +0200223 if( strcmp( str, "$key" ) == 0 )
224 {
225 *value = ( $key );
226 return( 0 );
227 }
228END
Manuel Pégourié-Gonnard18c443d2013-10-17 14:58:24 +0200229
230 # handle depenencies, unless used at least one without depends
231 if ($value->{""}) {
232 $mapping_code .= $key_mapping_code;
233 next;
234 }
235 for my $ifdef ( keys %$value ) {
236 (my $endif = $ifdef) =~ s!ifdef!endif //!g;
237 $mapping_code .= $ifdef . $key_mapping_code . $endif;
238 }
Paul Bakker19343182013-08-16 13:31:10 +0200239}
240
241$dispatch_code =~ s/^(.+)/ $1/mg;
242
243$test_main =~ s/TEST_FILENAME/$test_case_data/;
244$test_main =~ s/FUNCTION_CODE//;
245$test_main =~ s/DEP_CHECK_CODE/$dep_check_code/;
246$test_main =~ s/DISPATCH_FUNCTION/$dispatch_code/;
247$test_main =~ s/MAPPING_CODE/$mapping_code/;
Paul Bakker367dae42009-06-28 21:50:27 +0000248
249print TEST_FILE << "END";
Paul Bakker19343182013-08-16 13:31:10 +0200250$test_main
Paul Bakker367dae42009-06-28 21:50:27 +0000251END
252
Paul Bakker367dae42009-06-28 21:50:27 +0000253close(TEST_FILE);