diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-04-15 17:06:52 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-04-15 17:19:47 -0400 |
commit | bd1d554a35b543afa5a79dd483583bf2aad9cf47 (patch) | |
tree | 4c93824f367f0d0f95ce4231ee563ed8a865317e /src/lib/librexgettext | |
parent | 080d2decb7e3aae1917de9d8a7d5089d74833d65 (diff) |
libremessages:flag: Fix several things (also librexgettext)
- Fix a bug where it panicked if given an odd number of sub-headings.
- Document the the ability to include sub-headings.
- Fix librexgettext's handling of it. It only worked correctly for times
when it was only called once in a program, or when it was only ever
called with exactly one flag/description pair (and no headings).
Diffstat (limited to 'src/lib/librexgettext')
-rwxr-xr-x | src/lib/librexgettext | 101 |
1 files changed, 78 insertions, 23 deletions
diff --git a/src/lib/librexgettext b/src/lib/librexgettext index 22a6df2..c82b9ae 100755 --- a/src/lib/librexgettext +++ b/src/lib/librexgettext @@ -65,49 +65,104 @@ xgettext-sh() { xgettext-flag() { { - declare -i x=0 + # Stage 1: Generate + # + # Get all of the arguments to `flag`. Because `flag` + # takes an arbitrary number of arguments, just iterate + # through arg1, arg2, ... argN; until we've come up + # empty 3 times. Why 3? Because each flag takes 2 + # arguments, and because we don't keep track of which + # one of those we're on, waiting for 3 empties ensures + # us that we've had a complete "round" with nothing. + # + # Why can't I just do i+=2, and not have to keep track + # of empties? Because, we also allow for arguments + # ending in a colon to be headings, which changes the + # offsets. + declare -i empties=0 declare -i i - for (( i=1; x < 3; i++ )); do + for (( i=1; empties < 3; i++ )); do local out out="$(xgettext-sh --keyword="flag:$i,\"$i\"" "$@")" if [[ -n $out ]]; then printf -- '%s\n' "$out" else - x+=1 + empties+=1 fi done } | whitespace-collapse | sed '/^\#, sh-format/d' | { - declare -i i - - IFS='' - local segments=() + # Stage 2: Parse + # + # Read in the lines, and group them into an array of + # (multi-line) msgs. This just makes working with + # them easier. + local msgs=() + declare -i i=-1 local re='^#\. ([0-9]+)$' + IFS='' local line while read -r line; do if [[ $line =~ $re ]]; then - i=${BASH_REMATCH[1]} - else - segments[$i]+="$line"$'\n' + i+=1 fi + msgs[$i]+="$line"$'\n' done - - declare -i last=$(printf '%s\n' "${!segments[@]}"|sed -n '$p') - + # Stage 3: Sort + # + # Now, we have the `msgs` array, and it is + # sorted such that it is all of the arg1's to `flag`, + # then all of the arg2's, then all of the arg3's, and + # so on. We want to re-order them such that it's all + # of the args for the first invocation then all of the + # args for the second; and so on. + # + # 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 flag=true - for (( i=1; i <= last; i++ )); do - if $flag; then - local lines=(${segments[$i]}) + local locations=($( + local i + for i in "${!msgs[@]}"; do + 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 + )) + # 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. + local expectflag=true + local location + for location in "${locations[@]}"; do + 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 + fi + if $expectflag; then + IFS=$'\n' + local lines=(${msg}) if [[ ${lines[1]} == *':"' ]]; then - printf -- '%s\n' "${segments[$i]}" + # We expected a flag, but got + # a heading + printf -- '%s\n' "$msg" else - flag=false + # We expected a flag, and got + # one! + expectflag=false fi else - if [[ -n ${segments[$i]} ]]; then - printf -- '%s\n' "${segments[$i]}" - fi - flag=true + printf -- '%s\n' "$msg" + expectflag=true fi done } |