#!/bin/bash
# pck-create -- plugin for autospec
# Copyright (C) 2004-2015 Davide Madrisan <davide.madrisan@gmail.com>

[ -z "$BASH" ] || [ ${BASH_VERSION:0:1} -lt 3 ] &&
 { echo $"this script requires bash version 3 or better" >&2 && exit 1; }

me=(${0##*/} "1.45" "Thu Apr 23 2026")

[ -r /usr/share/autospec/lib/libmsgmng.lib ] ||
 { echo "$me: "$"library not found"": /usr/share/autospec/lib/libmsgmng.lib" 1>&2
   exit 1; }
. /usr/share/autospec/lib/libmsgmng.lib

[ -r /usr/share/autospec/lib/libnetwork.lib ] ||
 { echo "$me: "$"library not found"": /usr/share/autospec/lib/libnetwork.lib" 1>&2
   exit 1; }
. /usr/share/autospec/lib/libnetwork.lib

# set default variables
# output verbosity
let "verbose = 1"

spec_type=standard
spec_first_release=1
spec_run_ldconfig="/sbin/ldconfig"
spec_changelog_date="$(LC_ALL="C" date "+%a %b %d %Y")"
spec_changelog_comment="package created by autospec"

spec_default_summary="..."
spec_default_group="..."
spec_default_url="..."
spec_default_license="..."
spec_default_source="..."
spec_default_description="..."
spec_default_description_devel="..."
spec_setup_macro=

spec_cmd_configure_autotools="%configure"
spec_cmd_make_autotools="%make"
spec_cmd_makeinstall_autotools="%makeinstall"

spec_cmd_configure_autogen="./autogen.sh\n%configure"
spec_cmd_make_autogen="%make"
spec_cmd_makeinstall_autogen="%makeinstall"

spec_cmd_configure_cmake="%cmake"
spec_cmd_make_cmake="%cmake_build"
spec_cmd_makeinstall_cmake="%cmake_install"

spec_cmd_configure_scons=""
spec_cmd_make_scons="scons"
spec_cmd_makeinstall_scons="scons install DESTDIR=%{buildroot}/<ADDME>"

spec_cmd_configure_makefileonly=""
spec_cmd_make_makefileonly="%make"
spec_cmd_makeinstall_makefileonly="%makeinstall"

spec_cmd_configure_default=""
spec_cmd_make_default=""
spec_cmd_makeinstall_default=""

spec_cmd_configure_meson="%meson"
spec_cmd_make_meson="%meson_build"
spec_cmd_makeinstall_meson="%meson_install"

[ "$perl_Makefile_generator" ] || perl_Makefile_generator="Makefile.PL"

preserve_dot_git=0

# load the configuration file(s)
[ -r /usr/share/autospec/lib/libcfg.lib ] ||
 { echo "$me: "$"library not found"": /usr/share/autospec/lib/libcfg.lib" 1>&2
   exit 1; }
. /usr/share/autospec/lib/libcfg.lib

[ -r /usr/share/autospec/lib/libtranslate.lib ] ||
 { echo "$me: "$"library not found"": /usr/share/autospec/lib/libtranslate.lib" 1>&2
   exit 1; }
. /usr/share/autospec/lib/libtranslate.lib

function copying() {
   echo "\
"$"This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2 as published by the
Free Software Foundation.  There is NO warranty; not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE."
}

function version() {
   echo "\
${me[0]} ${me[1]}
Copyright (C) 2004-2013 Davide Madrisan <davide.madrisan@gmail.com>"
}

# $1: optional exit code (default is '1')
function usage() {
   version
   echo "\
"$"Try to create a specfile for the specified source archive"".

"$"Usage"":
 autospec -s <source-archive> [-n <name>] [-v <ver>] [-t <type>] \\
    [-o <outfile>] [--changelog \""$"message""\"] [<"$"git-opts"">] \\
    [--packager-fullname \"Full Name\" ] [--packager-email \"email@domain\" ] \\
    [-C <conf_file>]

"$"where the above options mean"":
 -s, --source       "$"Try to create a specfile for the specified source archive""
 -n, --pck-name     "$"Name of the package (default: taken from <source-archive> name)""
 -v, --pck-version  "$"Version of the package (default: taken from <source-archive> name)""
 -t, --type         "$"Typology of the specfile to be created""
                      standard        : "$"standard specfile (default)""
                      ghc             : "$"specfile for ghc packages""
                      gnome           : "$"specfile for gnome packages""
                      kde5            : "$"specfile for kde5 packages""
                      library         : "$"specfile for common library packages""
                      ocaml-libs      : "$"specfile for OCaml library packages""
                      perl            : "$"specfile for single-package perl modules""
                      python          : "$"specfile for python modules""
                      standard-daemon : "$"standard specfile for system/network services""
                      web             : "$"specfile for web packages""
 -o, --output       "$"Redirect the output to the file <outfile>""
     --changelog    "$"Set change information for the package""
     --packager-fullname
                    "$"Override packager full name""
     --packager-email
                    "$"Override packager email""
     --git-branch   "$"Specify a git branch or tag and (optionally) a commit by appending @commit_id""
 --preserve-dot-git "$"Do not remove git files""
     --colors       "$"Select the theme to be used for the colorized output""
 -C, --config       "$"Use an alternate user configuration file"" <conf_file>""
                    "$"Default files:"" $default_cfg_strlist""
                    "$"Default user files:"" $default_cfg_user_strlist""

"$"Operation modes"":
 -h, --help         "$"Print this help, then exit""
 -V, --version      "$"Print version number, then exit""
 -q, --quiet        "$"Run in quiet mode""
 -D, --debug        "$"Run in debugging mode (very verbose output)""

"$"Samples"":
 autospec -s ~/software/autospec-1.45.tar.bz2 -t standard -o autospec.spec
 autospec -s http://ftp.openmamba.org/devel/tools/autospec/autospec-1.45.tar.bz2
 autospec -s autospec-1.45.tar.bz2 --changelog \"First build\"
 autospec -s git://anongit.freedesktop.org/gstreamer/gst-omx \\
    --git-branch=\"raspberry\" --preserve-dot-git -o gst-omx.spec

"$"Report bugs to <davide.madrisan@gmail.com>."

   exit ${1:-1}
}

case $1 in
   --autospec-args-file*)
      if [[ "$1" =~ = ]]; then
         argsfile=`echo $1 | sed 's/^--autospec-args-file=//'`
      else
         argsfile=$2
      fi
      [ -r "$argsfile" ] || notify.error $"cannot read"": \`$argsfile'"
      . $argsfile && rm -f $argsfile
   ;;
esac

for arg in $@; do
   case $arg in
   -h|--help) usage 0 ;;
   -V|--version) version; echo; copying; exit 0 ;;
   esac
done

# the user configuration file for autospec is required
config.check4user

exec_options=`LC_ALL=C getopt \
   -o s:n:v:t:o:C:DqrhV \
   --long \
source:,pck-name:,pck-version:,type:,output:,changelog:,\
packager-fullname:,packager-email:,\
git-branch:,preserve-dot-git,\
colors:,config:,debug,quiet,help,version,\
frontend_opts: \
   -n "$me" -- "$@"`
[ $? = 0 ] || exit 1

notify.debug "[ ${0} ${exec_options} ]\n"
eval set -- "$exec_options"

cmdline_vars=()

while :; do
   case $1 in
      -s|--source)
         [ "$2" = "--help" ] && usage 0
         [ "$2" = "-h" ] && usage 0
         pck_tarball=$2; shift
         ;;
      -n|--pck-name)
         pck_name=$2; shift ;;
      -v|--pck-version)
         shift; pck_version=$1 ;;
      -t|--type)
         spec_type=$2; shift ;;
      -o|--output)
         outfile=$2; shift ;;
      --changelog)
         spec_changelog_comment="$2"; shift ;;
      --packager-fullname)
         packager_fullname="$2"; shift
         cmdline_vars[${#cmdline_vars[*]}]="packager_fullname=\"$packager_fullname\"" ;;
      --packager-email)
         packager_email="$2"; shift
         cmdline_vars[${#cmdline_vars[*]}]="packager_email=\"$packager_email\"" ;;
      --git-branch)
         git_branch=$2; shift ;;
      --preserve-dot-git)
         preserve_dot_git=1 ;;
      -D|--debug)
         let "verbose = 2" ;;
      -q|--quiet)
         let "verbose = 0" ;;
      --colors)
         color_scheme="$2"; shift
         notify.debug "color_scheme = \"$color_scheme\""
         cmdline_vars[${#cmdline_vars[*]}]="color_scheme=\"$color_scheme\""
      ;;
      -C|--config)
         cfgfile_list_cmdline="$2"; shift
         notify.debug "cfgfile_list_cmdline = \"$cfgfile_list_cmdline\""
         cmdline_vars[${#cmdline_vars[*]}]="\
cfgfile_list_cmdline=\"$cfgfile_list_cmdline\""
      ;;
      -h|--help)
         usage 0 ;;
      -V|--version)
         version; echo; copying; exit 0 ;;
      --) shift; break ;;
      *) notify.error $"unrecognized option"" -- \`$1'" ;;
   esac
   shift
done

for arg in $@; do
   notify.error $"unrecognized option"" -- \`$arg'"
done

cfg_load_files "$cfgfile_list_cmdline"

# otherwrite the configuration variables by set them again using
# the values defined via the commanline options
for i in ${!cmdline_vars[@]}; do
   notify.debug "eval \"${cmdline_vars[i]}\""
   eval "${cmdline_vars[i]}"
done

notify.enable_colors "$color_scheme"

function specfile.ckeck_defvalues() {
   # $1: name of the specfile
   local specfile="$1" currvalue

   check_values=(
      "Summary"            spec_default_summary
      "Group"              spec_default_group
      "URL"                spec_default_url
      "Source"             spec_default_source
      "License"            spec_default_license
      "%description"       spec_default_description
      "%description devel" spec_default_description_devel
   )

   for i in `seq 1 1 $(( ${#check_values[@]} / 2 ))`; do
      id="${check_values[($i-1)*2]}"
      value="${check_values[($i-1)*2+1]}"
      case "$id" in
         # when id begins by a '%' character, the two lines below the id must
         # be taken into account (three lines: the line containing the id, the
         # following one and the following (blank) line)
         %*) sed -n "/^$id$/,/^$/p" $specfile | sed 3q | grep -q "${!value}"
             [ $? -eq 0 ] && notify.warning $"\
remember to modify the value for \`${NOTE}$id${NORM}'" ;;
          *) currvalue="\
$(sed -n "/%description/q;{/^[ \t]*$id[ \t]*:[ \t]*/{s,.*:[ \t]*,,p}}" $specfile)"
notify.debug "[[ \"$currvalue\" =~ \"${!value}\" ]]"
             [[ "$currvalue" =~ "${!value}" ]] && notify.warning $"\
remember to modify the value for \`${NOTE}$id${NORM}'" ;;
      esac
   done
}

function template.expand() {
   local OPTIONS=`LC_ALL=C getopt \
   -o t:T:n:v:s:l:S:b: \
   --long template:,type:,pckname:,pckversion:,setupmacro:,summary:,license:,\
source:,source-comment:,standard-docs:,standard-docs-devel:,\
build-technology:,i18n:,icons-mimetypes:,infopages:,manpages:,\
pck-devel:,pck-library:,pck-apidocs:,pck-tools:,\
shared-libraries:,debug-package:,\
   -n "${0}" -- "$@"`
[ $? = 0 ] || exit 1

   notify.debug "$FUNCNAME: ${OPTIONS}"
   eval set -- "${OPTIONS}"

   local templatefile spec_type
   local pck_name pck_version
   local pck_name_devel
   local pck_name_tools
   local pck_name_apidocs
   local spec_setup_macro
   local spec_summary="$spec_default_summary"
   local spec_license="$spec_default_license"
   local spec_source
   local spec_source_comment
   local standard_docs
   local standard_docs_devel
   local build_technology
   local buildrequires_buildtool

   local i18n="0"
   local icons_mimetypes="0"
   local infopages="0"
   local manpages="0"
   local pck_devel="0"
   local pck_library="0"
   local pck_apidocs="0"
   local pck_tools="0"
   local shared_libraries="0"
   local debug_package="0"

   while :; do
      case $1 in
      -t|--template)
         templatefile=$2; shift ;;
      -T|--type)
         spec_type=$2; shift ;;
      -n|--pckname)
         pck_name=$2; shift ;;
      -v|--pckversion)
         pck_version=$2; shift ;;
      -s|--setupmacro)
         spec_setup_macro="$2"; shift ;;
      --summary)
         spec_summary="$2"; shift ;;
      -l|--license)
         spec_license="$2"; shift ;;
      -S|--source)
         spec_source="$2"; shift ;;
      --source-comment)
         spec_source_comment="$2"; shift ;;      
      --standard-docs)
         standard_docs="$2"; shift ;;
      --standard-docs-devel)
         standard_docs_devel="$2"; shift ;;
      -b|--build-technology)
         build_technology="$2"; shift ;;
      --i18n)
         i18n="$2"; shift ;;
      --icons-mimetypes)
         icons_mimetypes="$2"; shift ;;
      --infopages)
         infopages="$2"; shift ;;
      --manpages)
         manpages="$2"; shift ;;
      --pck-devel)
         pck_devel="$2"; shift ;;
      --pck-library)
         pck_library="$2"; shift ;;
      --pck-apidocs)
         pck_apidocs="$2"; shift ;;
      --pck-tools)
         pck_tools="$2"; shift ;;
      --shared-libraries)
         shared_libraries="$2"; shift ;;
      --debug-package)
         debug_package="$2"; shift ;;
      --) shift; break ;;
      *) notify.error $"unrecognized option"" -- \`$1'" ;;
      esac
      shift
   done

   notify.debug "$FUNCNAME: build_technology = $build_technology"

   local spec_cmd_configure
   local spec_cmd_make
   local spec_cmd_makeinstall

   case "$build_technology" in
   cmake)
      spec_cmd_configure="$spec_cmd_configure_cmake"
      spec_cmd_make="$spec_cmd_make_cmake"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_cmake"
      buildrequires_buildtool="cmake"
   ;;
   autotools)
      spec_cmd_configure="$spec_cmd_configure_autotools"
      spec_cmd_make="$spec_cmd_make_autotools"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_autotools"
   ;;
   autogen)
      spec_cmd_configure="$spec_cmd_configure_autogen"
      spec_cmd_make="$spec_cmd_make_autogen"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_autogen"
   ;;
   makefile)
      spec_cmd_configure="$spec_cmd_configure_makefileonly"
      spec_cmd_make="$spec_cmd_make_makefileonly"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_makefileonly"
   ;;
   scons)
      spec_cmd_configure="$spec_cmd_configure_scons"
      spec_cmd_make="$spec_cmd_make_scons"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_scons"
      buildrequires_buildtool="scons"
   ;;
   meson)
      spec_cmd_configure="$spec_cmd_configure_meson"
      spec_cmd_make="$spec_cmd_make_meson"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_meson"
      buildrequires_buildtool="meson"
   ;;
   unknown)
      notify.warning $"unknown build techonology"
      spec_cmd_configure="$spec_cmd_configure_default"
      spec_cmd_make="$spec_cmd_make_default"
      spec_cmd_makeinstall="$spec_cmd_makeinstall_default"
   ;;
   esac
   notify.debug "$FUNCNAME: spec_cmd_configure   = \"$spec_cmd_configure\""
   notify.debug "$FUNCNAME: spec_cmd_make        = \"$spec_cmd_make\""
   notify.debug "$FUNCNAME: spec_cmd_makeinstall = \"$spec_cmd_makeinstall\""
   notify.debug "\
$FUNCNAME: buildrequires_buildtool = \"$buildrequires_buildtool\""

   [ -r "$templatefile" ] || notify.error $"file not found"": $templatefile"

   local pck_name_tail="<FIXME>"
   case "$pck_name" in *-*) pck_name_tail="${pck_name#*-}" ;; esac
   notify.debug "$FUNCNAME: pck_name_tail = \"$pck_name_tail\""

   local currvar line if_value if_level=0
   # FIXME: at most two nested @if statements are supported
   if_value[0]='N/A'; if_value[1]='1'; if_value[2]='1';
   local template_linenum=0
   while read line; do
      template_linenum=$(($template_linenum + 1))
      case "$line" in
      @if:*)
         [ $if_level -ge 2 ] && notify.error "\
$spec_type ("$"line""#$template_linenum): "$"too many nested @if blocks"
         if_level=$(($if_level + 1))
         currvar="$(echo "$line" | sed "s,@if:\([^ \t]*\).*,\1,")"
         [[ "${!currvar}" = 1 || \
           ( -n "${!currvar}" && "${!currvar}" != 0 ) ]] || \
            if_value[$if_level]='0'
         notify.debug "\
$FUNCNAME: @if:$currvar lev:$if_level val:${if_value[$if_level]})"
         continue
      ;;
      @else:*)
         [ "$if_level" = '0' ] && notify.error "\
$spec_type ("$"line""#$template_linenum): "$"@else without @if statement"
         if_value[$if_level]=$(( ! ${if_value[$if_level]} ))
         notify.debug "\
$FUNCNAME: @else:$currvar lev:$if_level val:${if_value[$if_level]})"
         continue
      ;;
      @fi:*)
         [ "$if_level" = '0' ] && notify.error "\
$spec_type ("$"line""#$template_linenum): "$"@fi without @if statement"
         if_value[$if_level]='1'
         if_level=$(($if_level - 1))
         notify.debug "\
$FUNCNAME: @fi:$currvar lev:$if_level val:${if_value[$if_level]})"
         continue
      ;;
      @configure@*)
         [ "${if_value[1]}" = '1' -a ${if_value[2]} = '1' ] || continue
         [ "$spec_cmd_configure" ] && echo "$line" | \
            sed "s,@configure@,$spec_cmd_configure,"
      ;;      
      *) [ "${if_value[1]}" = '1' -a ${if_value[2]} = '1' ] &&
            echo "$line" | sed "\
s,@DISTRO@,${DISTRO:-?DISTRO?},
s,@DISTRO_rpm@,${DISTRO_rpm:-?DISTRO_rpm?},
s,@VENDOR@,${VENDOR:-?VENDOR?},
s,@packager_fullname@,${packager_fullname:-?packager_fullname?},
s,@packager_email@,${packager_email:-?packager_email?},
s,@rpm_default_buildroot@,${rpm_default_buildroot:-?rpm_default_buildroot?},
s,@pck_name@,$pck_name,
s,@pck_name_tail@,$pck_name_tail,
s,@pck_version@,$pck_version,
s,@spec_first_release@,${spec_first_release:-1},
s,@spec_run_ldconfig@,$spec_run_ldconfig,
s,^\(%setup.*\),${spec_setup_macro},
/^[ \t]*Summary[ \t]*:[ \t]*\.\.\..*$/{
   s,\(^[ \t]*Summary[ \t]*:[ \t]*\).*,\1${spec_summary},}
/^[ \t]*License[ \t]*:[ \t]*\.\.\.$/{
   s,\(^[ \t]*License[ \t]*:[ \t]*\).*,\1${spec_license},}
s,^\([ \t]*Source[ \t]*:[ \t]*\).*,\
${spec_source_comment:+$spec_source_comment\n}\1${spec_source},
s,@make@,$spec_cmd_make,
s,@makeinstall@,$spec_cmd_makeinstall,
s,@build_tool@,$buildrequires_buildtool,
s,@standard_docs@,${standard_docs:+%doc $standard_docs},
s,@standard_docs_devel@,${standard_docs_devel:+%doc $standard_docs_devel},
s,@spec_changelog_date@,$spec_changelog_date,
s,@spec_changelog_comment@,$spec_changelog_comment,
"
#/$spec_i18n/{ # if spec_i18n
#   s,@i18n@\([^@]*\)@.*,\1,;be;}   #select 1st arg
#:e s,@i18n@[^@]*@\([^@]*\)[@]*,\1, #select 2nd arg
   ;;
   esac
   done < $templatefile | \
      sed '/^$/{n;/^$/d}' # remove duplicate blank lines
}

# specfile.create()
# Parameters:
#   $1 : try to create a specfile from this tarball
#   $2 : source (with or without path; can be a remote url)
#   $3 : package name
#   $4 : package version
#   $5 : output file
# Description:
#   Create an initial specfile to help packaging activities
#

function specfile.create() {
   notify.debug "[ ${0}${exec_options} ]\n"

   # check if all the needed tools are available
   # note: uncompress has been removed from the mandatory list
   for tool in chmod find grep mktemp sed bunzip2 gunzip unzip; do
      [ "$(type -p $tool)" ] ||
         notify.error $"utility not found"": \`$tool'"
   done

   local spec_type="$1"

   # collect informations from the tarball name and the source files
   #  1.  pck_tarball, pck_name , pck_version
   #  2.  pck_rootdir (where the package has been decompressed) --> pck_rootdir_4spec

   # 'pck_tarball' = absolute path of '$1'
   local pck_tarball
   local pck_name
   local pck_version="$4"

   case "$2" in
      git://*|http://*.git|https://*.git)
         git.create_tarball \
            --pck-version="$pck_version" \
            --git-branch="$git_branch" \
            --preserve-dot-git="$preserve_dot_git" \
            --destdir="$source_dir" "$2"

         spec_source="$2/${git_branch:-master}/$spec_source"
         pck_tarball="$source_dir/${spec_source##*/}"
      ;;
      http://*|https://*|ftp://*)
         pck_tarball="${2##*/}"
         spec_source="$2"

         curl.download \
--options "$curl_options" \
${proxy:+--proxy $proxy} ${proxy_user:+--proxy-user $proxy_user} \
--exit-on-err --destdir="$source_dir" "$spec_source"

         pck_tarball=$source_dir/$pck_tarball
      ;;
      *://*)
         notify.error $"unsupported protocol"": \`${2//\:*}'"
      ;;
      /*) pck_tarball="$2" ;;
      *) pck_tarball="$(pwd)/$2" ;;
   esac
   notify.debug "$FUNCNAME: pck_tarball = $pck_tarball"
   notify.debug "$FUNCNAME: spec_source = $spec_source"
   notify.debug "$FUNCNAME: spec_source_comment = $spec_source_comment"

   [ "$pck_tarball" ] || notify.error $"missing tarball name"

   [ -e $pck_tarball ] ||
      notify.error $"cannot find the package $pck_tarball"

   # get the package name from the tarball name
   [ "$pck_name" ] || pck_name=${3:-`echo $pck_tarball | sed -n "\
      s/.*\///  # remove directory name, if any
      s/\.[^0-9].*//  # remove trailing stuff (.tar.gz, ...)
      /-[0-9]*/{s/-[0-9].*//p;q}  # <pck_name>-<pck_ver>
      /[^-\.][0-9]\./{s/\(.*[^-\.]\)[0-9]\..*/\1/p;q}  # <pck_name><pck_ver>
      # <pck_name> (no version, but <pck_name> can end with numbers)
      /^[^0-9]*[0-9]*$/p"`}
   notify.debug "pck_name = \"$pck_name\""
   [ "$pck_name" ] ||
      notify.error $"cannot get the package name, use the \`-n' option"

   [ "$pck_version" ] || pck_version=${4:-`echo $pck_tarball | sed -n "\
      /[0-9]/!q  # return nothing if no number is found in the package name
      s,.*/,,  # remove directory name, if any
      s/\.[^0-9].*//  # remove trailing stuff (.tar.gz, ...)
      /-[0-9]*/{s/.*-\([0-9]*.*\)/\1/p;q}  # <pck_name>-<pck_ver>
      /[^-\.][0-9]\./{s/.*[^-\.]\([0-9]\..*\)/\1/p;q}  # <pck_name><pck_ver>
      # <pck_name> (no version, but <pck_name> can end with numbers)
      /^[^0-9]*[0-9]*$/q"`}
   notify.debug "$FUNCNAME: pck_version = \"$pck_version\""
   [ "$pck_version" ] ||
      notify.error $"cannot get the package version, use the \`-v' option"

   local outfile="$5"
   if [ "$outfile" ]; then
      notify.debug "$FUNCNAME: output file"": ${NOTE}$outfile${NORM}"
      > $outfile || notify.error $"can't create output file"" $outfile"
      # do not chmod a non-regular file (for instance /dev/null)
      [ -f "$outfile" ] && chmod ${rpm_specfile_mode:-644} $outfile
   fi

   notify.note "${NOTE}"$"generating specfile""${NORM}""...""
 * "$"source"": ${NOTE}$pck_tarball${NORM}""
 * "$"mode"": ${NOTE}$spec_type${NORM}"

   case "$spec_type" in
   ghc)
      [[ "$pck_name" =~ $ghc_module_name_structure ]] || notify.error $"\
ghc modules must have this name structure (use \`-n'):"" \
\`$ghc_module_name_structure'"
   ;;
   library)
      [[ "$pck_name" =~ $library_name_structure ]] || notify.error $"\
libraries must have this name structure (use \`-n'):"" \
\`$library_name_structure'"
   ;;
   ocaml-libs)
      [[ "$pck_name" =~ $ocaml_module_name_structure ]] || notify.error $"\
ocaml modules must have this name structure (use \`-n'):"" \
\`$ocaml_module_name_structure'"
   ;;
   perl)
      [[ "$pck_name" =~ $perl_module_name_structure ]] || notify.error $"\
perl modules must have this name structure (use \`-n'):"" \
\`$perl_module_name_structure'"
   ;;
   python)
      [[ "$pck_name" =~ $python_module_name_structure ]] || notify.error $"\
python modules must have this name structure (use \`-n'):"" \
\`$python_module_name_structure'"
   ;;
   esac

   # link fd#3 with stdout and redirect stdout to the log file
   [ "$outfile" ] && { exec 3<&1; exec 1>>$outfile; }

   local tmpdir=`mktemp -q -d -p /var/tmp -t $me.XXXXXXXX`
   [ $? -eq 0 ] ||
      notify.error $"can't create temporary directory"

   # decompress the tarball in the 'tmpdir' directory
   cp -f $pck_tarball $tmpdir
   pushd $tmpdir >/dev/null 
   case $pck_tarball in
      *.tar.gz|*.tgz)
         gunzip -c $pck_tarball | tar xf - ;;
      *.tar.bz2|*.tbz2)
         bunzip2 -c $pck_tarball | tar xf - ;;
      *.tar.Z)
         [ "$(type -p uncompress)" ] ||
            notify.error $"utility not found"": \`uncompress'"
         uncompress -c $pck_tarball | tar xf - ;;
      *.shar.gz)
         gunzip -c $pck_tarball | unshar ;;
      *.zip)
         unzip -q $pck_tarball ;;
      *.tar.xz|*.tar.lzma)
         [ "$(type -p xz)" ] ||
            notify.error $"utility not found"": \`xz'"
         xz -d --stdout $pck_tarball | tar xf - ;;
      *.tar.lz)
         [ "$(type -p lzip)" ] ||
            notify.error $"utility not found"": \`lzip'"
         lzip -cd $pck_tarball | tar -xf - ;;
      *.tar.7z)
         [ "$(type -p 7za)" ] ||
            notify.error $"utility not found"": \`7za'"
         7za x -bd $pck_tarball >/dev/null | tar xf - ;;
      *.7z)
         [ "$(type -p 7za)" ] ||
            notify.error $"utility not found"": \`7za'"
         7za x -bd $pck_tarball >/dev/null ;;
      *.jar)
         [ "$(type -p jar)" ] ||
            notify.error $"utility not found"": \`jar'"
         jar -xf $pck_tarball >/dev/null ;;
      *) notify.warning $"unsupported package compression method" ;;
   esac
   popd >/dev/null
   rm -f $tmpdir/${pck_tarball##*/}

   local pck_rootdir_dirs=(`\
LC_ALL=C find $tmpdir -mindepth 1 -maxdepth 1 -type d -printf "%f "`)
   notify.debug "$FUNCNAME: pck_rootdir_dirs = \"$pck_rootdir_dirs\""
   local pck_rootdir_files=(`\
LC_ALL=C find $tmpdir -mindepth 1 -maxdepth 1 -type f -printf "%f "`)
   notify.debug "$FUNCNAME: pck_rootdir_files = \"$pck_rootdir_files\""

   # 0. set 'spec_setup_macro'

   local pck_rootdir local pck_rootdir_4spec spec_setup_macro

   if [[ -n "$pck_rootdir_files" || \
        ( -z "$pck_rootdir_dirs" && -z "$pck_rootdir_files" ) ]]; then
      # detected a package without a root directory
      pck_rootdir=""
      pck_rootdir_4spec="-c %{name}-%{version}"
      spec_setup_macro="%setup -q $pck_rootdir_4spec"
   else
      pck_rootdir="$pck_rootdir_dirs"
      pck_rootdir_4spec=`echo $pck_rootdir | \
         sed "s/$pck_name/%{name}/;s/$pck_version/%{version}/"`
      if [ "$pck_rootdir_4spec" = "%{name}-%{version}" ]; then
         spec_setup_macro="%setup -q"
      elif [ "$pck_rootdir_4spec" = "-c %{name}-%{version}" ]; then
         spec_setup_macro="%setup -q $pck_rootdir_4spec"
      else
         spec_setup_macro="%setup -q -n $pck_rootdir_4spec"
      fi
   fi

   notify.debug "$FUNCNAME: pck_rootdir = \"$pck_rootdir\""
   notify.debug "$FUNCNAME: pck_rootdir_4spec = \"$pck_rootdir_4spec\""
   notify.debug "$FUNCNAME: spec_setup_macro = \"$spec_setup_macro\""

   # 1. preliminaries checks

   case "$spec_type" in perl) ;;
   *) [[ -e $tmpdir/$pck_rootdir/$perl_Makefile_generator ||
         -e $tmpdir/$pck_rootdir/Build.PL ]] && notify.warning $"\
looks like a perl package (use \`-t perl' if this is true)" ;;
   esac
   case "$spec_type" in python) ;;
   *) [[ -e $tmpdir/$pck_rootdir/setup.py ]] && notify.warning $"\
looks like a python module (use \`-t python' if this is true)" ;;
   esac

   # 2. set 'spec_summary'
   local spec_summary="$spec_default_summary"
   local perl_pckname_from_makefile=""
   case "$spec_type" in
   perl)
      if [ -e $tmpdir/$pck_rootdir/Makefile.PL ]; then
         # look for the variable `NAME' in Makefile.PL inside the
         # 'WriteMakefile(' ... ')' block
         perl_pckname_from_makefile=$(sed -n "\
/^[ \t]*WriteMakefile(/,/^)/{#
   /^[ \t]*[']NAME['][ \t]*=>/{#
      s|.*=>[ \t]*['\"]\(.*\)['\"].*|\1|;p}}" \
            $tmpdir/$pck_rootdir/Makefile.PL)
#         [ "$perl_pckname_from_makefile" ] ||
#            perl_pckname_from_makefile=$(sed -n "\
#/name/{s,^[ \t]*name[ \t]*['\"]*\([a-zA-Z]*\)['\"]*.*,\1,p}" \
#            $tmpdir/$pck_rootdir/Makefile.PL)
      fi
      [ -n "$perl_pckname_from_makefile" ] &&
         spec_summary="$perl_pckname_from_makefile - ..."
   ;;
   ocaml-libs)
      local metafile
      metafile=$(find $tmpdir/$pck_rootdir/ -type f -name "META" 2>/dev/null)
      [ "$metafile" ] || metafile="$(\
find $tmpdir/$pck_rootdir/ -type f -name "META.in" 2>/dev/null)"
      if [ "$metafile" ]; then
        #notify.debug "$FUNCNAME: OCaml META file found"
         while read line; do
            if [[ "$line" =~ ^description[\ \t]*=[\ \t]*\".*\"$ ]]; then
               spec_summary="... $(\
echo "$line" | sed "s|.*=[\ \t]*\"\(.*\)\"|\1|") ..."  # vim highlight need a "
               notify.debug "$FUNCNAME: spec_summary = \"$spec_summary\""
               break
            fi
           #if [[ "$line" =~ ^description[\ \t]*=[\ \t]*$ ]]; then
           #   ... FIXME
         done < $metafile
      fi 
   ;;
   esac

   # 3. set 'spec_license'
   case "$spec_type" in perl)
      spec_license="${perl_License_default:-$spec_default_license}"
   esac

   # find for package license info
   # FIXME: currently GNU GPL, LGPL, and W3C licenses are supported
   local spec_license="$spec_default_license"

   if [[ -e $tmpdir/$pck_rootdir/COPYING ]]; then
      [[ `grep -c "[ ]*GNU GENERAL PUBLIC LICENSE[ ]*" \
         $tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="GPL"
      [[ `grep -c "[ ]*GNU LIBRARY GENERAL PUBLIC LICENSE[ ]*" \
         $tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="LGPL"
      [[ `grep -c "[ ]*GNU LESSER GENERAL PUBLIC LICENSE[ ]*" \
         $tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="LGPL"
      [[ `grep -c "Copyright .* World Wide Web Consortium" \
         $tmpdir/$pck_rootdir/COPYING` -eq 0 ]] || spec_license="W3C"
   fi

   notify.debug "$FUNCNAME: spec_license (1) = \"$spec_license\""   

   # 4. set 'spec_source'

   local spec_preamble_tarball=`echo "${pck_tarball##*/}" |
      sed "s,$pck_version,%{version},g"`
   local spec_preamble_source=`echo "$spec_source" |
      sed "s,$pck_version,%{version},g"`

   [ "$spec_source" ] ||
      spec_preamble_tarball="http://.../$spec_preamble_tarball"

   notify.debug "$FUNCNAME: spec_preamble_tarball = \"$spec_preamble_tarball\""
   notify.debug "$FUNCNAME: spec_preamble_source = \"$spec_preamble_source\""

   # 5. discover basic documentation and set 'spec_basic_docs'

   # standard text documentation files (see 'automake --help')
   # + some other documentation files commonly found in several packages
   local standard_docs_list='
      AUTHORS
      COPYING
      COPYING.DOC
      COPYING.LESSER
      COPYING.LIB
      CREDITS
      LICENCE
      LICENSE
      MANUAL
      THANKS'

   local standard_docs_dirlist='
      LICENSES'

   local standard_docs_devel_list='
      BACKLOG
      BUGS
      CHANGES
      ChangeLog*
      NEWS
      README*
      TODO
      WHATSNEW
      WHERE'

   local standard_docs doc currdocs currdoc
   for doc in $standard_docs_list; do
      # `ls' if used to support strings like `ChangeLog*'
      currdocs=$(cd $tmpdir/$pck_rootdir && ls $doc 2>/dev/null)
      for currdoc in $currdocs; do
         # ignore empty documentation files
         [ -s $tmpdir/$pck_rootdir/$currdoc ] &&
            standard_docs="\
${standard_docs:+$standard_docs }$currdoc"
      done
   done
   for doc in $standard_docs_dirlist; do
      currdocs=$(cd $tmpdir/$pck_rootdir && ls -d $doc 2>/dev/null)
      for currdoc in $currdocs; do
         [ -d $tmpdir/$pck_rootdir/$currdoc ] &&
            standard_docs="\
${standard_docs:+$standard_docs }$currdoc"
      done
   done
   for doc in $standard_docs_devel_list; do
      currdocs=$(cd $tmpdir/$pck_rootdir && ls $doc 2>/dev/null)
      for currdoc in $currdocs; do
         [ -s $tmpdir/$pck_rootdir/$currdoc ] &&
            standard_docs_devel="\
${standard_docs_devel:+$standard_docs_devel }$currdoc"
      done
   done

   # split the list of docs into multiple lines if necessary
   #[ "$docs" ] && docs=`echo $docs | fmt -u -w 77 | sed 's,.*,%doc &,'`

   # 6. discover build technology

   local build_techology="unknown"
   case "$spec_type" in
   perl|python)
      build_techology="$spec_type"
   ;;
   *) if [ -e $tmpdir/$pck_rootdir/meson.build ]; then
         build_techology="meson"
      elif [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ]; then
         build_techology="cmake"
      elif [ -x $tmpdir/$pck_rootdir/configure ]; then
         build_techology="autotools"
      elif [ -e $tmpdir/$pck_rootdir/Makefile -o \
             -e $tmpdir/$pck_rootdir/makefile -o \
             -e $tmpdir/$pck_rootdir/GNUmakefile ]; then
         build_techology="makefile"
      elif [ -x $tmpdir/$pck_rootdir/autogen.sh ]; then
         build_techology="autogen"
      elif [ -e $tmpdir/$pck_rootdir/SConstruct -o \
             -e $tmpdir/$pck_rootdir/Sconstruct -o \
             -e $tmpdir/$pck_rootdir/sconstruct ]; then
         build_techology="scons"
      fi
   ;;
   esac

   # 7. check for internationalization files

   local spec_i18n="0"
   # note: in the 'tar' tarball there is no 'intl' folder, so we use 'po'
   [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ -type d -name po 2>/dev/null)" ] &&
      spec_i18n="1"

   # 8. check for manpages

   local spec_manpages="0"
   [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ -name Makefile.am \
-exec grep "MANS[ ]*=" {} \; 2>/dev/null)" ] && spec_manpages="1"

   [ "$spec_manpages" = 0 ] &&
     { [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ \
-type f -name "*.[0-9]" 2>/dev/null)" ] && spec_manpages="1"; }

   # 9. check for infopages

   local spec_infopages="0"
   [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ -name Makefile.am \
-exec grep "info_TEXINFOS[ ]*=" {} \; 2>/dev/null)" ] && spec_infopages="1"
   notify.debug "$FUNCNAME: spec_infopages = $spec_infopages"

   [ "$spec_infopages" = 0 ] &&
     { [ "$(LC_ALL=C find $tmpdir/$pck_rootdir/ \
-type f -name "*.info" 2>/dev/null)" ] && spec_infopages="1"; }
   notify.debug "$FUNCNAME: spec_infopages = $spec_infopages"

   # 10. check for gtk-doc documentation

   local spec_gtk_doc="0"
   [ "$(LC_ALL=C $tmpdir/$pck_rootdir/configure --help 2>/dev/null | \
grep -e "enable-gtk-doc")" ] && {
      spec_gtk_doc="1"
      [ "$build_techology" = "autotools" ] && spec_cmd_configure="\
$spec_cmd_configure_autotools --enable-gtk-doc"
    }

   # 11. check for library packages
   local pck_library="0"
   local pck_tools="1"
   case "$spec_type" in library)
      [[ "$pck_name" =~ ^lib.* ]] ||
       { pck_library="1"; pck_tools="0"; }
   esac

   # 12. debug package
   local debug_package="0"

   # FIXME: missing support for:
   #   pkgconfig  files
   #   includedir files

   template.expand \
      --template "$templatedir/${spec_type}" \
      --type "$spec_type" \
      --pckname "$pck_name" \
      --pckversion "$pck_version" \
      --setupmacro "$spec_setup_macro" \
      --summary="$spec_summary" \
      --license "$spec_license" \
      --source "${spec_preamble_source:-$spec_preamble_tarball}" \
      --source-comment "$spec_source_comment" \
      --standard-docs "$standard_docs" \
      --standard-docs-devel "$standard_docs_devel" \
      --build-technology "$build_techology" \
      --i18n "$spec_i18n" \
      --icons-mimetypes "1" \
      --infopages "$spec_infopages" \
      --manpages "$spec_manpages" \
      --pck-apidocs "$spec_gtk_doc" \
      --pck-devel "1" \
      --pck-library "$pck_library" \
      --pck-tools "$pck_tools" \
      --shared-libraries "1" \
      --debug-package "1"

   [ "$outfile" ] && specfile.ckeck_defvalues "$outfile"

   rm -fr $tmpdir
   if [ "$outfile" ]; then
      exec 1<&3 3<&-   # restore stdout and close fd#3
      [ -f "$outfile" ] &&
         notify.note $"created specfile"": \`${NOTE}$outfile${NORM}'"
   fi
}

specfile.create \
   "$spec_type" "$pck_tarball" "$pck_name" "$pck_version" "$outfile"
