#!/bin/sh # # Copyright (C) 2014 Masatake YAMATO # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set -e # Avoid trouble with weird bytes on non-C locales export LC_ALL=C READTAGS=${1:-./readtags} UNITS=${2:-./Units} shift 2 MINITRIP= while [ $# -gt 0 ]; do case $1 in --minitrip) MINITRIP=minitrip ;; *) echo "Unexpected argument: $1" 1>&2 exit 1 ;; esac shift done s=0 if ! [ -f "${READTAGS}" ]; then echo "No such file: ${READTAGS}" 1>&2 exit 1 fi if ! [ -x "${READTAGS}" ]; then echo "Not an executable: ${READTAGS}" 1>&2 exit 1 fi if ! [ -x "${UNITS}" ]; then echo "Not such directory: ${UNITS}" 1>&2 exit 1 fi # Expand CTags escape sequences (and keep the original, too) # See docs/format.rst expandEscapeSequences() { sed -e ' # early out if there is no escape sequence (common case) /\\/!b # loop until we handled all occurrences of \. # as it is not possible to do all replacements at once and we need not to # ever use the result of an replacement to perform another one, use two # reserved placeholders. :again s/\\/__BACKSLASH__/ s/__BACKSLASH__\\/__LITBACKSLASH__/; t again s/__BACKSLASH__t/ /; t again s/__BACKSLASH__r/'"$(printf '\r')"'/; t again s/__BACKSLASH__n/\ /; t again s/__BACKSLASH__a//; t again s/__BACKSLASH__b/'"$(printf '\b')"'/; t again s/__BACKSLASH__v/ /; t again s/__BACKSLASH__f/ /; t again s/__BACKSLASH__x01//; t again s/__BACKSLASH__x02//; t again s/__BACKSLASH__x03//; t again s/__BACKSLASH__x04//; t again s/__BACKSLASH__x05//; t again s/__BACKSLASH__x06//; t again s/__BACKSLASH__x07//; t again s/__BACKSLASH__x08//; t again s/__BACKSLASH__x09/ /; t again s/__BACKSLASH__x0[aA]/\ /; t again s/__BACKSLASH__x0[bB]/ /; t again s/__BACKSLASH__x0[cC]/ /; t again s/__BACKSLASH__x0[dD]/'"$(printf '\r')"'/; t again s/__BACKSLASH__x0[eE]//; t again s/__BACKSLASH__x0[fF]//; t again s/__BACKSLASH__x10//; t again s/__BACKSLASH__x11//; t again s/__BACKSLASH__x12//; t again s/__BACKSLASH__x13//; t again s/__BACKSLASH__x14//; t again s/__BACKSLASH__x15//; t again s/__BACKSLASH__x16//; t again s/__BACKSLASH__x17//; t again s/__BACKSLASH__x18//; t again s/__BACKSLASH__x19//; t again s/__BACKSLASH__x1[aA]//; t again s/__BACKSLASH__x1[bB]//; t again s/__BACKSLASH__x1[cC]//; t again s/__BACKSLASH__x1[dD]//; t again s/__BACKSLASH__x1[eE]//; t again s/__BACKSLASH__x1[fF]//; t again s/__BACKSLASH__x21/!/; t again s/__BACKSLASH__x20/ /; t again s/__BACKSLASH__x7[fF]//; t again /\\/b again # replace lonely "\"es s/__BACKSLASH__/\\/g # replace literal "\"es ("\\" from the input) s/__LITBACKSLASH__/\\/g ' } # disable path expansion, because we don't need it and it's applied on the # result of the commands used to loop on, and we don't want that. set -f # remove space from IFS as it's valid in tag names OLD_IFS="$IFS" IFS=' ' ntagfiles=0 ntrips=0 tagfiles=$(find "$UNITS" -name expected.tags) for tags in $tagfiles; do ntagfiles=$(expr $ntagfiles + 1) dir=$(dirname "$tags") if [ -n "$MINITRIP" -a ! -e "$dir/$MINITRIP" ]; then continue fi ntrips=$(expr $ntrips + 1) tagnames=$(sed -e 's/^\([^ ]*\) .*/\1/' "$tags") for name in $tagnames; do # Yes, there is a reason for this craziness. We need to properly # handle embedded newlines (expanded from "\n"), including trailing # ones the shell would strip automatically. To work around this, we # add a dummy character at the end to inhibit stripping, and then # remove it, plus the extra newline, using variable substitutions. # Note: we use "printf '%s\n'" instead of "echo" because Dash's "echo" # unconditionally expands some sequences, like "\t" and alike. t="$(printf '%s\n' "$name" | expandEscapeSequences; printf _)" t="${t% _}" if [ 1 -gt $("${READTAGS}" -t "$tags" - "$t" | wc -l) ]; then printf 'FAILED: "%s" -t "%s" - "%s"\n' "${READTAGS}" "$tags" "$t" printf ' The raw tag name was "%s"\n' "$name" s=1 fi done done IFS="$OLD_IFS" note= if [ -n "$MINITRIP" ]; then note="[$MINITRIP]" fi printf "%s/%s%s...%d\n" "$ntrips" "$ntagfiles" "$note" "$s" exit $s