#ifdef vs #if for feature checks [proof of concept]

Thomas Arnhold thomas-libo at arnhold.org
Wed Mar 20 07:32:44 PDT 2013


Hi,

https://gerrit.libreoffice.org/#/c/2875/

At least on Linux with

--without-java --enable-werror

works for me.

I only replaced guards like *_HXX_, *_HXX__ and *_HXX_INCLUDED which are 
not used at any other place. Those are ~8700 matches. Approx. 500 look 
like guards, but don't match the scheme and ~400 hxx headers don't have 
guards at all. So the replace of the 8700 matches should be a good estimate.

The script is some kind of weirdo, but it should demonstrate the 
difference between guard and pragma. I inserted #if 1 to ignore the 
#endif at the end of the file.

Files which RSC touches cannot be converted, because he complains about 
#pragma once. If you get RSC errors then some hrc or src includes a hxx 
with pragma once.

So the door is open for a comparison.

Happy benchmarking.

Thomas
-------------- next part --------------

rm guards-all.log
rm guards-all-count.log

# get a list of all guards from all hxx files (~8700)
# ZIPFILE_HXX
# ZIPFILE_HXX_
# ZIPFILE_HXX_INCLUDED
git grep -h '^\s*#\s*ifndef\s*.*_HXX\(_\|__\|_INCLUDED\)\?$' -- '*.hxx' | sed 's/^\s*#\s*ifndef\s\+//g' | sort -u > guards-all.log

# those must not be in the list
# INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX*

# omitted: those don't match to _HXX scheme (~500)
#git grep '^\s*#\s*ifndef\s*.*' -- '*.hxx' | grep -v '_HXX'

# omit those which are used in other files, too
# for this we count them (takes some time)


for i in `cat guards-all.log`; do
	git grep -w $i > guards.tmp; # safe to save greps

	# there has to be at least one define and one ifndef otherwise it's no guard
	if [ `cat guards.tmp | grep "#\s*ifndef\s\+$i" | wc -l` == 1 ] && [ `cat guards.tmp | grep "#\s*define\s\+$i" | wc -l` == 1 ]; then
		countfiles=`cat guards.tmp | cut -d':' -f1 | sort -u | wc -l`
		countmatches=`cat guards.tmp | cut -d':' -f2- |
			grep -v "#\s*ifndef\s\+$i" |
			grep -v "#\s*define\s\+$i" |
			grep -v '#\s*endif' |
			grep -v "//\s*$i" |
			wc -l`

		### log it
		# row 1: matches n files (should be one)
		# row 2: k matches expect those guard lines (should be zero)
		echo $countfiles $countmatches $i >> guards-all-count.log;

		### substitute

		# dirty fix: delete include guard and use #pragma once
		# at the moment don't care about #endif -> insert #if 1

		# TODO: insert pragma nicely right after the licence header
		# one newline before and after, no more

		# safe are those which are in one file and have no further matches than the defined above
		if [ $countfiles == 1 ] && [ $countmatches == 0 ]; then
			file=`cat guards.tmp | cut -d':' -f1 | sort -u`

			echo $file; # for progress
			# FIXME: doing this in one regex would be safer (CSV_CSV_ENV_HXX_HAD_NDEBUG)
			sed -i "s/\s*\#\s*ifndef\s\+$i/#pragma once/" $file;
			sed -i "s/\s*\#\s*define\s\+$i/#if 1/g" $file;
		fi
	fi;
done


### whitelist hrc and src included hxx files (rsc complies)

# omit guards in header files which are included in [sh]rc files
# fixed with git checking out the list of includes-hsrc.log at the moment

# get all includes from hrc and src files, only hxx files
for i in `find . -name *.hrc -or -name *.src | grep -v '/workdir/' | grep -v '/solver/'`; do grep '^\s*#\s*include\s*[<"]' $i | grep '\.hxx[">]'; done >includes-hsrc-all.log

# extract filename
cat includes-hsrc-all.log | sed 's/^\s*#\s*include\s*[<"]\([^">]*\)[">].*/\1/g' | sort -u > includes-hsrc.log

# reset them	
for i in `cat includes-hsrc.log`; do find . -name `basename $i` | grep -v '/workdir/' | grep -v '/solver/'; done | xargs git checkout

# there are more
git checkout ./basic/inc/basic/sbxdef.hxx



## manual cross check
# there should be only added two lines with excatly these expressions
# git diff HEAD | grep '^+[^+]' | grep -v '^+#if 1$' | grep -v '^+#pragma once$'


More information about the LibreOffice mailing list