# pro-archman # src/control.sh # Functions for parsing control files. # # Copyright (C) 2012, 2013 Patrick McDermott # # This file is part of the ProteanOS Archive Manager. # # The ProteanOS Archive Manager 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 3 of the # License, or (at your option) any later version. # # The ProteanOS Archive Manager 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 the ProteanOS Archive Manager. If not, see # . control_file= control_line_nr= parse_control() { control_file="${1}" local field_cb="${2}" local req_fields="${3}" local opt_fields="${4}" shift 4 local all_fields= local got_fields= local line= local name= local value= 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}" shift 1 local file_info= 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 }