1#!/bin/sh
2#
3#
4# Licensed to the Apache Software Foundation (ASF) under one
5# or more contributor license agreements.  See the NOTICE file
6# distributed with this work for additional information
7# regarding copyright ownership.  The ASF licenses this file
8# to you under the Apache License, Version 2.0 (the
9# "License"); you may not use this file except in compliance
10# with the License.  You may obtain a copy of the License at
11#
12#   http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing,
15# software distributed under the License is distributed on an
16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17# KIND, either express or implied.  See the License for the
18# specific language governing permissions and limitations
19# under the License.
20#
21#
22HELP="\
23Usage: $0 [--remove] [FILE...]
24
25Insert or remove the GCC attribute \"warn_unused_result\" on each function
26that returns a Subversion error, in the specified files or, by default,
27*.h and *.c in the ./subversion and ./tools trees.
28"
29
30LC_ALL=C
31
32# Parse options
33REMOVE=
34case "$1" in
35--remove) REMOVE=1; shift;;
36--help)   echo "$HELP"; exit 0;;
37--*)      echo "$0: unknown option \"$1\"; try \"--help\""; exit 1;;
38esac
39
40# Set the positional parameters to the default files if none specified
41if [ $# = 0 ]; then
42  set -- `find subversion/ tools/ -name '*.[ch]'`
43fi
44
45# A line that declares a function return type of "svn_error_t *" looks like:
46# - Possibly leading whitespace, though not often.
47# - Possibly "static" or "typedef".
48# - The return type "svn_error_t *".
49# - Possibly a function or pointer-to-function declarator:
50#     - "identifier"
51#     - "(identifier)"  (used in some typedefs)
52#     - "(*identifier)"
53#   with either nothing more, or a "(" next (especially not "," or ";" or "="
54#   which all indicate a variable rather than a function).
55
56# Regular expressions for "sed"
57# Note: take care in matching back-reference numbers to parentheses
58PREFIX="^\( *\| *static  *\| *typedef  *\)"
59RET_TYPE="\(svn_error_t *\* *\)"
60IDENT="[a-zA-Z_][a-zA-Z0-9_]*"
61DECLR="\($IDENT\|( *\(\*\|\) *$IDENT *)\)"
62SUFFIX="\($DECLR *\((.*\|\)\|\)$"
63
64# The attribute string to be inserted or removed
65ATTRIB_RE="__attribute__((warn_unused_result))"  # regex version of it
66ATTRIB_STR="__attribute__((warn_unused_result))"  # plain text version of it
67
68if [ $REMOVE ]; then
69  SUBST="s/$PREFIX$ATTRIB_RE $RET_TYPE$SUFFIX/\1\2\3/"
70else
71  SUBST="s/$PREFIX$RET_TYPE$SUFFIX/\1$ATTRIB_STR \2\3/"
72fi
73
74for F do
75  # Edit the file, leaving a backup suffixed with a tilde
76  { sed -e "$SUBST" "$F" > "$F~1" &&
77    { ! cmp -s "$F" "$F~1"; } &&
78    mv "$F" "$F~" &&  # F is briefly absent now; a copy could avoid this
79    mv "$F~1" "$F"
80  } ||
81  # If anything went wrong or no change was made, remove the temporary file
82  rm "$F~1"
83done
84