Blame MakeTools/unifdef2.sh

Packit 857059
#!/bin/bash
Packit 857059
Packit 857059
###################################################################################
Packit 857059
#
Packit 857059
# unifdef2.sh script
Packit 857059
#
Packit 857059
# Arguments:
Packit 857059
#   featureset-tag - this names the feature set and is used to identify sections
Packit 857059
#     in the in-file to be considered in the out-file
Packit 857059
#   in-file - the input file. The file must contain at least one instance of
Packit 857059
#     "ifdef <tag>" and "endif <tag>" bracketing some text
Packit 857059
#   out-file - the output file to be written after applying the filtering
Packit 857059
#
Packit 857059
#   unifdef2.sh filters a file by including everything outside of ifdef-endif
Packit 857059
#     brackets, and including only lines inside ifdef-endif brackets with the
Packit 857059
#     given featureset tag. All other lines are filtered out.
Packit 857059
#
Packit 857059
#   Syntax of ifdef-endif pairs:
Packit 857059
#     Bracketing lines is accomplished by using "#ifdef <tag>" and "#endif <tag>"
Packit 857059
#     lines starting in the first colunm. There must be a single space between
Packit 857059
#     the ifdef/endif keyword and the tag. The tag can be followed by whitespace
Packit 857059
#     and then optional commenting text.
Packit 857059
#     Tags can be made up of alphnumeric and underscore characters, for example,
Packit 857059
#     "opa10", "opa11_2", etc.
Packit 857059
#     Examples:
Packit 857059
#     #ifdef opa10
Packit 857059
#     
Packit 857059
#     #endif opa10 # this can be comments, the pound sign is not necessary
Packit 857059
#
Packit 857059
#   Calling example: MakeTools/unifdef2.sh opa10 foo.sh.base foo.sh
Packit 857059
#     This example calls the script on the input file "foo.sh.base", processing
Packit 857059
#     the file looking for ifdef-endif bracketing pairs, and excluding all code
Packit 857059
#     within those brackets except those bracketed by "#ifdef opa10".."#endif opa10"
Packit 857059
#
Packit 857059
###################################################################################
Packit 857059
Packit 857059
check_tag_syntax()
Packit 857059
{
Packit 857059
	ltag1=$1
Packit 857059
	where="$2"
Packit 857059
Packit 857059
	rest=${ltag1//[A-Za-z0-9_]}
Packit 857059
	if [ "$rest" != "" ]
Packit 857059
	then
Packit 857059
		echo ERROR: unifdef2.sh: invalid featureset \<$ltag1\> "$where"
Packit 857059
		echo        featureset can only be alphanumeric and underscores
Packit 857059
		rm -f .greps .greps1
Packit 857059
		exit 1
Packit 857059
	fi
Packit 857059
}
Packit 857059
Packit 857059
# shut off globbing
Packit 857059
set -f
Packit 857059
Packit 857059
if [ $# -ne 3 ]
Packit 857059
then
Packit 857059
	echo ERROR: unifdef2.sh: wrong number of arguments: $#
Packit 857059
	echo Usage: unifdef2.sh featureset-tag in-file out-file
Packit 857059
	exit 1
Packit 857059
fi
Packit 857059
Packit 857059
featureset=$1
Packit 857059
in_file=$2
Packit 857059
out_file=$3
Packit 857059
Packit 857059
check_tag_syntax $featureset "on command line"
Packit 857059
Packit 857059
# check existence of in_file
Packit 857059
Packit 857059
if [ ! -f $in_file ]
Packit 857059
then
Packit 857059
	echo ERROR: unifdef2.sh: no such file $in_file
Packit 857059
	exit 1
Packit 857059
fi
Packit 857059
Packit 857059
# check that in_file and out_file are different
Packit 857059
Packit 857059
if [ "$in_file" = "$out_file" ]
Packit 857059
then
Packit 857059
	echo ERROR: unifdef2.sh: in-file must be different than out-file
Packit 857059
	echo Usage: unifdef2.sh featureset-tag in-file out-file
Packit 857059
	exit 1
Packit 857059
fi
Packit 857059
Packit 857059
# parse for syntax - check ifdef and endif tags, ensure matching and no nesting
Packit 857059
Packit 857059
# first extract all #ifdef and #endif directives to make it run faster
Packit 857059
# ... in the grep, record the line nu㏔ers as well, we will use in main loop below
Packit 857059
Packit 857059
grep -n "^#ifdef .*" $in_file > .greps1
Packit 857059
grep -n "^#endif .*" $in_file >> .greps1
Packit 857059
sort -g .greps1 > .greps # sort using line numbers with general-number-sort
Packit 857059
rm -f .greps1
Packit 857059
Packit 857059
# check for:
Packit 857059
#  - mismatched ifdef-endif pairs
Packit 857059
#  - endif before ifdef
Packit 857059
#  - nesting
Packit 857059
Packit 857059
outside_bracket=1
Packit 857059
save_tag=
Packit 857059
while read line
Packit 857059
do
Packit 857059
	if [ $outside_bracket = 1 ]
Packit 857059
	then
Packit 857059
		if echo $line | grep "#ifdef " > /dev/null
Packit 857059
		then
Packit 857059
			save_tag=$(echo $line | cut -d' ' -f 2 | cut -f1)
Packit 857059
			check_tag_syntax $save_tag "in $in_file"
Packit 857059
			outside_bracket=0
Packit 857059
		elif echo $line | grep "#endif " > /dev/null
Packit 857059
		then
Packit 857059
			save_tag=$(echo $line | cut -d' ' -f 2 | cut -f1)
Packit 857059
			check_tag_syntax $save_tag "in $in_file"
Packit 857059
			echo ERROR: unifdef2.sh: endif tag before ifdef for $save_tag in $in_file
Packit 857059
			exit 1
Packit 857059
		fi
Packit 857059
	else # inside bracket - look for endif for this tag
Packit 857059
		if echo $line | grep "#endif $save_tag" > /dev/null
Packit 857059
		then
Packit 857059
			save_tag=
Packit 857059
			outside_bracket=1
Packit 857059
		elif echo $line | grep "#ifdef " > /dev/null
Packit 857059
		then
Packit 857059
			save_tag2=$(echo $line | cut -d' ' -f 2 | cut -f1)
Packit 857059
			check_tag_syntax $save_tag2 "in $in_file"
Packit 857059
			echo ERROR: unifdef2.sh: ifdef tag for $save_tag2 before endif for $save_tag in $in_file
Packit 857059
			exit 1
Packit 857059
		elif echo $line | grep "#endif " > /dev/null
Packit 857059
		then
Packit 857059
			save_tag2=$(echo $line | cut -d' ' -f 2 | cut -f1)
Packit 857059
			check_tag_syntax $save_tag2 "in $in_file"
Packit 857059
			echo ERROR: unifdef2.sh: endif tag for $save_tag2 inside bracket for $save_tag in $in_file
Packit 857059
			exit 1
Packit 857059
		fi
Packit 857059
	fi
Packit 857059
done < .greps
Packit 857059
if [ $outside_bracket = 0 ]
Packit 857059
then
Packit 857059
	echo ERROR: unifdef2.sh: no endif for ifdef for $save_tag in $in_file
Packit 857059
	exit 1
Packit 857059
fi
Packit 857059
Packit 857059
Packit 857059
#
Packit 857059
# now filter the file to create the out file
Packit 857059
#
Packit 857059
# Set writing to 1 (write everything except what is inside other ifdefs)
Packit 857059
# Set line number to 1
Packit 857059
#
Packit 857059
# Loop through lines in in_file:
Packit 857059
#   read a line
Packit 857059
#   if the line number matches an ifdef/endif directive
Packit 857059
#     grab tag and directive from line
Packit 857059
#     if directive is ifdef
Packit 857059
#       if tag does not match featureset
Packit 857059
#         set writing to 0 (filter out this stuff)
Packit 857059
#     else (directive is endif)
Packit 857059
#       if tag does not match featureset
Packit 857059
#         set writing to 1 (start writing again, "filter out" bracket is closed)
Packit 857059
#   else (not a directive, just a normal line)
Packit 857059
#     if writing is 1, write line to out_file
Packit 857059
#   increment line number
Packit 857059
#
Packit 857059
Packit 857059
> $out_file
Packit 857059
chmod --reference=$in_file $out_file		# match permissions of in-file
Packit 857059
Packit 857059
writing=1
Packit 857059
line_number=1
Packit 857059
Packit 857059
while IFS= read -r line
Packit 857059
do
Packit 857059
	# is line_number in .greps?
Packit 857059
	if grep -w $line_number .greps > /dev/null
Packit 857059
	then
Packit 857059
		ltag=$(grep -w $line_number .greps|cut -f2 -d' '|cut -f1)
Packit 857059
		ldirective=$(grep -w $line_number .greps | cut -d' ' -f1 | cut -d# -f2)
Packit 857059
		if [ "$ldirective" = "ifdef" ]
Packit 857059
		then
Packit 857059
			if [ "$ltag" != "$featureset" ]
Packit 857059
			then
Packit 857059
				writing=0
Packit 857059
			fi
Packit 857059
		else # it is endif
Packit 857059
			if [ "$ltag" != "$featureset" ]
Packit 857059
			then
Packit 857059
				writing=1
Packit 857059
			fi
Packit 857059
		fi
Packit 857059
	elif [ $writing -eq 1 ]
Packit 857059
	then
Packit 857059
		echo "$line" >> $out_file
Packit 857059
	fi
Packit 857059
	line_number=$((line_number+1))
Packit 857059
done < $in_file
Packit 857059
Packit 857059
rm -f .greps
Packit 857059
Packit 857059
exit 0