1#!/usr/bin/perl 2# 3# This file is part of mbed TLS (https://tls.mbed.org) 4# 5# Copyright (c) 2014-2016, ARM Limited, All Rights Reserved 6# 7# Purpose 8# 9# Comments and uncomments #define lines in the given header file and optionally 10# sets their value or can get the value. This is to provide scripting control of 11# what preprocessor symbols, and therefore what build time configuration flags 12# are set in the 'config.h' file. 13# 14# Usage: config.pl [-f <file> | --file <file>] [-o | --force] 15# [set <symbol> <value> | unset <symbol> | get <symbol> | 16# full | realfull] 17# 18# Full usage description provided below. 19# 20# Things that shouldn't be enabled with "full". 21# 22# MBEDTLS_TEST_NULL_ENTROPY 23# MBEDTLS_DEPRECATED_REMOVED 24# MBEDTLS_HAVE_SSE2 25# MBEDTLS_PLATFORM_NO_STD_FUNCTIONS 26# MBEDTLS_ECP_DP_M221_ENABLED 27# MBEDTLS_ECP_DP_M383_ENABLED 28# MBEDTLS_ECP_DP_M511_ENABLED 29# MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES 30# MBEDTLS_NO_PLATFORM_ENTROPY 31# MBEDTLS_REMOVE_ARC4_CIPHERSUITES 32# MBEDTLS_SSL_HW_RECORD_ACCEL 33# MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 34# MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION 35# - this could be enabled if the respective tests were adapted 36# MBEDTLS_ZLIB_SUPPORT 37# MBEDTLS_PKCS11_C 38# and any symbol beginning _ALT 39# 40 41use warnings; 42use strict; 43 44my $config_file = "include/mbedtls/config.h"; 45my $usage = <<EOU; 46$0 [-f <file> | --file <file>] [-o | --force] 47 [set <symbol> <value> | unset <symbol> | get <symbol> | 48 full | realfull] 49 50Commands 51 set <symbol> [<value>] - Uncomments or adds a #define for the <symbol> to 52 the configuration file, and optionally making it 53 of <value>. 54 If the symbol isn't present in the file an error 55 is returned. 56 unset <symbol> - Comments out the #define for the given symbol if 57 present in the configuration file. 58 get <symbol> - Finds the #define for the given symbol, returning 59 an exitcode of 0 if the symbol is found, and -1 if 60 not. The value of the symbol is output if one is 61 specified in the configuration file. 62 full - Uncomments all #define's in the configuration file 63 excluding some reserved symbols, until the 64 'Module configuration options' section 65 realfull - Uncomments all #define's with no exclusions 66 67Options 68 -f | --file <filename> - The file or file path for the configuration file 69 to edit. When omitted, the following default is 70 used: 71 $config_file 72 -o | --force - If the symbol isn't present in the configuration 73 file when setting it's value, a #define is 74 appended to the end of the file. 75 76EOU 77 78my @excluded = qw( 79MBEDTLS_TEST_NULL_ENTROPY 80MBEDTLS_DEPRECATED_REMOVED 81MBEDTLS_HAVE_SSE2 82MBEDTLS_PLATFORM_NO_STD_FUNCTIONS 83MBEDTLS_ECP_DP_M221_ENABLED 84MBEDTLS_ECP_DP_M383_ENABLED 85MBEDTLS_ECP_DP_M511_ENABLED 86MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES 87MBEDTLS_NO_PLATFORM_ENTROPY 88MBEDTLS_REMOVE_ARC4_CIPHERSUITES 89MBEDTLS_SSL_HW_RECORD_ACCEL 90MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 91MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION 92MBEDTLS_ZLIB_SUPPORT 93MBEDTLS_PKCS11_C 94_ALT\s*$ 95); 96 97# Things that should be enabled in "full" even if they match @excluded 98my @non_excluded = qw( 99PLATFORM_[A-Z0-9]+_ALT 100); 101 102# Process the command line arguments 103 104my $force_option = 0; 105 106my ($arg, $name, $value, $action); 107 108while ($arg = shift) { 109 110 # Check if the argument is an option 111 if ($arg eq "-f" || $arg eq "--file") { 112 $config_file = shift; 113 114 -f $config_file or die "No such file: $config_file\n"; 115 116 } 117 elsif ($arg eq "-o" || $arg eq "--force") { 118 $force_option = 1; 119 120 } 121 else 122 { 123 # ...else assume it's a command 124 $action = $arg; 125 126 if ($action eq "full" || $action eq "realfull") { 127 # No additional parameters 128 die $usage if @ARGV; 129 130 } 131 elsif ($action eq "unset" || $action eq "get") { 132 die $usage unless @ARGV; 133 $name = shift; 134 135 } 136 elsif ($action eq "set") { 137 die $usage unless @ARGV; 138 $name = shift; 139 $value = shift if @ARGV; 140 141 } 142 else { 143 die "Command '$action' not recognised.\n\n".$usage; 144 } 145 } 146} 147 148# If no command was specified, exit... 149if ( not defined($action) ){ die $usage; } 150 151# Check the config file is present 152if (! -f $config_file) { 153 154 chdir '..' or die; 155 156 # Confirm this is the project root directory and try again 157 if ( !(-d 'scripts' && -d 'include' && -d 'library' && -f $config_file) ) { 158 die "If no file specified, must be run from the project root or scripts directory.\n"; 159 } 160} 161 162 163# Now read the file and process the contents 164 165open my $config_read, '<', $config_file or die "read $config_file: $!\n"; 166my @config_lines = <$config_read>; 167close $config_read; 168 169my ($exclude_re, $no_exclude_re); 170if ($action eq "realfull") { 171 $exclude_re = qr/^$/; 172 $no_exclude_re = qr/./; 173} else { 174 $exclude_re = join '|', @excluded; 175 $no_exclude_re = join '|', @non_excluded; 176} 177 178open my $config_write, '>', $config_file or die "write $config_file: $!\n"; 179 180my $done; 181for my $line (@config_lines) { 182 if ($action eq "full" || $action eq "realfull") { 183 if ($line =~ /name SECTION: Module configuration options/) { 184 $done = 1; 185 } 186 187 if (!$done && $line =~ m!^//\s?#define! && 188 ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) ) { 189 $line =~ s!^//\s?!!; 190 } 191 if (!$done && $line =~ m!^\s?#define! && 192 ! ( $line !~ /$exclude_re/ || $line =~ /$no_exclude_re/ ) ) { 193 $line =~ s!^!//!; 194 } 195 } elsif ($action eq "unset") { 196 if (!$done && $line =~ /^\s*#define\s*$name\b/) { 197 $line = '//' . $line; 198 $done = 1; 199 } 200 } elsif (!$done && $action eq "set") { 201 if ($line =~ m!^(?://)?\s*#define\s*$name\b!) { 202 $line = "#define $name"; 203 $line .= " $value" if defined $value && $value ne ""; 204 $line .= "\n"; 205 $done = 1; 206 } 207 } elsif (!$done && $action eq "get") { 208 if ($line =~ /^\s*#define\s*$name\s*(.*)\s*\b/) { 209 $value = $1; 210 $done = 1; 211 } 212 } 213 214 print $config_write $line; 215} 216 217# Did the set command work? 218if ($action eq "set"&& $force_option && !$done) { 219 220 # If the force option was set, append the symbol to the end of the file 221 my $line = "#define $name"; 222 $line .= " $value" if defined $value && $value ne ""; 223 $line .= "\n"; 224 $done = 1; 225 226 print $config_write $line; 227} 228 229close $config_write; 230 231if ($action eq "get") { 232 if($done) { 233 if ($value ne '') { 234 print $value; 235 } 236 exit 0; 237 } else { 238 # If the symbol was not found, return an error 239 exit -1; 240 } 241} 242 243if ($action eq "full" && !$done) { 244 die "Configuration section was not found in $config_file\n"; 245 246} 247 248if ($action ne "full" && $action ne "unset" && !$done) { 249 die "A #define for the symbol $name was not found in $config_file\n"; 250} 251 252__END__ 253