blob: 2c203997d9498ff619735b8aa1526f007ac2a176 [file] [log] [blame]
Markus Pfeiffera26a0052014-04-22 20:16:15 +00001#!/usr/bin/env perl
SimonB3ddf3552016-02-10 23:50:28 +00002
3# generate_code.pl
Paul Bakker367dae42009-06-28 21:50:27 +00004#
Simon Butcher64d60da2016-03-01 18:35:02 +00005# Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02006# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7#
8# This file is provided under the Apache License 2.0, or the
9# GNU General Public License v2.0 or later.
10#
11# **********
12# Apache License 2.0:
Bence Szépkúti09b4f192020-05-26 01:54:15 +020013#
14# Licensed under the Apache License, Version 2.0 (the "License"); you may
15# not use this file except in compliance with the License.
16# You may obtain a copy of the License at
17#
18# http://www.apache.org/licenses/LICENSE-2.0
19#
20# Unless required by applicable law or agreed to in writing, software
21# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
22# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23# See the License for the specific language governing permissions and
24# limitations under the License.
25#
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020026# **********
27#
28# **********
29# GNU General Public License v2.0 or later:
30#
31# This program is free software; you can redistribute it and/or modify
32# it under the terms of the GNU General Public License as published by
33# the Free Software Foundation; either version 2 of the License, or
34# (at your option) any later version.
35#
36# This program is distributed in the hope that it will be useful,
37# but WITHOUT ANY WARRANTY; without even the implied warranty of
38# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39# GNU General Public License for more details.
40#
41# You should have received a copy of the GNU General Public License along
42# with this program; if not, write to the Free Software Foundation, Inc.,
43# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
44#
45# **********
46#
Bence Szépkúti09b4f192020-05-26 01:54:15 +020047# This file is part of Mbed TLS (https://tls.mbed.org)
Simon Butcher64d60da2016-03-01 18:35:02 +000048#
SimonB152ea182016-02-15 23:27:28 +000049# Purpose
50#
SimonB3ddf3552016-02-10 23:50:28 +000051# Generates the test suite code given inputs of the test suite directory that
52# contain the test suites, and the test suite file names for the test code and
53# test data.
54#
55# Usage: generate_code.pl <suite dir> <code file> <data file> [main code file]
SimonB152ea182016-02-15 23:27:28 +000056#
57# Structure of files
58#
59# - main code file - 'main_test.function'
60# Template file that contains the main() function for the test suite,
61# test dispatch code as well as support functions. It contains the
62# following symbols which are substituted by this script during
63# processing:
SimonB15942102016-04-25 21:34:49 +010064# TESTCASE_FILENAME
65# TESTCODE_FILENAME
SimonB152ea182016-02-15 23:27:28 +000066# SUITE_PRE_DEP
67# MAPPING_CODE
68# FUNCTION CODE
69# SUITE_POST_DEP
70# DEP_CHECK_CODE
71# DISPATCH_FUNCTION
SimonB15942102016-04-25 21:34:49 +010072# !LINE_NO!
SimonB152ea182016-02-15 23:27:28 +000073#
74# - common helper code file - 'helpers.function'
75# Common helper functions
76#
77# - test suite code file - file name in the form 'test_suite_xxx.function'
78# Code file that contains the actual test cases. The file contains a
79# series of code sequences delimited by the following:
80# BEGIN_HEADER / END_HEADER - list of headers files
81# BEGIN_SUITE_HELPERS / END_SUITE_HELPERS - helper functions common to
82# the test suite
83# BEGIN_CASE / END_CASE - the test cases in the test suite. Each test
84# case contains at least one function that is used to create the
85# dispatch code.
86#
87# - test data file - file name in the form 'test_suite_xxxx.data'
88# The test case parameters to to be used in execution of the test. The
SimonB15942102016-04-25 21:34:49 +010089# file name is used to replace the symbol 'TESTCASE_FILENAME' in the main
90# code file above.
SimonB152ea182016-02-15 23:27:28 +000091#
Gilles Peskineb04e2c32017-09-29 15:45:12 +020092# A test data file consists of a sequence of paragraphs separated by
93# a single empty line. Line breaks may be in Unix (LF) or Windows (CRLF)
94# format. Lines starting with the character '#' are ignored
95# (the parser behaves as if they were not present).
96#
97# Each paragraph describes one test case and must consist of: (1) one
98# line which is the test case name; (2) an optional line starting with
99# the 11-character prefix "depends_on:"; (3) a line containing the test
100# function to execute and its parameters.
101#
102# A depends_on: line consists of a list of compile-time options
103# separated by the character ':', with no whitespace. The test case
104# is executed only if this compilation option is enabled in config.h.
105#
106# The last line of each paragraph contains a test function name and
107# a list of parameters separated by the character ':'. Running the
108# test case calls this function with the specified parameters. Each
109# parameter may either be an integer written in decimal or hexadecimal,
110# or a string surrounded by double quotes which may not contain the
111# ':' character.
112#
Paul Bakker367dae42009-06-28 21:50:27 +0000113
114use strict;
115
116my $suite_dir = shift or die "Missing suite directory";
117my $suite_name = shift or die "Missing suite name";
Paul Bakker46c17942011-07-13 14:54:54 +0000118my $data_name = shift or die "Missing data name";
Rich Evansf4253c72015-01-14 19:23:00 +0000119my $test_main_file = do { my $arg = shift; defined($arg) ? $arg : $suite_dir."/main_test.function" };
Paul Bakker46c17942011-07-13 14:54:54 +0000120my $test_file = $data_name.".c";
SimonB152ea182016-02-15 23:27:28 +0000121my $test_common_helper_file = $suite_dir."/helpers.function";
Paul Bakker367dae42009-06-28 21:50:27 +0000122my $test_case_file = $suite_dir."/".$suite_name.".function";
Paul Bakker19343182013-08-16 13:31:10 +0200123my $test_case_data = $suite_dir."/".$data_name.".data";
Paul Bakker367dae42009-06-28 21:50:27 +0000124
125my $line_separator = $/;
126undef $/;
127
SimonB15942102016-04-25 21:34:49 +0100128
129#
130# Open and read in the input files
131#
132
SimonB152ea182016-02-15 23:27:28 +0000133open(TEST_HELPERS, "$test_common_helper_file") or die "Opening test helpers
134'$test_common_helper_file': $!";
135my $test_common_helpers = <TEST_HELPERS>;
Paul Bakker367dae42009-06-28 21:50:27 +0000136close(TEST_HELPERS);
137
Paul Bakker19343182013-08-16 13:31:10 +0200138open(TEST_MAIN, "$test_main_file") or die "Opening test main '$test_main_file': $!";
SimonB15942102016-04-25 21:34:49 +0100139my @test_main_lines = split/^/, <TEST_MAIN>;
140my $test_main;
SimonB43dba3d2016-05-02 21:31:51 +0100141my $index = 2;
SimonB15942102016-04-25 21:34:49 +0100142for my $line (@test_main_lines) {
143 $line =~ s/!LINE_NO!/$index/;
144 $test_main = $test_main.$line;
145 $index++;
146}
Paul Bakker19343182013-08-16 13:31:10 +0200147close(TEST_MAIN);
148
Paul Bakker367dae42009-06-28 21:50:27 +0000149open(TEST_CASES, "$test_case_file") or die "Opening test cases '$test_case_file': $!";
SimonB15942102016-04-25 21:34:49 +0100150my @test_cases_lines = split/^/, <TEST_CASES>;
151my $test_cases;
SimonB43dba3d2016-05-02 21:31:51 +0100152my $index = 2;
SimonB15942102016-04-25 21:34:49 +0100153for my $line (@test_cases_lines) {
SimonB37f26202016-05-02 21:58:19 +0100154 if ($line =~ /^\/\* BEGIN_SUITE_HELPERS .*\*\//)
155 {
156 $line = $line."#line $index \"$test_case_file\"\n";
157 }
158
SimonB15942102016-04-25 21:34:49 +0100159 if ($line =~ /^\/\* BEGIN_CASE .*\*\//)
160 {
161 $line = $line."#line $index \"$test_case_file\"\n";
162 }
163
SimonBc1d2eb32016-05-02 15:52:52 +0100164 $line =~ s/!LINE_NO!/$index/;
165
SimonB15942102016-04-25 21:34:49 +0100166 $test_cases = $test_cases.$line;
167 $index++;
168}
169
Paul Bakker367dae42009-06-28 21:50:27 +0000170close(TEST_CASES);
Paul Bakker19343182013-08-16 13:31:10 +0200171
172open(TEST_DATA, "$test_case_data") or die "Opening test data '$test_case_data': $!";
173my $test_data = <TEST_DATA>;
174close(TEST_DATA);
175
SimonB15942102016-04-25 21:34:49 +0100176
177#
178# Find the headers, dependencies, and suites in the test cases file
179#
180
Paul Bakker33b43f12013-08-20 11:48:36 +0200181my ( $suite_header ) = $test_cases =~ /\/\* BEGIN_HEADER \*\/\n(.*?)\n\/\* END_HEADER \*\//s;
182my ( $suite_defines ) = $test_cases =~ /\/\* BEGIN_DEPENDENCIES\n \* (.*?)\n \* END_DEPENDENCIES/s;
SimonB152ea182016-02-15 23:27:28 +0000183my ( $suite_helpers ) = $test_cases =~ /\/\* BEGIN_SUITE_HELPERS \*\/\n(.*?)\n\/\* END_SUITE_HELPERS \*\//s;
Paul Bakker5690efc2011-05-26 13:16:06 +0000184
185my $requirements;
186if ($suite_defines =~ /^depends_on:/)
187{
188 ( $requirements ) = $suite_defines =~ /^depends_on:(.*)$/;
189}
Paul Bakker19343182013-08-16 13:31:10 +0200190
Paul Bakker5690efc2011-05-26 13:16:06 +0000191my @var_req_arr = split(/:/, $requirements);
192my $suite_pre_code;
193my $suite_post_code;
Paul Bakker19343182013-08-16 13:31:10 +0200194my $dispatch_code;
195my $mapping_code;
196my %mapping_values;
Paul Bakker5690efc2011-05-26 13:16:06 +0000197
198while (@var_req_arr)
199{
200 my $req = shift @var_req_arr;
Manuel Pégourié-Gonnarde46c6c32015-03-23 13:59:10 +0100201 $req =~ s/(!?)(.*)/$1defined($2)/;
Paul Bakker5690efc2011-05-26 13:16:06 +0000202
Manuel Pégourié-Gonnarde46c6c32015-03-23 13:59:10 +0100203 $suite_pre_code .= "#if $req\n";
Paul Bakker5690efc2011-05-26 13:16:06 +0000204 $suite_post_code .= "#endif /* $req */\n";
205}
Paul Bakker367dae42009-06-28 21:50:27 +0000206
207$/ = $line_separator;
208
209open(TEST_FILE, ">$test_file") or die "Opening destination file '$test_file': $!";
210print TEST_FILE << "END";
SimonB152ea182016-02-15 23:27:28 +0000211/*
212 * *** THIS FILE HAS BEEN MACHINE GENERATED ***
213 *
214 * This file has been machine generated using the script: $0
215 *
216 * Test file : $test_file
217 *
218 * The following files were used to create this file.
219 *
220 * Main code file : $test_main_file
221 * Helper file : $test_common_helper_file
222 * Test suite file : $test_case_file
Simon Butcher64d60da2016-03-01 18:35:02 +0000223 * Test suite data : $test_case_data
SimonB152ea182016-02-15 23:27:28 +0000224 *
225 *
226 * This file is part of mbed TLS (https://tls.mbed.org)
227 */
228
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200229#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +0000230#include <mbedtls/config.h>
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +0200231#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +0200233#endif
Paul Bakker5690efc2011-05-26 13:16:06 +0000234
SimonB152ea182016-02-15 23:27:28 +0000235
236/*----------------------------------------------------------------------------*/
SimonB0269dad2016-02-17 23:34:30 +0000237/* Common helper code */
SimonB152ea182016-02-15 23:27:28 +0000238
239$test_common_helpers
240
241
242/*----------------------------------------------------------------------------*/
243/* Test Suite Code */
Rich Evans00ab4702015-02-06 13:43:58 +0000244
Paul Bakkerde56ca12013-09-15 17:05:21 +0200245$suite_pre_code
Paul Bakker367dae42009-06-28 21:50:27 +0000246$suite_header
SimonB152ea182016-02-15 23:27:28 +0000247$suite_helpers
Paul Bakkerde56ca12013-09-15 17:05:21 +0200248$suite_post_code
Paul Bakker367dae42009-06-28 21:50:27 +0000249
Paul Bakker367dae42009-06-28 21:50:27 +0000250END
251
Paul Bakkerb34fef22013-08-20 12:06:33 +0200252$test_main =~ s/SUITE_PRE_DEP/$suite_pre_code/;
253$test_main =~ s/SUITE_POST_DEP/$suite_post_code/;
254
Paul Bakker33b43f12013-08-20 11:48:36 +0200255while($test_cases =~ /\/\* BEGIN_CASE *([\w:]*) \*\/\n(.*?)\n\/\* END_CASE \*\//msg)
Paul Bakker367dae42009-06-28 21:50:27 +0000256{
Paul Bakker19343182013-08-16 13:31:10 +0200257 my $function_deps = $1;
Paul Bakker33b43f12013-08-20 11:48:36 +0200258 my $function_decl = $2;
259
260 # Sanity checks of function
SimonB15942102016-04-25 21:34:49 +0100261 if ($function_decl !~ /^#line\s*.*\nvoid /)
Paul Bakker33b43f12013-08-20 11:48:36 +0200262 {
SimonB15942102016-04-25 21:34:49 +0100263 die "Test function does not have 'void' as return type.\n" .
264 "Function declaration:\n" .
265 $function_decl;
Paul Bakker33b43f12013-08-20 11:48:36 +0200266 }
SimonB15942102016-04-25 21:34:49 +0100267 if ($function_decl !~ /^(#line\s*.*)\nvoid (\w+)\(\s*(.*?)\s*\)\s*{(.*)}/ms)
Paul Bakker33b43f12013-08-20 11:48:36 +0200268 {
269 die "Function declaration not in expected format\n";
270 }
SimonB15942102016-04-25 21:34:49 +0100271 my $line_directive = $1;
272 my $function_name = $2;
273 my $function_params = $3;
Paul Bakker19343182013-08-16 13:31:10 +0200274 my $function_pre_code;
275 my $function_post_code;
Paul Bakker19343182013-08-16 13:31:10 +0200276 my $param_defs;
277 my $param_checks;
278 my @dispatch_params;
Paul Bakker33b43f12013-08-20 11:48:36 +0200279 my @var_def_arr = split(/,\s*/, $function_params);
Paul Bakker19343182013-08-16 13:31:10 +0200280 my $i = 1;
281 my $mapping_regex = "".$function_name;
282 my $mapping_count = 0;
Paul Bakker367dae42009-06-28 21:50:27 +0000283
SimonB15942102016-04-25 21:34:49 +0100284 $function_decl =~ s/(^#line\s*.*)\nvoid /$1\nvoid test_suite_/;
Paul Bakker33b43f12013-08-20 11:48:36 +0200285
Paul Bakker318d0fe2014-07-10 14:59:25 +0200286 # Add exit label if not present
287 if ($function_decl !~ /^exit:$/m)
288 {
289 $function_decl =~ s/}\s*$/\nexit:\n return;\n}/;
290 }
291
Paul Bakker19343182013-08-16 13:31:10 +0200292 if ($function_deps =~ /^depends_on:/)
Paul Bakkerccff1672009-10-03 19:57:10 +0000293 {
Paul Bakker19343182013-08-16 13:31:10 +0200294 ( $function_deps ) = $function_deps =~ /^depends_on:(.*)$/;
Paul Bakkerccff1672009-10-03 19:57:10 +0000295 }
296
Paul Bakker19343182013-08-16 13:31:10 +0200297 foreach my $req (split(/:/, $function_deps))
Paul Bakker367dae42009-06-28 21:50:27 +0000298 {
Paul Bakker19343182013-08-16 13:31:10 +0200299 $function_pre_code .= "#ifdef $req\n";
300 $function_post_code .= "#endif /* $req */\n";
Paul Bakker367dae42009-06-28 21:50:27 +0000301 }
Paul Bakker367dae42009-06-28 21:50:27 +0000302
Paul Bakker19343182013-08-16 13:31:10 +0200303 foreach my $def (@var_def_arr)
304 {
305 # Handle the different parameter types
Paul Bakker33b43f12013-08-20 11:48:36 +0200306 if( substr($def, 0, 4) eq "int " )
Paul Bakker19343182013-08-16 13:31:10 +0200307 {
308 $param_defs .= " int param$i;\n";
SimonB8ca7bc42016-04-17 23:24:50 +0100309 $param_checks .= " if( verify_int( params[$i], &param$i ) != 0 ) return( DISPATCH_INVALID_TEST_DATA );\n";
Paul Bakker19343182013-08-16 13:31:10 +0200310 push @dispatch_params, "param$i";
Paul Bakker367dae42009-06-28 21:50:27 +0000311
Paul Bakker19343182013-08-16 13:31:10 +0200312 $mapping_regex .= ":([\\d\\w |\\+\\-\\(\\)]+)";
313 $mapping_count++;
314 }
Paul Bakker33b43f12013-08-20 11:48:36 +0200315 elsif( substr($def, 0, 6) eq "char *" )
Paul Bakker19343182013-08-16 13:31:10 +0200316 {
317 $param_defs .= " char *param$i = params[$i];\n";
SimonB8ca7bc42016-04-17 23:24:50 +0100318 $param_checks .= " if( verify_string( &param$i ) != 0 ) return( DISPATCH_INVALID_TEST_DATA );\n";
Paul Bakker19343182013-08-16 13:31:10 +0200319 push @dispatch_params, "param$i";
Andres AG9060d4d2017-02-02 14:36:49 +0000320 $mapping_regex .= ":(?:\\\\.|[^:\n])+";
Paul Bakker19343182013-08-16 13:31:10 +0200321 }
Paul Bakker33b43f12013-08-20 11:48:36 +0200322 else
323 {
324 die "Parameter declaration not of supported type (int, char *)\n";
325 }
Paul Bakker19343182013-08-16 13:31:10 +0200326 $i++;
Paul Bakker367dae42009-06-28 21:50:27 +0000327
Paul Bakker19343182013-08-16 13:31:10 +0200328 }
329
330 # Find non-integer values we should map for this function
331 if( $mapping_count)
332 {
333 my @res = $test_data =~ /^$mapping_regex/msg;
334 foreach my $value (@res)
335 {
Manuel Pégourié-Gonnard18c443d2013-10-17 14:58:24 +0200336 next unless ($value !~ /^\d+$/);
337 if ( $mapping_values{$value} ) {
338 ${ $mapping_values{$value} }{$function_pre_code} = 1;
339 } else {
340 $mapping_values{$value} = { $function_pre_code => 1 };
341 }
Paul Bakker19343182013-08-16 13:31:10 +0200342 }
343 }
344
345 my $call_params = join ", ", @dispatch_params;
346 my $param_count = @var_def_arr + 1;
347 $dispatch_code .= << "END";
348if( strcmp( params[0], "$function_name" ) == 0 )
349{
350$function_pre_code
351$param_defs
352 if( cnt != $param_count )
353 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 mbedtls_fprintf( stderr, "\\nIncorrect argument count (%d != %d)\\n", cnt, $param_count );
SimonB8ca7bc42016-04-17 23:24:50 +0100355 return( DISPATCH_INVALID_TEST_DATA );
Paul Bakker19343182013-08-16 13:31:10 +0200356 }
357
358$param_checks
Paul Bakker33b43f12013-08-20 11:48:36 +0200359 test_suite_$function_name( $call_params );
SimonB8ca7bc42016-04-17 23:24:50 +0100360 return ( DISPATCH_TEST_SUCCESS );
Paul Bakker19343182013-08-16 13:31:10 +0200361$function_post_code
SimonB8ca7bc42016-04-17 23:24:50 +0100362 return ( DISPATCH_UNSUPPORTED_SUITE );
Paul Bakker19343182013-08-16 13:31:10 +0200363}
364else
365END
366
SimonB15942102016-04-25 21:34:49 +0100367 my $function_code = $function_pre_code . $function_decl . "\n" .
368 $function_post_code;
Paul Bakker33b43f12013-08-20 11:48:36 +0200369 $test_main =~ s/FUNCTION_CODE/$function_code\nFUNCTION_CODE/;
Paul Bakker19343182013-08-16 13:31:10 +0200370}
371
372# Find specific case dependencies that we should be able to check
373# and make check code
374my $dep_check_code;
375
Hanno Beckerf058f342017-07-23 10:24:22 +0100376my @res = $test_data =~ /^depends_on:([!:\w]+)/msg;
Paul Bakker19343182013-08-16 13:31:10 +0200377my %case_deps;
378foreach my $deps (@res)
379{
380 foreach my $dep (split(/:/, $deps))
381 {
382 $case_deps{$dep} = 1;
383 }
384}
385while( my ($key, $value) = each(%case_deps) )
386{
Hanno Beckerf058f342017-07-23 10:24:22 +0100387 if( substr($key, 0, 1) eq "!" )
388 {
389 my $key = substr($key, 1);
390 $dep_check_code .= << "END";
391 if( strcmp( str, "!$key" ) == 0 )
392 {
393#if !defined($key)
394 return( DEPENDENCY_SUPPORTED );
395#else
396 return( DEPENDENCY_NOT_SUPPORTED );
397#endif
398 }
399END
400 }
401 else
402 {
403 $dep_check_code .= << "END";
Paul Bakker19343182013-08-16 13:31:10 +0200404 if( strcmp( str, "$key" ) == 0 )
405 {
406#if defined($key)
SimonB8ca7bc42016-04-17 23:24:50 +0100407 return( DEPENDENCY_SUPPORTED );
Paul Bakker19343182013-08-16 13:31:10 +0200408#else
SimonB8ca7bc42016-04-17 23:24:50 +0100409 return( DEPENDENCY_NOT_SUPPORTED );
Paul Bakker19343182013-08-16 13:31:10 +0200410#endif
411 }
Paul Bakker367dae42009-06-28 21:50:27 +0000412END
Hanno Beckerf058f342017-07-23 10:24:22 +0100413 }
Paul Bakker367dae42009-06-28 21:50:27 +0000414}
415
Paul Bakker19343182013-08-16 13:31:10 +0200416# Make mapping code
417while( my ($key, $value) = each(%mapping_values) )
418{
Manuel Pégourié-Gonnard18c443d2013-10-17 14:58:24 +0200419 my $key_mapping_code = << "END";
Paul Bakker19343182013-08-16 13:31:10 +0200420 if( strcmp( str, "$key" ) == 0 )
421 {
422 *value = ( $key );
SimonB8ca7bc42016-04-17 23:24:50 +0100423 return( KEY_VALUE_MAPPING_FOUND );
Paul Bakker19343182013-08-16 13:31:10 +0200424 }
425END
Manuel Pégourié-Gonnard18c443d2013-10-17 14:58:24 +0200426
427 # handle depenencies, unless used at least one without depends
428 if ($value->{""}) {
429 $mapping_code .= $key_mapping_code;
430 next;
431 }
432 for my $ifdef ( keys %$value ) {
433 (my $endif = $ifdef) =~ s!ifdef!endif //!g;
434 $mapping_code .= $ifdef . $key_mapping_code . $endif;
435 }
Paul Bakker19343182013-08-16 13:31:10 +0200436}
437
438$dispatch_code =~ s/^(.+)/ $1/mg;
439
SimonB15942102016-04-25 21:34:49 +0100440$test_main =~ s/TESTCASE_FILENAME/$test_case_data/g;
441$test_main =~ s/TESTCODE_FILENAME/$test_case_file/g;
Paul Bakker19343182013-08-16 13:31:10 +0200442$test_main =~ s/FUNCTION_CODE//;
443$test_main =~ s/DEP_CHECK_CODE/$dep_check_code/;
444$test_main =~ s/DISPATCH_FUNCTION/$dispatch_code/;
445$test_main =~ s/MAPPING_CODE/$mapping_code/;
446
Paul Bakker367dae42009-06-28 21:50:27 +0000447print TEST_FILE << "END";
Paul Bakker19343182013-08-16 13:31:10 +0200448$test_main
Paul Bakker367dae42009-06-28 21:50:27 +0000449END
450
Paul Bakker367dae42009-06-28 21:50:27 +0000451close(TEST_FILE);