Last active
August 29, 2015 14:12
-
-
Save pamaury/3fa6ff03ecc26387b977 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/bin/bash | |
TMPDIR="./tmp-check-defines" | |
SEARCH_DIRS="apps/ firmware/ uisimulator/" | |
function usage() | |
{ | |
echo "Usage: $0 <build file> <define 1> [<define 2>...]" | |
echo "If the define name is suffixed with @ or ~, the tool will also print its value" | |
echo "Furthermore, if a regex follows the @, the tool will try to list all defines" | |
echo "matching this regex to pretty print the output" | |
echo "If the define name is suffixed with ~, the tool will try to list all definitions" | |
echo "of the macro and compare the right hand side value with the actual value" | |
echo "to pretty print the value" | |
echo "" | |
echo "Examples:" | |
echo "$0 ../www/buildserver/builds HAVE_USBSTACK " | |
echo "$0 ../www/buildserver/builds 'CONFIG_LCD@LCD_[[:alnum:]_]*'" | |
echo "$0 ../www/buildserver/builds CONFIG_CPU~" | |
exit 1 | |
} | |
# pattern_check define file | |
function pattern_check() | |
{ | |
cat >>"$2" <<EOF | |
#ifdef $1 | |
#pragma message "cafebabe-$1" | |
#else | |
#pragma message "deadbeef-$1" | |
#endif | |
EOF | |
} | |
# pattern_check define file | |
function pattern_value() | |
{ | |
cat >>"$2" <<EOF | |
#ifdef $1 | |
#pragma message "cafebabe-$1@"MYEVAL($1)"@" | |
#else | |
#pragma message "deadbeef-$1" | |
#endif | |
EOF | |
} | |
# pattern_check define regex file | |
function pattern_regex() | |
{ | |
# not implemented yet | |
cat >>"$3" <<EOF | |
#ifdef $1 | |
#pragma message "cafebabe-$1@"MYEVAL($1)"@" | |
#else | |
#pragma message "deadbeef-$1" | |
#endif | |
EOF | |
} | |
# pattern_list define file | |
function pattern_list() | |
{ | |
cat >>"$2" <<EOF | |
#if !defined($1) | |
#pragma message "deadbeef-$1" | |
EOF | |
# find all occurences | |
grep -REh "^#define[[:space:]]+$1[[:space:]]+" $SEARCH_DIRS | | |
awk -v "DEF=$1" '{ match($0,/#define[[:space:]]+[[:alnum:]_]+[[:space:]]+(.*)/,arr); | |
print("#elif "DEF" == ("arr[1]")"); | |
print("#pragma message \"cafebabe-"DEF"@"arr[1]"@\""); }' >> $2 | |
cat >>"$2" <<EOF | |
#else | |
#pragma message "cafebabe-$1@"MYEVAL($1)"@" | |
#endif | |
EOF | |
} | |
# check number of arguments | |
if [ $# -le 1 ]; then | |
usage | |
fi | |
# print invocation, for reference | |
echo "#invocation $0 $*" | |
# build file | |
BUILD_FILE="$1" | |
shift | |
# check build file | |
if [ ! -f $BUILD_FILE ]; then | |
echo "ERROR: build file doesn't exist" | |
exit 2 | |
fi | |
# fill template test file | |
TMPLFILE=template.c | |
cat > "$TMPLFILE" <<EOF | |
/* Automatically generated. http://www.rockbox.org/ */ | |
#include "system.h" | |
#include "usb.h" | |
#include "usb_ch9.h" | |
/* add more includes here if needed */ | |
#define MYEVAL_(x) #x | |
#define MYEVAL(x) MYEVAL_(x) | |
EOF | |
# generate test pattern for each define | |
for DEFINE in "$@" | |
do | |
# check if define must be printed (named suffixed by @) | |
if [[ "$DEFINE" =~ "@" ]]; then | |
REGEX=`echo "$DEFINE" | awk '{ match($0,/@(.*)$/,arr); print(arr[1]); }'` | |
DEFINE=`echo "$DEFINE" | awk '{ match($0,/([^@]*)@/,arr); print(arr[1]); }'` | |
# if regex is empty, it's simple | |
if [ "$REGEX" = "" ]; then | |
pattern_value "$DEFINE" "$TMPLFILE" | |
else | |
pattern_regex "$DEFINE" "$REGEX" "$TMPLFILE" | |
fi | |
elif [[ "$DEFINE" =~ "~" ]]; then | |
DEFINE=`echo "$DEFINE" | awk '{ match($0,/([^~]*)~/,arr); print(arr[1]); }'` | |
pattern_list "$DEFINE" "$TMPLFILE" | |
else | |
pattern_check "$DEFINE" "$TMPLFILE" | |
fi | |
done | |
# process lines in the build | |
while read line | |
do | |
# ignore wps and manual lines, also sim | |
if `echo "$line" | grep -E "(wps)|(manual)|(sim)" &> /dev/null`; then | |
continue | |
fi | |
# format of each line: compiler:x:name:title:file:hint:command | |
NAME=`echo "$line" | awk 'BEGIN { FS=":" } { print $3 }'` | |
CMD=`echo "$line" | awk 'BEGIN { FS=":" } { print $7 }'` | |
# remove temporary directory | |
rm -rf "$TMPDIR" | |
# create temporary directory and cd into it | |
mkdir "$TMPDIR" | |
cd "$TMPDIR" | |
# create a fake generated file | |
TESTFILE=mytest | |
cp "../$TMPLFILE" "$TESTFILE.c" | |
# the command extract is of the form | |
# ../tools/configure <options> && make <blabla> | |
# extract the part before && and replace the whole thing with: | |
# ../tools/configure <options> && make $TESTFILE.o | |
CFGCMD=`echo "$CMD" | awk '{ i=index($0, "&&"); print(substr($0,1,i-1)); }'` | |
# try to run configure | |
# it might error if the target compiler is not installed for example | |
if eval $CFGCMD &>/dev/null; then | |
# pretend dependencies were generated (because it's very long) | |
touch make.dep | |
# try to build our test file | |
OUTPUT=out.txt | |
ERROR=err.txt | |
if ! make $TESTFILE.o >$OUTPUT 2>$ERROR; then | |
# print make error | |
echo "$NAME: <make error>" | |
else | |
# print defines | |
echo "$NAME:" `cat "$ERROR" | awk 'BEGIN { list="" } | |
{ if(match($0,/cafebabe-([[:alnum:]_]+)/,arr) != 0) list = list " " arr[1]; | |
if(match($0,/@([^@]*)@/,arr)) list = list "=" arr[1]; } | |
END { print(list); }'` | |
fi | |
else | |
# print config error | |
echo "$NAME: <config error>" | |
fi | |
# cd back to root | |
cd .. | |
done < "$BUILD_FILE" | |
# remove everything | |
rm -rf "$TMPDIR" | |
rm -f "$TMPLFILE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment