summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-07-09 18:32:20 -0400
committerLuke Shumaker <lukeshu@lukeshu.com>2017-07-09 18:32:20 -0400
commit5ebc9f2a5ad207b8621e1aacf7bb23d32a7ce772 (patch)
tree957f6cb71c39af70d9d78ae9844a5ebc829bd94b
parent6b772f881dd8bb1a2a40181e6c76187c9c847c30 (diff)
librexgettext: Make the tests pass
-rwxr-xr-xsrc/lib/librexgettext84
1 files changed, 68 insertions, 16 deletions
diff --git a/src/lib/librexgettext b/src/lib/librexgettext
index cc18999..27a701d 100755
--- a/src/lib/librexgettext
+++ b/src/lib/librexgettext
@@ -40,7 +40,7 @@ fi
errusage() {
if [[ $# -gt 0 ]]; then
fmt="$(gettext "$1")"; shift
- printf "${0##*/}: $fmt\n" "$@"
+ printf "${0##*/}: $fmt\n" "$@" >&2
fi
usage >&2
}
@@ -76,6 +76,7 @@ xgettext-sh() {
}
xgettext-flag() {
+ local file="$1"
{
# Stage 1: Generate
#
@@ -95,9 +96,10 @@ xgettext-flag() {
declare -i i
for (( i=1; empties < 3; i++ )); do
local out
- out="$(xgettext-sh --keyword="flag:$i,\"$i\"" "$@")"
+ out="$(xgettext-sh --keyword="flag:$i,\"$i\"" -- "$file")"
if [[ -n $out ]]; then
printf -- '%s\n' "$out"
+ empties=0
else
empties+=1
fi
@@ -130,36 +132,77 @@ xgettext-flag() {
#
# We do this by simply sorting them by the location
# that they appear in the file. Then, when we see the
- # argument number go back down to 1, we know that a
- # new invocation has started!
- IFS=$'\n'
- local locations=($(
+ # argument number go back down, we know that a new
+ # invocation has started!
+ local locations=()
+ readarray -t locations < <(
local i
for i in "${!msgs[@]}"; do
+ local lines=()
+ readarray -t lines < <(printf '%s' "${msgs[$i]}")
+
declare -i arg row
- local lines=(${msgs[$i]})
arg=${lines[0]#'#. '}
row=${lines[1]##*:}
- printf '%d.%d %d\n' "$row" "$arg" "$i"
- done | sort -n
- ))
+
+ printf '%d %d %d\n' "$row" "$arg" "$i"
+ done | sort -k 1n -k 2n
+ )
# Stage 4: Output
#
# Now, we prune out the arguments that aren't
# localizable. Also, remove the "#." comment lines.
# As explained above (in stage 3), when we see $arg go
- # to 1, that's the beginning of a new invocation.
+ # down, that's the beginning of a new invocation.
local expectflag=true
+ local prev_arg=0
+ local prev_row=0 # for better error messages only; no real logic
local location
for location in "${locations[@]}"; do
- IFS=' .'
+ IFS=' '
local row arg i
read -r row arg i <<<"$location"
local msg="${msgs[$i]#*$'\n'}"
- # Now we operate based on $row, $arg, and $msg
- if [[ $arg == 1 ]]; then
- expectflag=true
+
+ # See if we need to fiddle with $expectflag
+ # (and do some sanity checking).
+ if [[ $arg != "$((prev_arg+1))" ]]; then
+ if ! $expectflag; then
+ local pos
+ if [[ $row != "$prev_row" ]]; then
+ printf -v pos "%s:%d-%d" "$file" "$prev_row" "$row"
+ else
+ printf -v pos "%s:%d" "$file" "$prev_row"
+ fi
+ >&2 printf "%s: $(gettext "flag error: Missing expected flag meaning at argument %d")\n" \
+ "$pos" "$((prev_arg+1))"
+ exit 1 # $EXIT_FAILURE
+ elif [[ $arg == "$((prev_arg+2))" ]]; then
+ # skipped flag argument
+ expectflag=false
+ elif [[ "$arg" == 1 ]]; then
+ # started new invocation
+ expectflag=true
+ elif [[ $arg == 2 ]]; then
+ # started new invocation and skipped flag argument
+ expectflag=false
+ else
+ local pos
+ if [[ $row != "$prev_row" ]]; then
+ printf -v pos "%s:%d-%d" "$file" "$prev_row" "$row"
+ else
+ printf -v pos "%s:%d" "$file" "$prev_row"
+ fi
+ >&2 printf "%s: $(gettext "flag error: Jumped from argument %d to %d")\n" \
+ "$pos" "$prev_arg" "$arg"
+ exit 1 # $EXIT_FAILURE
+ fi
fi
+ prev_arg=$arg
+ prev_row=$row
+
+ # Now we operate based on $row, $arg, $msg,
+ # and $expectflag.
if $expectflag; then
IFS=$'\n'
local lines=(${msg})
@@ -177,6 +220,12 @@ xgettext-flag() {
expectflag=true
fi
done
+ if ! $expectflag; then
+ >&2 printf "%s:%d: $(gettext "flag error: Missing expected flag meaning at argument %d")\n" \
+ "$file" "$prev_row" \
+ "$((prev_arg+1))"
+ exit 1 # $EXIT_FAILURE
+ fi
}
}
@@ -186,6 +235,7 @@ whitespace-collapse() {
}
main() {
+ set -euE -o pipefail
local simple=()
local prose=()
local files=()
@@ -223,7 +273,9 @@ main() {
{
xgettext-sh "${simple[@]}" -- "${files[@]}"
xgettext-sh "${prose[@]}" -- "${files[@]}" | whitespace-collapse
- xgettext-flag -- "${files[@]}"
+ for file in "${files[@]}"; do
+ xgettext-flag "$file"
+ done
} | sed '/^\#, sh-format/d' | msguniq -Fi --to-code=UTF-8
}