Module Name: src Committed By: cjep Date: Tue Jun 29 08:02:50 UTC 2021
Modified Files: src/usr.sbin/sysinst: msg_xlat.sh Log Message: 1. Rework the IFS handling when checking consistency of formatting in sysinst messages. Closes PR toolchain/56181. 2. Whilst here, change some shell clauses to be more portable. Patch developed by kre. Also reviewed by martin. Cross-builds tested on NetBSD, OpenBSD, FreeBSD and Darwin. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/sysinst/msg_xlat.sh Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/sysinst/msg_xlat.sh diff -u src/usr.sbin/sysinst/msg_xlat.sh:1.2 src/usr.sbin/sysinst/msg_xlat.sh:1.3 --- src/usr.sbin/sysinst/msg_xlat.sh:1.2 Thu Nov 5 19:13:21 2020 +++ src/usr.sbin/sysinst/msg_xlat.sh Tue Jun 29 08:02:50 2021 @@ -1,5 +1,5 @@ #! /bin/sh -# $NetBSD: msg_xlat.sh,v 1.2 2020/11/05 19:13:21 christos Exp $ +# $NetBSD: msg_xlat.sh,v 1.3 2021/06/29 08:02:50 cjep Exp $ #- # Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -37,32 +37,35 @@ usage() exit 1 } -error() { +error() +{ echo "$PROG: ERROR $@" >&2 } -count_fmtargs= +IGNORE_MISSING_TRANSLATIONS=false +count_fmtargs=false msg_defs=msg_defs.h + while getopts cd:f:i f do - case $f in - c) count_fmtargs=1;; + case "$f" in + c) count_fmtargs=true;; d) msg_defs=$OPTARG;; f) fmt_count=$OPTARG;; - i) IGNORE_MISSING_TRANSLATIONS=y;; + i) IGNORE_MISSING_TRANSLATIONS=true;; *) usage;; esac done shift $(($OPTIND - 1)) -[ "$#" = 0 ] || usage +if [ "$#" -ne 0 ]; then usage; fi -nl=" -" -msg_long="((msg)(long)" -close_paren=")" -open_brace="{" -close_brace="}" -slash="/" +nl=' +' +msg_long='((msg)(long)' +close_paren=')' +open_brace='{' +close_brace='}' +slash=/ rval=0 @@ -70,13 +73,13 @@ rval=0 exec 3<&0 # Read existing list of format arg counts -[ -n "$fmt_count" ] && { +if [ -n "$fmt_count" ]; then exec <$fmt_count || exit 2 while read name count do eval count_$name=\$count done -} +fi # Read header file and set up map of message names to numbers @@ -84,12 +87,14 @@ exec <$msg_defs || exit 2 while read define MSG_name number rest do - [ -z "$number" -o -n "$rest" ] && continue - [ "$define" = "#define" ] || continue + if [ -z "$number" ] || [ -n "$rest" ]; then continue; fi + if [ "$define" != "#define" ]; then continue; fi + name="${MSG_name#MSG_}" - [ "$name" = "${MSG_name}" ] && continue + if [ "$name" = "${MSG_name}" ]; then continue; fi + msg_number="${number#$msg_long}" - [ "$msg_number" = "$number" ] && continue + if [ "$msg_number" = "$number" ]; then continue; fi msg_number="${msg_number%$close_paren}" eval $MSG_name=$msg_number @@ -105,101 +110,106 @@ exec <&3 3<&- name= msg= -OIFS="$IFS" while IFS= read -r line do - [ -z "$name" ] && { + if [ -z "$name" ]; then IFS=" " set -- $line - [ "$1" = message ] || continue + if [ "$1" != message ]; then continue; fi name="$2" eval number=\$MSG_$name - [ -z "$number" ] && { + if [ -z "$number" ]; then error "unknown message \"$name\"" - [ -n "$IGNORE_MISSING_TRANSLATIONS" ] || rval=1 + $IGNORE_MISSING_TRANSLATIONS || rval=1 number=unknown - } + fi l=${line#*$open_brace} - [ "$l" = "$line" ] && continue + if [ "$l" = "$line" ]; then continue; fi line="{$l" - } - [ -z "$msg" ] && { - l="${line#$open_brace}" - [ "$l" = "$line" ] && continue + fi + if [ -z "$msg" ]; then + l=${line#$open_brace} + if [ "$l" = "$line" ]; then continue; fi msg="$line" - } || msg="$msg$nl$line" - m="${msg%$close_brace}" - [ "$m" = "$msg" ] && { + else + msg="$msg$nl$line" + fi + m=${msg%$close_brace} + if [ "$m" = "$msg" ]; then # Allow <tab>*/* comment */ (eg XXX translate) - m="${msg%%$close_brace*$slash[*]*[*]$slash}" - [ "$m" = "$msg" ] && - continue - } + m=${msg%%$close_brace*$slash[*]*[*]$slash} + if [ "$m" = "$msg" ]; then continue; fi + fi # We need the %b to expand the \n that exist in the message file - msg="$(printf "%bz" "${m#$open_brace}")" - msg="${msg%z}" + msg=$(printf %bz "${m#$open_brace}") + msg=${msg%z} eval old=\"\$MSGTEXT_$number\" - [ -n "$old" -a "$number" != unknown ] && { + if [ -n "$old" ] && [ "$number" != unknown ]; then error "Two translations for message \"$name\"" - [ -n "$IGNORE_MISSING_TRANSLATIONS" ] || rval=1 - } + $IGNORE_MISSING_TRANSLATIONS || rval=1 + fi eval MSGTEXT_$number=\"\${msg}\" # echo $number $msg sv_name="$name" sv_msg="$msg" name= msg= - [ -z "$count_fmtargs" -a -z "$fmt_count" ] && continue + if ! $count_fmtargs && [ -z "$fmt_count" ]; then continue; fi + + IFS=% + set -- $sv_msg - IFS='%' - set -- - x$sv_msg - [ -n "$count_fmtargs" ] && { + # For our purposes, empty messages are the same as words without % + if [ $# -eq 0 ]; then set -- x; fi + + if $count_fmtargs; then echo $number $# continue - } + fi eval count=\${count_$number:-unknown} - [ "$count" = $# ] || { + if [ "$count" -ne $# ]; then error "Wrong number of format specifiers in \"$sv_name\", got $#, expected $count" - [ -n "$IGNORE_MISSING_TRANSLATIONS" ] || rval=1 - } + $IGNORE_MISSING_TRANSLATIONS || rval=1 + fi done +unset IFS -[ -n "$count_fmtargs" ] && exit $rval +if $count_fmtargs; then exit $rval; fi # Output the total number of messages and the offset of each in the file. # Use ascii numbers because generating target-ordered binary numbers # is just a smidgen tricky in the shell. -offset="$(( 8 + $last_msg_number * 8 + 8 ))" +offset=$(( 8 + $last_msg_number * 8 + 8 )) printf 'MSGTXTS\0%-7d\0' $last_msg_number msgnum=0 while - msgnum="$(( $msgnum + 1 ))" + msgnum=$(( $msgnum + 1 )) [ "$msgnum" -le "$last_msg_number" ] do eval msg=\${MSGTEXT_$msgnum} - [ -z "$msg" ] && { + if [ -z "$msg" ]; then eval error "No translation for message \$MSGNUM_$msgnum" printf '%-7d\0' 0 - [ -n "$IGNORE_MISSING_TRANSLATIONS" ] || rval=1 + $IGNORE_MISSING_TRANSLATIONS || rval=1 continue - } + fi printf '%-7d\0' $offset - offset="$(( $offset + ${#msg} + 1 ))" + offset=$(( $offset + ${#msg} + 1 )) done # Finally output and null terminate the messages. msgnum=0 while - msgnum="$(( $msgnum + 1 ))" + msgnum=$(( $msgnum + 1 )) [ "$msgnum" -le "$last_msg_number" ] do eval msg=\${MSGTEXT_$msgnum} - [ -z "$msg" ] && continue + if [ -z "$msg" ]; then continue; fi printf '%s\0' $msg done