From acb7fb29fd8d47a9f6fa6acc0dfead5dec07a26f Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sun, 14 Jul 2013 16:31:13 -0400 Subject: parse_control(): New function. This function is ported from libopkbuild. --- diff --git a/lib/control.sh b/lib/control.sh new file mode 100644 index 0000000..dbbcc96 --- /dev/null +++ b/lib/control.sh @@ -0,0 +1,136 @@ +# pro-archman +# lib/control.sh +# Functions for parsing control files. +# +# Copyright (C) 2012, 2013 Patrick "P. J." McDermott +# +# 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 . + +[ "x${_CONTROL_SM+set}" = 'xset' ] && return 0 +_CONTROL_SM=1 + +use output +use locale + +control_file= +control_line_nr= + +parse_control() +{ + local field_cb="${2}" + local req_fields="${3}" + local opt_fields="${4}" + local all_fields= + local got_fields= + local line= + local name= + local value= + + control_file="${1}" + control_line_nr=0 + + req_fields="$(printf '%s\n' ${req_fields})" + opt_fields="$(printf '%s\n' ${opt_fields})" + all_fields="${LF}${req_fields}${LF}${opt_fields}${LF}" + got_fields="${LF}" + + while IFS='' read -r line; do + control_line_nr=$(($control_line_nr + 1)) + if [ "x$(echo ${line})" = 'x' ]; then + parse_control_error 'control_empty_line' + elif [ "x${line#\#}" != "x${line}" ]; then + # Comment. + : + elif [ "x${line# }" = "x${line}" ]; then + # "Name: Value" line. + if [ "x${name}" != 'x' ]; then + if ! "${field_cb}" "${name}" "${value}"; then + return 0 + fi + fi + name="${line%%:*}" + value="${line#*:}" + value="${value# }" + if [ "x${name}" = 'x' -o "x${name}" = "x${line}" ]; then + parse_control_error 'control_bad_nv' + continue + fi + if [ "x${req_fields}" != 'x' ]; then + if [ "x${all_fields%${LF}${name}${LF}*}" = \ + "x${all_fields}" ]; then + # Unknown field. + parse_control_error \ + 'control_unknown_field' \ + "${name}" + else + # Remove field from list of required + # fields. + req_fields="$(printf '%s' \ + "${req_fields}" | \ + grep -Fv "${name}")" + fi + fi + if [ "x${got_fields%${LF}${name}${LF}*}" != \ + "x${got_fields}" ]; then + # Duplicate field. + parse_control_error 'control_duplicate_field' \ + "${name}" + else + got_fields="${got_fields}${name}${LF}" + fi + else + # Continuation line. + if [ "x${name}" = 'x' ]; then + # Expecting a "Name: Value" line. + parse_control_error 'control_found_continuation' + continue + fi + value="${value}${LF}${line# }" + fi + done <<-EOF + $(cat "${control_file}") + EOF + + if [ "x${name}" != 'x' ]; then + if ! "${field_cb}" "${name}" "${value}"; then + return 0 + fi + fi + + if [ "x${req_fields}" != 'x' ]; then + req_fields="$(printf "%s$(get_msg 'list_item_separator')" \ + ${req_fields})" + parse_control_error 'control_missing_fields' "${req_fields}" + fi + + return 0 +} + +parse_control_error() +{ + local msgid="${1}" + local file_info + shift 1 + + if [ ${control_line_nr} -eq 0 ]; then + file_info="$(printf '%20s:' "${control_file}")" + else + file_info="$(printf '%20s(l%d):' "${control_file}" \ + "${control_line_nr}")" + fi + + warn "${file_info} $(get_msg "${msgid}")" "${@}" + + return 0 +} diff --git a/lib/local.mk b/lib/local.mk index 2229f8c..b7c5377 100644 --- a/lib/local.mk +++ b/lib/local.mk @@ -4,4 +4,5 @@ pkglib_srcs = \ lib/output.sh \ lib/locale.sh \ + lib/control.sh \ lib/cmd.sh diff --git a/locale/en_US/pro_archman.sh b/locale/en_US/pro_archman.sh index 4e0acc6..bf4e831 100644 --- a/locale/en_US/pro_archman.sh +++ b/locale/en_US/pro_archman.sh @@ -25,3 +25,12 @@ msg_pro_archman_cmd_help_summary='print this help message' msg_pro_archman_cmd_help_usage='[]' msg_pro_archman_cmd_include_summary='include packages described in changes files' msg_pro_archman_cmd_include_usage=' ...' + +# lib/control.sh +msg_pro_archman_control_empty_line='empty line' +msg_pro_archman_control_bad_nv='badly formatted control field' +msg_pro_archman_control_unknown_field='unrecognized field "%s"' +msg_pro_archman_control_duplicate_field='duplicate field "%s"' +msg_pro_archman_control_found_contination='found continuation line where expected start of field' +msg_pro_archman_list_item_separator=', ' +msg_pro_archman_control_missing_fields='missing fields: %s' -- cgit v0.9.1