#!/bin/sh HELP="\ Usage: $0 [--remove] [FILE...] Insert or remove the GCC attribute \"warn_unused_result\" on each function that returns a Subversion error, in the specified files or, by default, *.h and *.c in the ./subversion and ./tools trees. " LC_ALL=C # Parse options REMOVE= case "$1" in --remove) REMOVE=1; shift;; --help) echo "$HELP"; exit 0;; --*) echo "$0: unknown option \"$1\"; try \"--help\""; exit 1;; esac # Set the positional parameters to the default files if none specified if [ $# = 0 ]; then set -- `find subversion/ tools/ -name '*.[ch]'` fi # A line that declares a function return type of "svn_error_t *" looks like: # - Possibly leading whitespace, though not often. # - Possibly "static" or "typedef". # - The return type "svn_error_t *". # - Possibly a function or pointer-to-function declarator: # - "identifier" # - "(identifier)" (used in some typedefs) # - "(*identifier)" # with either nothing more, or a "(" next (especially not "," or ";" or "=" # which all indicate a variable rather than a function). # Regular expressions for "sed" # Note: take care in matching back-reference numbers to parentheses PREFIX="^\( *\| *static *\| *typedef *\)" RET_TYPE="\(svn_error_t *\* *\)" IDENT="[a-zA-Z_][a-zA-Z0-9_]*" DECLR="\($IDENT\|( *\(\*\|\) *$IDENT *)\)" SUFFIX="\($DECLR *\((.*\|\)\|\)$" # The attribute string to be inserted or removed ATTRIB_RE="__attribute__((warn_unused_result))" # regex version of it ATTRIB_STR="__attribute__((warn_unused_result))" # plain text version of it if [ $REMOVE ]; then SUBST="s/$PREFIX$ATTRIB_RE $RET_TYPE$SUFFIX/\1\2\3/" else SUBST="s/$PREFIX$RET_TYPE$SUFFIX/\1$ATTRIB_STR \2\3/" fi for F do # Edit the file, leaving a backup suffixed with a tilde { sed -e "$SUBST" "$F" > "$F~1" && { ! cmp -s "$F" "$F~1"; } && mv "$F" "$F~" && # F is briefly absent now; a copy could avoid this mv "$F~1" "$F" } || # If anything went wrong or no change was made, remove the temporary file rm "$F~1" done