summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pjm@nac.net>2013-07-14 16:31:13 (EDT)
committer P. J. McDermott <pjm@nac.net>2013-07-14 16:31:13 (EDT)
commitacb7fb29fd8d47a9f6fa6acc0dfead5dec07a26f (patch)
tree5925bcc859656767b0ecb3d603d20b43d47926bb
parent83fe0314a62b8f80e3095dcd6a0c0e465b7dcbea (diff)
parse_control(): New function.
This function is ported from libopkbuild.
-rw-r--r--lib/control.sh136
-rw-r--r--lib/local.mk1
-rw-r--r--locale/en_US/pro_archman.sh9
3 files changed, 146 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+
+[ "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='[<command>]'
msg_pro_archman_cmd_include_summary='include packages described in changes files'
msg_pro_archman_cmd_include_usage='<changes> ...'
+
+# 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'