summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rwxr-xr-xsrc/lib/librexgettext84
-rw-r--r--src/lib/messages.sh7
2 files changed, 74 insertions, 17 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
}
diff --git a/src/lib/messages.sh b/src/lib/messages.sh
index 37ee1b8..f28ce7c 100644
--- a/src/lib/messages.sh
+++ b/src/lib/messages.sh
@@ -124,7 +124,12 @@ bullet() {
#
# A heading MUST end with a colon (':'), this is how it knows that it
# is a heading. Similarly, a flag MUST NOT end with a colon.
-flag() {
+#
+# NB: The opening curly brace is on a separate line because otherwise
+# xgettext gets confused when parsing this file. It's a dumb bug in
+# GNU xgettext.
+flag()
+{
local args=("$@")
declare -i flaglen=0