1 #! /usr/bin/env perl 2 3 # Generate query_config.c 4 # 5 # The file query_config.c contains a C function that can be used to check if 6 # a configuration macro is defined and to retrieve its expansion in string 7 # form (if any). This facilitates querying the compile time configuration of 8 # the library, for example, for testing. 9 # 10 # The query_config.c is generated from the current configuration at 11 # include/mbedtls/mbedtls_config.h. The idea is that the mbedtls_config.h contains ALL the 12 # compile time configurations available in Mbed TLS (commented or uncommented). 13 # This script extracts the configuration macros from the mbedtls_config.h and this 14 # information is used to automatically generate the body of the query_config() 15 # function by using the template in scripts/data_files/query_config.fmt. 16 # 17 # Usage: scripts/generate_query_config.pl without arguments, or 18 # generate_query_config.pl config_file template_file output_file 19 # 20 # Copyright The Mbed TLS Contributors 21 # SPDX-License-Identifier: Apache-2.0 22 # 23 # Licensed under the Apache License, Version 2.0 (the "License"); you may 24 # not use this file except in compliance with the License. 25 # You may obtain a copy of the License at 26 # 27 # http://www.apache.org/licenses/LICENSE-2.0 28 # 29 # Unless required by applicable law or agreed to in writing, software 30 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 31 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 32 # See the License for the specific language governing permissions and 33 # limitations under the License. 34 35 use strict; 36 37 my ($config_file, $query_config_format_file, $query_config_file); 38 39 if( @ARGV ) { 40 die "Invalid number of arguments - usage: $0 [CONFIG_FILE TEMPLATE_FILE OUTPUT_FILE]" if scalar @ARGV != 3; 41 ($config_file, $query_config_format_file, $query_config_file) = @ARGV; 42 43 -f $config_file or die "No such file: $config_file"; 44 -f $query_config_format_file or die "No such file: $query_config_format_file"; 45 } else { 46 $config_file = "./include/mbedtls/mbedtls_config.h"; 47 $query_config_format_file = "./scripts/data_files/query_config.fmt"; 48 $query_config_file = "./programs/test/query_config.c"; 49 50 unless( -f $config_file && -f $query_config_format_file ) { 51 chdir '..' or die; 52 -f $config_file && -f $query_config_format_file 53 or die "No arguments supplied, must be run from project root or a first-level subdirectory\n"; 54 } 55 } 56 57 # Excluded macros from the generated query_config.c. For example, macros that 58 # have commas or function-like macros cannot be transformed into strings easily 59 # using the preprocessor, so they should be excluded or the preprocessor will 60 # throw errors. 61 my @excluded = qw( 62 MBEDTLS_SSL_CIPHERSUITES 63 ); 64 my $excluded_re = join '|', @excluded; 65 66 open(CONFIG_FILE, "$config_file") or die "Opening config file '$config_file': $!"; 67 68 # This variable will contain the string to replace in the CHECK_CONFIG of the 69 # format file 70 my $config_check = ""; 71 my $list_config = ""; 72 73 while (my $line = <CONFIG_FILE>) { 74 if ($line =~ /^(\/\/)?\s*#\s*define\s+(MBEDTLS_\w+).*/) { 75 my $name = $2; 76 77 # Skip over the macro if it is in the ecluded list 78 next if $name =~ /$excluded_re/; 79 80 $config_check .= "#if defined($name)\n"; 81 $config_check .= " if( strcmp( \"$name\", config ) == 0 )\n"; 82 $config_check .= " {\n"; 83 $config_check .= " MACRO_EXPANSION_TO_STR( $name );\n"; 84 $config_check .= " return( 0 );\n"; 85 $config_check .= " }\n"; 86 $config_check .= "#endif /* $name */\n"; 87 $config_check .= "\n"; 88 89 $list_config .= "#if defined($name)\n"; 90 $list_config .= " OUTPUT_MACRO_NAME_VALUE($name);\n"; 91 $list_config .= "#endif /* $name */\n"; 92 $list_config .= "\n"; 93 } 94 } 95 96 # Read the full format file into a string 97 local $/; 98 open(FORMAT_FILE, "$query_config_format_file") or die "Opening query config format file '$query_config_format_file': $!"; 99 my $query_config_format = <FORMAT_FILE>; 100 close(FORMAT_FILE); 101 102 # Replace the body of the query_config() function with the code we just wrote 103 $query_config_format =~ s/CHECK_CONFIG/$config_check/g; 104 $query_config_format =~ s/LIST_CONFIG/$list_config/g; 105 106 # Rewrite the query_config.c file 107 open(QUERY_CONFIG_FILE, ">$query_config_file") or die "Opening destination file '$query_config_file': $!"; 108 print QUERY_CONFIG_FILE $query_config_format; 109 close(QUERY_CONFIG_FILE); 110