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 35use strict; 36 37my ($config_file, $query_config_format_file, $query_config_file); 38 39if( @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. 61my @excluded = qw( 62MBEDTLS_SSL_CIPHERSUITES 63); 64my $excluded_re = join '|', @excluded; 65 66open(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 70my $config_check = ""; 71 72while (my $line = <CONFIG_FILE>) { 73 if ($line =~ /^(\/\/)?\s*#\s*define\s+(MBEDTLS_\w+).*/) { 74 my $name = $2; 75 76 # Skip over the macro if it is in the ecluded list 77 next if $name =~ /$excluded_re/; 78 79 $config_check .= "#if defined($name)\n"; 80 $config_check .= " if( strcmp( \"$name\", config ) == 0 )\n"; 81 $config_check .= " {\n"; 82 $config_check .= " MACRO_EXPANSION_TO_STR( $name );\n"; 83 $config_check .= " return( 0 );\n"; 84 $config_check .= " }\n"; 85 $config_check .= "#endif /* $name */\n"; 86 $config_check .= "\n"; 87 } 88} 89 90# Read the full format file into a string 91local $/; 92open(FORMAT_FILE, "$query_config_format_file") or die "Opening query config format file '$query_config_format_file': $!"; 93my $query_config_format = <FORMAT_FILE>; 94close(FORMAT_FILE); 95 96# Replace the body of the query_config() function with the code we just wrote 97$query_config_format =~ s/CHECK_CONFIG/$config_check/g; 98 99# Rewrite the query_config.c file 100open(QUERY_CONFIG_FILE, ">$query_config_file") or die "Opening destination file '$query_config_file': $!"; 101print QUERY_CONFIG_FILE $query_config_format; 102close(QUERY_CONFIG_FILE); 103