Finding missing void keywords in C source code I'm writing a bash script to search C source files and find the lines where I missed the void keyword (unlike in C++, in C, empty parameter lists have to be indicated with the void keyword).

I read that I shouldn't use for but while: https://mywiki.wooledge.org/DontReadLinesWithFor

I find that for has an easier to follow, top-down structure (first I write the command that produces the items to be iterated, then I write what to do with each).

I understand that if a filename contained a newline it would cause trouble in case of for; however, with IFS=$'\n'; set -f I would think all other problems are solved.

My code using for:

#!/bin/bash

returnTypeOpt_BRE='\([a-zA-Z_][a-zA-Z0-9_]\{0,\}[*  ]\{1,\}\)\{0,1\}'
spaceOpt_BRE=$'[ \t\r]\\{0,\\}'
functionName_BRE='\([a-zA-Z_][a-zA-Z0-9_]\{0,\}\)'
declarationMissingVoid_BRE="^$returnTypeOpt_BRE$spaceOpt_BRE$functionName_BRE$spaceOpt_BRE($spaceOpt_BRE)$spaceOpt_BRE;$spaceOpt_BRE\$"

targetFolder_Path="$1"
if [ $# -eq 0 ]; then
    targetFolder_Path="."
fi

IFS=$'\n'; set -f; for file in $( find "$targetFolder_Path" -name '*.c' -or -name '*.h' ); do
    printf "%s\n" "$file"
    for line in $( grep --basic-regex --regexp=$declarationMissingVoid_BRE $file ); do
        printf "\t&gt;%s\n" "$line"
    done
done; unset IFS; set +f


My code using while:

#!/bin/bash

returnTypeOpt_BRE='\([a-zA-Z_][a-zA-Z0-9_]\{0,\}[*  ]\{1,\}\)\{0,1\}'
spaceOpt_BRE=$'[ \t\r]\\{0,\\}'
functionName_BRE='\([a-zA-Z_][a-zA-Z0-9_]\{0,\}\)'
declarationMissingVoid_BRE="^$returnTypeOpt_BRE$spaceOpt_BRE$functionName_BRE$spaceOpt_BRE($spaceOpt_BRE)$spaceOpt_BRE;$spaceOpt_BRE\$"

targetFolder_Path="$1"
if [ $# -eq 0 ]; then
    targetFolder_Path="."
fi

while IFS=; read -u 3 -r -d $'\0' file; do
    printf "%s\n" "$file"
    while IFS=; read -u 4 -r line; do
        printf "\t&gt;%s\n" "$line"
    done 4&lt; &lt;( grep --basic-regex --regexp=$declarationMissingVoid_BRE $file )
done 3&lt; &lt;( find "$targetFolder_Path" -name '*.c' -print0 -or -name '*.h' -print0 )


So, for me both scripts work correctly, and produce the same result.

Beyond the "filenames with newlines" issue is there anything else that would make while better? Can you show me a test case?

If I had to solve similar but different (possibly more complex) tasks would I have problems with for?
I'm writing a bash script to search C source files and find the lines where I missed the void keyword


This alone suggests that your approach is very problematic. To do this properly you'd effectively need to write most of a C parser, and that isn't a good use of your time. There are other approaches that would get you more mileage and accuracy:


Double-check that your compiler (gcc?) for sure doesn't have warnings that cover your use-case; if it does, then simply compile and look at the output.
Failing that, reuse a parser. I recommend the Clang AST.


Bash is just the hideously wrong tool for this. Save yourself the pain of writing regexes that are both complex and likely missing many edge cases.