#!/bin/bash
# pck-create -- plugin for @package@
# Copyright (C) 2004-2010 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##*/} "@version@" "@date@")

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

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

# default values:
# colorized output (disabled by default)
let "colorize = 0"
# output verbosity
let "verbose = 1"
# Display all the man pages in the autogenerated specfile ("0")
# One entry per man page section ("1")
# Only one entry for all the man pages ("2")
let "man_condensed_list = 0"
# Display all the info pages in the autogenerated specfile ("0") (default)
# Only one entry for all the info pages ("1")
let "info_condensed_list = 0"
# do not use rpm variables for unix tools
let "format_unix_tools = 0"

spec_type="standard"

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

if [[ -z "$LANG" && -r /etc/sysconfig/i18n ]]; then
   . /etc/sysconfig/i18n
   [ "$LANG" ] && export LANG
fi
TEXTDOMAIN="${me[0]}"; export TEXTDOMAIN

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-2010 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 <tarball>"".

"$"Usage"":
 @frontend@ -s <tarball> [-n <name>] [-v <ver>] [-t <type>] [-o <outfile>]

"$"where the above options mean"":
 -s, --source       "$"Try to create a specfile for the specified <tarball>""
 -n, --pck-name     "$"Name of the package (default: taken from tarball name)""
 -v, --pck-version  "$"Version of the package (default: taken from tarball name)""
 -t, --type         "$"Typology of the specfile to be created""
                      standard    : "$"standard specfile (default)""
                      gnome       : "$"specfile for gnome packages""
                      kde3        : "$"specfile for kde3 packages""
                      kde4        : "$"specfile for kde4 packages""
                      library     : "$"specfile for common library packages""
                      librarytools: "$"specfile for library packages with tools""
                      perl        : "$"specfile for single-package perl modules""
                      python      : "$"specfile for python modules""
 -o, --output       "$"Redirect the output to the file <outfile>""

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

"$"Samples"":
 @frontend@ -s ~/software/@package@-@version@.tar.bz2 -t standard -o @package@.spec
 @frontend@ -s http://ftp.qilinux.it/devel/tools/@package@/@package@-@version@.tar.bz2

"$"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 @package@ is required
config.check4user

exec_options=`LANG=C getopt \
   -o s:n:v:t:o:DqrhV \
   --long \
source:,pck-name:,pck-version:,type:,output:,\
debug,quiet,colorize,help,version,\
frontend_opts: \
   -n "$me" -- "$@"`
[ $? = 0 ] || exit 1

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

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 ;;
      -D|--debug)
         let "verbose = 2" ;;
      -q|--quiet)
         let "verbose = 0" ;;
      -r|--colorize)
         let "colorize = 1" ;;
      -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

[ "$colorize" = "1" ] && notify.enable_colors

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

# specfile.create()
# Parameters:
#   $1 : try to create a specfile from this tarball
#   $2 : package name
#   $3 : package version
#   $4 : package tipology (template)
#   $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 fmt grep mktemp sed sort uniq \
bunzip2 gunzip unzip; do
      [ "$(type -p $tool)" ] ||
         notify.error $"utility not found"": \`$tool'"
   done

   # expand Makefile variables found in string '$1' looking in the
   # makefile '$2' and in the main Makefile
   # this function expand also configure variables (@var@)
   function expand.variables() {
      local str="$1"
      local am_makefile="$2"
      local token var expanded

      notify.debug "str = \"$str\", am_makefile = \"$am_makefile\""

      # expand the Makefile variables
      OIFS="$IFS"; IFS='$'
      for token in $str; do
         [ "$token" ] || continue
         var="`echo "$token" | sed 's,(,,;s,).*,,;s,{,,;s,}.*,,'`"
         token="`echo "$token" | sed 's,(,,;s,).*,,;s,}.*,},'`"
         unset expanded
         [[ -n "$am_makefile" && -e "$am_makefile" ]] &&
            expanded=`sed -n ":a
               /\\\\$/N;s/\\\\\n//;ta
               /^[ ]*${var//\//\\/}[ ]*=/{s,.*=[ ]*,,p}" $am_makefile`
         if [ "$expanded" ]; then
            str="`echo "$str" | \
               sed "s,\\$($var),$expanded,g;
                    s,\\${$var},$expanded,g"`"
         else
            # try to find a value looking in the main Makefile
            [[ -e $tmpdir/$pck_rootdir/Makefile.in ]] &&
               expanded=`sed -n ":a
                  /\\\\$/N;s/\\\\\n//;ta
                  /^[ ]*${var//\//\\/}[ ]*=/{s,.*=[ ]*,,p}" \
                  $tmpdir/$pck_rootdir/Makefile.in`
            [[ "$expanded" ]] && str="`echo "$str" | \
               sed "s,\\$($var),$expanded,g;
                    s,\\${$var},$expanded,g"`"
         fi
         [[ "$expanded" ]] &&
            notify.debug "\
   \"$token\" == \"$expanded\" (${am_makefile:-Makefile.in})" ||
            notify.debug "   \"$token\" == <not found>"
         notify.debug "   --> str = \"$str\""
      done
      IFS="$OIFS"

      # expand the configure variables
      OIFS="$IFS"; IFS='@'
      case "$str" in
      *@*@*)
         if [[ -x $tmpdir/$pck_rootdir/configure ]]; then
            for token in ${str%@*}; do
               [[ "$token" ]] || continue
               notify.debug "   token = \"$token\""
               # note: if there are two or more matching lines,
               # the first is choosen
               local expanded=`sed -n "\
                  # concatenate lines with a trailing backslash
                  /^[ ]*${token//\//\\/}=[^ ]*[ ]*$/{
                     s,.*=\([^ ]*\).*,\1,;s,',,g;p;q}" ./configure`
               notify.debug "   \"$token\" == \"$expanded\""
               # if @$token@ has been found in ./configure
               if [[ -n "$expanded" ]]; then
                  str=`echo "${str/$/\\$}" | \
                       sed "s,@$token@,$expanded,"`
                  notify.debug "   --> str = \"$str\""
               fi
            done
         fi ;;
      esac
      IFS="$OIFS"

      # try to adjust unresolved variables (best effort)
      # i.e. "$(libdir)/pkgconfig" --> "%{_libdir}/pkgconfig"
      str=`echo "$str" | sed 's,\${\([^_]\),%{_\1,g;s,\$(,%{_,g;s,),},g'`
      notify.debug "   --> str = \"$str\""
      echo "$str"
   }

   # find informations about available info pages
   function specfile.infopages() {
      local automake_used=`
         [[ ! -e $tmpdir/$pck_rootdir/Makefile.am ]]; echo $?`

      cd $tmpdir/$pck_rootdir &&
      case $1 in
      --exist)
         # If the package contains Texinfo source, it will be declared
         # with the 'TEXINFOS' primary.
         # Generally Texinfo files are converted into info, and thus the
         # 'info_TEXINFOS' macro is most commonly used.
         # Any Texinfo source file must end in the '.texi', '.txi', or
         # '.texinfo' extension ('.texi' is recommended).
         #
         # e.g. info_TEXINFOS = texinfo.txi info-stnd.texi info.texi
         [[ $automake_used -eq 1 ]] &&
         [[ "\
`LANG=C find -name Makefile.am -exec grep "info_TEXINFOS[ ]*=" {} \;`" ]] ||
         [[ "`LANG=C find -type f \
            \( -name '*.texi' -or -name '*.txi' -or -name '*.texinfo' \)`" ]]
         echo $((! $?)) ;;
      --list)
         if [[ $automake_used -eq 0 ]]; then
            [[ `specfile.infopages --exist` = 1 ]] &&
               echo "%{_infodir}/<"$"info-page"">"
         else
            LANG=C find -name Makefile.am -exec \
               sed -n -e :a -e '
                  # if a line ends with a backslash, append...
                  /\\$/N;s/\\\n//;ta  # ...the next line to it
                  /info_TEXINFOS[ ]*=/p' {} \; |
            while read macro skip infopages_list; do
               for f in ${infopages_list/\.*/}; do
                  LANG=C find -name $f\* \
                     -exec grep -H "produced by makeinfo" {} \; |
                     sed "s,.*/\(.*\):.*,%{_infodir}/\1$info_compress_ext,"
               done
            done
         fi ;;
      *) notify.error $"\
(bug)"" -- "$"illegal arg#1 for \`$FUNCNAME'" ;;
      esac
   }

   # find informations about available man pages
   function specfile.manpages() {
      # find the list of the manpages when automake is used
      # output like this:
      #    MANSRC = pkcs15-crypt.1 pkcs15-init.1 ...
      function manpages.am_expand() {
         local am_makefile
         for am_makefile in `LANG=C find -name Makefile.am -exec \
            grep -rl -m1 -e "MANS[ ]*=" {} \;`; do
            sed -n -e :a -e '
               # if a line ends with a backslash, append...
               /\\$/N;s/\\\n//;ta  # ...the next line to it
               /MANS[ ]*=/p' $am_makefile | \
            while read macro skip manpages_list; do
               # `manpages_list' can contain Makefile variables
               # i.e.  man_MANS = $(MANSRC) pkcs15-profile.5
               case "$manpages_list" in
               *\$\(*\)*|*\${*}*)
                # notify.debug "manpages_list ($am_makefile) = \"$manpages_list\""
                  for token in $manpages_list; do
                     case $token in
                     \$\(*\)|\${*}) # found variable `$token'
                        token=`echo $token | sed -n 's,^\$.,,;s,.$,,p'`
                        sed -n ":a
                           /\\\\$/N;s/\\\\\n//;ta
                           /$token[ ]*=/p" $am_makefile ;;
                     *) # 'plain' manpage (not a variable)
                        echo "$macro = $token" ;;
                     esac
                  done ;;
               *) # no Makefile variables has been used
                  echo "$macro = $manpages_list" ;;
               esac
            done
         done
      }

      local automake_used=`
         [[ ! -e $tmpdir/$pck_rootdir/Makefile.am ]]; echo $?`

      cd $tmpdir/$pck_rootdir &&
      case $1 in
      --exist)
         [ "$automake_used" = 1 ] &&
         [[ "`LANG=C find -name Makefile.am \
                -exec grep "MANS[ ]*=" {} \;`" ]] ||
         [[ "`LANG=C find -type f -name "*.[0-9]"`" ]]
         echo $((! $?)) ;;
      --groups)
         if [ "$automake_used" = 0 ]; then
            LANG=C find -type f -name "*.[0-9]" | sed 's,.*\(.\),\1,'
         else
            manpages.am_expand | \
            while read macro equal manpages_list; do
               case $macro in
               man[0-9]_MANS)
                  for f in $manpages_list; do
                     case $f in
                     *.man) echo $macro | sed "s/man\(.\)_MANS/\1/" ;;
                     *) echo $f | sed "s/.*\.//" ;;
                     esac
                  done ;;
               *) for f in $manpages_list; do
                     echo $f | sed "s/.*\(.\)/\1/"
                  done ;;
               esac
            done
         fi | sort | uniq ;;
      --list)
         [[ "$2" ]] || notify.error $"\
(bug)"" -- "$"missing arg#2 in \`$FUNCNAME $1'"

         # list of man pages in the section '$2'
         local manpage
         if [ "$automake_used" = 0 ]; then
            # FIXME : if a manpage is compressed in the source tarball,
            # a double `$man_compress_ext' will be appended
            LANG=C find -type f -name "*.$2" \
               -printf "%%{_mandir}/man$2/%f$man_compress_ext\n"
         else
            manpages.am_expand | \
            while read macro equal manpages_list; do
               case $macro in
                  # sometimes developers prefer to name a man page something
                  # like 'foo.man' in the source, and then rename it to have
                  # the correct suffix, e.g. 'foo.1', when installing the file.
                  # For instance, consider this example:
                  #    man1_MANS = rename.man thesame.1 alsothesame.1c
                  # In this case, 'rename.man' will be renamed to 'rename.1'
                  # when installed, but the other files will keep their names.
                  man[0-9]_MANS)
                     man_section=`echo $macro | sed "s/man\(.\)_MANS/\1/"`
                     # only man pages in section '$2'
                     [[ $man_section = $2 ]] || continue
                     for f in $manpages_list; do
                        echo -n "%{_mandir}/man$man_section/"
                        case $f in
                           *.man) echo "\
${f/\.man/.$man_section}$man_compress_ext" ;;
                           *) echo "$f$man_compress_ext" ;;
                        esac
                     done ;;
                  # Man pages are declared using the 'MANS' primary (generally
                  # 'man_MANS'). Man pages are installed in the correct
                  # subdirectory of 'mandir', based on the file extension
                  # ('0' through '9', and 'l' and 'n').
                  *) for f in $manpages_list; do
                        man_section=`echo $f | sed "s/.*\(.\)/\1/"`
                        [[ $man_section = $2 ]] || continue
                        echo "%{_mandir}/man$man_section/$f$man_compress_ext"
                     done ;;
               esac
            done | sort | uniq
         fi ;;
      *) notify.error $"\
(bug)"" -- "$"illegal arg#1 for \`$FUNCNAME'" ;;
      esac
   }

   # find informations about available i18n (gettext) files
   function specfile.i18n_support() {
      case $1 in
      --exist)
         # note: in the 'tar' tarball there is no 'intl' folder, so we use 'po'
         [[ "`LANG=C find $tmpdir/$pck_rootdir/ -type d -name po`" ]]
         echo $((! $?)) ;;
      *) notify.error $"\
(bug)"" -- "$"illegal arg#1 for \`$FUNCNAME'" ;;
      esac
   }

   # find informations about pkgconfig related stuff (*.pc files)
   function specfile.pkgconfig() {
      local automake_used=`
         [[ ! -e $tmpdir/$pck_rootdir/Makefile.am ]]; echo $?`

      cd $tmpdir/$pck_rootdir &&
      case $1 in
      --exist)
         if [[ $automake_used -eq 1 ]]; then
            [[ `LANG=C find -name Makefile.am \
                -exec grep "pkgconfigdir[ ]*=" {} \;` ]]
            echo $((! $?))
         else
            [[ `LANG=C find -name Makefile.in -exec grep "\.pc " {} \;` ]]
            echo $((! $?))
         fi ;;
      --dir)
         unset pkgconfigdir
         if [[ $automake_used -eq 1 ]]; then
            pkgconfigdir=`
               LANG=C find -name Makefile.am \
                  -exec grep "pkgconfigdir[ ]*=" {} \; | \
                  sed 's,pkgconfigdir[ ]*=[ ]*,,' | sort | uniq`
            notify.debug "pkgconfigdir = \"$pkgconfigdir\""
            pkgconfigdir="`expand.variables "$pkgconfigdir"`/*.pc"
            notify.debug "   pkgconfigdir = \"$pkgconfigdir\""
         else
            # FIXME : add a check for real path
            [[ `$FUNCNAME --exist` -eq 1 ]] &&
               pkgconfigdir="%{_libdir}/pkgconfig/*.pc"
         fi
         echo "$pkgconfigdir" ;;
      *) notify.error $"\
(bug)"" -- "$"illegal arg#1 for \`$FUNCNAME'" ;;
      esac
   }

   # specfile.includedir()
   # Parameters:
   #   $1 : --exist  (optional)
   # Description:
   #   Find information about installation directories of *.h files
   #
   function specfile.includedir() {
      local headers include_headers \
         include am_headers_path am_headers_paths \
         automake_used=`
         [[ ! -e $tmpdir/$pck_rootdir/Makefile.am ]]; echo $?`

      if [[ $automake_used -eq 1 ]]; then
         if [[ "$1" = "--exist" ]]; then
            cd $tmpdir/$pck_rootdir &&
            headers=`LANG=C find . -name Makefile.am -exec \
               grep -rl -e ".*include_HEADERS[ ]*=" {} \;`
            [[ -z "$headers" ]]; echo $?
            exit
         fi

         cd $tmpdir/$pck_rootdir &&
         case "$spec_type" in
            standard | library)
               am_headers_paths=()
               # found for Makefiles that install header files
               # note: ^[^ ]*includedir can be not present
               for f in `LANG=C find . -name Makefile.am -exec \
                         grep -rl -e "^[^ ]*include_HEADERS[ ]*=" {} \;`; do
                  # some examples:
                  # [apt]
                  # includedir=${prefix}/include/apt-pkg
                  # include_HEADERS = ...
                  #    --> ${prefix}/include/apt-pkg
                  # [avifile]
                  # mainincludedir = $(pkgincludedir)
                  # maininclude_HEADERS = ...
                  #    --> $(pkgincludedir) --> $(includedir)/@PACKAGE@
                  # [a52dec]
                  # pkginclude_HEADERS = ...
                  #    --> %{_includedir}
                  # [aspell]
                  # include_HEADERS = aspell.h
                  # pspell_includedir = ${includedir}/pspell
                  # pspell_include_HEADERS = pspell.h
                  #    --> %{_includedir} %{_includedir}/pspell
                  # [pygtk-2.4.1]
                  # PLATFORM_VERSION = 2.0
                  # pkginclude_HEADERS = pygtk.h
                  # pkgincludedir = $(includedir)/pygtk-$(PLATFORM_VERSION)/pygtk
                  #    --> %{_includedir}/pygtk-2.0/pygtk
                  for include_headers in `
                     sed -n 's/\(^[^ ]*include_HEADERS\)[ ]*=.*/\1/p' $f`; do
                     include=`echo $include_headers | \
                        sed -n 's/^\([^ ]*\)include_HEADERS[ ]*/\1/p'`
                     headers=`echo $include_headers | sed -n "\
s,^${include}includedir[ ]*=[ ]*\([^ ]*\),\1,p" $f`

                     notify.debug "include_headers ($f) = \"$include_headers\""
                     notify.debug "   --> include = \"$include\""
                     notify.debug "   --> headers = \"$headers\""

                     if [[ "$headers" ]]; then
                        local newheader=`echo $headers | sed -n '
                           s,\$[{(]includedir[)}],%{_includedir},
                           s,\$[{(]prefix[)}],%{_prefix},;p'`
                        # add `newheader' only if not yet in `am_headers_paths'
                        local alreadyin=0
                        for i in `seq 1 1 ${#am_headers_paths[*]}`; do
                           [[ "${am_headers_paths[$i-1]}" = "$newheader" ]] &&
                              let "alreadyin = 1" && break
                        done
                        newheader="`expand.variables $newheader $f`"
                        [[ $alreadyin -eq 0 ]] &&
                           am_headers_paths[${#am_headers_paths[*]}]=$newheader
                     else
am_headers_paths[${#am_headers_paths[*]}]="%{_includedir}" #"(needed by KDE editors)
                     fi
                     notify.debug "   \
am_headers_paths = \"${am_headers_paths[*]}\""
                  done

               done
               for i in `seq 1 1 ${#am_headers_paths[*]}`; do
                  am_headers_path=${am_headers_paths[$i-1]}
                  notify.debug "am_headers_path[$i] = $am_headers_path"
                  # check if one or more configure variable are used
                  case "$am_headers_path" in
                  *@*@*)
                     if [[ -x ./configure ]]; then
                        OIFS="$IFS"; IFS='@'
                        for token in ${am_headers_path%@*}; do
                           [[ "$token" ]] || continue
                           # expand the variables looking into the
                           # ./configure file
                           local exp_token=`sed -n "\
/^[ ]*${token//\//\\/}=[^ ]*[ ]*$/{s,.*=\([^ ]*\).*,\1,;s,',,g;p}" ./configure`
                           notify.debug "   \"$token\" == \"$exp_token\""
                           # if @$token@ has been found in ./configure
                           if [[ -n "$exp_token" ]]; then
                              am_headers_path=`echo "${am_headers_path/$/\\$}" | \
                                 sed "s,@$token@,$exp_token,"`
                              notify.debug "\
   --> am_headers_path[$i] = \"$am_headers_path\""
                           fi
                        done
                        IFS="$OIFS"
                        # at this point there should be no directory
                        # different to '$(includedir)' (hopefully)
                        am_headers_path=`echo $am_headers_path | \
                           sed 's,\${includedir},%{_includedir},
                                s,\$(includedir),%{_includedir},
                                s,\${prefix},%{_prefix},
                                s,\$(prefix),%{_prefix},'`
                        notify.debug "\
   --> am_headers_path[$i] = \"$am_headers_path\""
                     fi
                  ;;
                  esac

                  [[ "$am_headers_path" =~ / ]] &&
                     am_headers_path="$am_headers_path/*.h" ||
                     am_headers_path="\
%dir $am_headers_path\n$am_headers_path/*.h"
                  am_headers_paths[$i-1]="$am_headers_path"
               done ;;
            python)
               : ;;   # FIXME
         esac
      else
         # no Makefile.am file found (check in Makefile[.in])
         # FIXME: modify this brainless code
         [[ "$spec_type" = "library" ]] &&
            am_headers_paths=("%{_includedir}/*.h")
      fi
      # remove duplicate entries
      for i in `seq 1 1 ${#am_headers_paths[*]}`; do
         echo ${am_headers_paths[$i-1]}
      done | sort | uniq
   }

   function specfile.devel_exist() {
      [[ $(specfile.includedir --exist) -eq 1 ||
         $(specfile.pkgconfig --exist) -eq 1 ]] && echo 1 || echo 0
   }

   # 1. specfile preamble
   function specfile.write_preamble() {
      # set package name and version to '%{name}' and '%{version}'
#     local pck_tarball_4spec=`echo ${pck_tarball##*/} |
#        sed "s,$pck_name,%{name},g;s,$pck_version,%{version},g"`
      local pck_tarball_4spec=`echo "${pck_tarball##*/}" |
         sed "s,$pck_version,%{version},g"`

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

      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

      case $spec_type in
         standard)
            [ "$spec_source" ] || spec_source=".../$pck_tarball_4spec"
            [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ] && spec_buildrequires="cmake"
         ;;
         library)
            [ "$spec_source" ] || spec_source=".../$pck_tarball_4spec"
            spec_group="$library_group"
            [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ] && spec_buildrequires="cmake"
         ;;
         perl)
            local perl_module_name
            if [[ -e $tmpdir/$pck_rootdir/Build.PL ]]; then
               notify.debug "$FUNCNAME: -e Build.PL"
               # new building/installing technology
               perl_module_name=$(
                  sed -n "/^[ \t]*module_name[ ]*/{
                     s,.*=>[ ]*['\"]\(.*\)['\"].*,\1,;p
                  }" $tmpdir/$pck_rootdir/Build.PL)
               local Build_PL_license
               Build_PL_license=$(
                  sed -n "/^[ \t]*license[ ]*/{
                     s,.*=>[ ]*['\"]\(.*\)['\"].*,\1,;p
                  }" $tmpdir/$pck_rootdir/Build.PL)
               notify.debug "Build_PL_license = \"$Build_PL_license\""
               # see manpage of "Module::Build"
               case "$Build_PL_license" in
                  perl)
                     spec_license="GPL, Artistic" ;;
                  gpl)
                     spec_license="GPL" ;;
                  lgpl)
                     spec_license="LGPL" ;;
                  artistic)
                     spec_license="Artistic" ;;
                  bsd)
                     spec_license="BSD License" ;;
                  open_source)
                     spec_license="OSI Approved" ;;
                  unrestricted)
                     # The distribution is licensed under a license that is not
                     # approved by www.opensource.org but that allows distribution
                     # without restrictions
                     spec_license="no OSI Approved" ;;
                  restricted)
                     # The distribution may not be redistributed without special
                     # permission from the author and/or copyright holder
                     spec_license="no OSI Approved" ;;
                  *) spec_license="$perl_License_default" ;;
               esac
            elif [[ -e $tmpdir/$pck_rootdir/$perl_Makefile_generator ]]; then
               notify.debug "$FUNCNAME: -e $perl_Makefile_generator"
               # look in the Makefile.PL file for the variable `NAME' in the
               # block 'WriteMakefile(' ... ')'
               perl_module_name=$(
                  sed -n "/^WriteMakefile(/,/^)/{
                     /^[ \t]*NAME/{s,.*NAME.*=>[ ]*['\"]\(.*\)['\"]\,.*,\1,p
                  }}" $tmpdir/$pck_rootdir/$perl_Makefile_generator)
               [ "$perl_module_name" ] || perl_module_name=$(
                  sed -n "\
/name/{s,^[ \t]*name[ \t]*['\"]*\([a-zA-Z]*\)['\"]*.*,\1,p}" \
                     $tmpdir/$pck_rootdir/$perl_Makefile_generator)
               spec_license="$perl_License_default"
            else
               notify.error "\
neither \`$perl_Makefile_generator' nor \`Build.PL' file found"
            fi
            notify.debug "perl_module_name = \"$perl_module_name\""

            [ -n "$perl_module_name" ] &&
               spec_summary="$perl_module_name - $summary_defvalue" ||
               spec_summary="... - $summary_defvalue"
            notify.debug "spec_summary = \"$spec_summary\""
            spec_group="$library_group_perl"

            [ "$spec_source" ] ||
            if [ "$perl_module_name" ]; then
               spec_source="\
http://www.cpan.org/modules/by-module/${perl_module_name//::/\/}/$pck_tarball_4spec"
            else
               spec_source="\
http://www.cpan.org/modules/by-module/.../$pck_tarball_4spec"
            fi

            spec_url="http://www.cpan.org"
            spec_buildrequires="perl-devel >= %perl_major_ver"
            spec_requires='perl >= %perl_major_ver'
           #spec_buildroot='%{_tmppath}/perl-root # fixed in perl-5.8.6-3qilnx
         ;;
         python)
            # check if `setup.py' exists
            [[ -e $tmpdir/$pck_rootdir/setup.py ]] ||
               notify.error "\`setup.py': "$"file not found"

            spec_group="$python_modules_group"
            spec_summary="$(\
cd $tmpdir/$pck_rootdir && python setup.py --description 2>/dev/null | \
sed 1q 2>/dev/null)"
            spec_url="$(\
cd $tmpdir/$pck_rootdir && python setup.py --url 2>/dev/null | \
sed 1q 2>/dev/null)"
            [ "$spec_source" ] || spec_source=".../$pck_tarball_4spec"
            spec_license="$(\
cd $tmpdir/$pck_rootdir && python setup.py --license 2>/dev/null | \
sed 1q 2>/dev/null)"
            [[ "$spec_license" = UNKNOWN ]] && spec_license="$license_defvalue"
            spec_requires="python${rpm_macro_pyver:+ >= $rpm_macro_pyver}"
         ;;
      esac

      local spec_source_4spec=`echo "$spec_source" |
         sed "s,$pck_version,%{version},g"`

      [[ "$spec_type" = perl ]] && echo "\
%define perl_major_ver %(eval \`perl -V:version\`; echo \${version%*.[0-9]*}.0)
"

     (echo "\
Name: $pck_name
Version: $pck_version
Release: 1$DISTRO_rpm
Summary: ${spec_summary:-$summary_defvalue}
Group: ${spec_group:-$group_defvalue}
Vendor: $VENDOR
Distribution: $DISTRO
Packager: $packager_fullname <$packager_email>
URL: ${spec_url:-$url_defvalue}
Source: ${spec_source_4spec:-$pck_tarball_4spec}
License: ${spec_license:-$license_defvalue}"
if [ "$(specfile.infopages --exist)" = 1 ]; then
   [ "$rpm_macro_installinfo_binary" ] &&
      echo "Requires(post): ${rpm_macro_installinfo_binary}" ||
      echo "Requires(post): ${path_installinfo:-/sbin/install-info}"
fi
[ "$spec_requires" ] && echo Requires: $spec_requires
[ "$spec_buildrequires" ] && echo BuildRequires: $spec_buildrequires
      echo "\
BuildRoot: ${spec_buildroot:-"$format_buildroot_value"}") | \
      while read id value; do
         printf "%-${format_preamble_tab:-14}s %s\n" "$id" "$value"
      done
   }

   # 2. specfile package(s) description
   function specfile.write_packages() {
      case $spec_type in
         python)
            echo "
%description
${spec_summary:-$summary_defvalue}." ;;
         *) echo "
%description
$description_defval" ;;
      esac

      case "$spec_type" in
         standard)
            [[ `specfile.includedir --exist` -eq 1 ||
               `specfile.pkgconfig --exist` -eq 1 ]] &&
            echo "
%package devel
Summary:       Devel package for %{name}
Group:         Development/Libraries
Requires:      %{name} = %{?epoch:%epoch:}%{version}-%{release}

%description devel
$description_devel_defval

This package contains static libraries and header files need for development."
         ;;
         library)
            echo "
%package devel
Group:         $library_group_devel
Summary:       $library_summary
Requires:      %{name} = %{?epoch:%epoch:}%{version}-%{release}

%description devel
$description_devel_defval

This package contains static libraries and header files need for development."
         ;;
         python)
            : # FIXME
         ;;
      esac
   }

   # 3. %setup
   function specfile.write_setup() {
         echo "
%prep"
      if [ "$pck_rootdir_4spec" = "%{name}-%{version}" ]; then
         echo "%setup -q"
      elif [ "$pck_rootdir_4spec" = "-c %{name}-%{version}" ]; then
         echo "%setup -q $pck_rootdir_4spec"
      else
         echo "%setup -q -n $pck_rootdir_4spec"
      fi
   }

   # 4. %build
   function specfile.write_build() {
      local pck_configure=`(\
         cd $tmpdir/$pck_rootdir &&
          { [[ -x ./configure ]] && echo -n "./configure"
            LANG=C find . -mindepth 2 -type f -perm +111 \
               -name configure -printf "%p "; } )`
      notify.debug "pck_configure = \"$pck_configure\""

      local make_bin perl_bin
      if [ "$format_unix_tools" = "1" ]; then
         make_bin="%{__make}"; perl_bin="%{__perl}"
      else
         make_bin="make"; perl_bin="perl"
      fi

      echo "
%build"
      case $spec_type in
         standard | library)
            # if `configure' exists, write the needed specfile commands
            if [[ -n "$rpm_macro_configure" && \
                  "$pck_configure" = "./configure" ]]; then
               echo "$rpm_macro_configure"
            elif [[ "$pck_configure" ]]; then
               # writes also the other `configure' executable scripts found
               # in the source package as a comment
               echo -n "${pck_configure/ */} \\"
               [[ "$pck_configure" =~ ' ' ]] &&
                  echo -n " # -or- ${pck_configure#* }"
               echo -n "
   --prefix=%{_prefix}"
[[ `specfile.infopages --exist` = 1 ]] && echo -n "\
 \\
   --infodir=%{_infodir}"
[[ `specfile.manpages --exist` = 1 ]] && echo "\
 \\
   --mandir=%{_mandir}" || echo ""
               echo ""
            elif [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ]; then
               if [ "$rpm_macro_cmake" ]; then
                  echo "$rpm_macro_cmake"
               else
                  echo "\
CFLAGS=\"${CFLAGS:-%optflags}\" ; export CFLAGS
CXXFLAGS=\"${CXXFLAGS:-%optflags}\" ; export CXXFLAGS
FFLAGS=\"${FFLAGS:-%optflags}\" ; export FFLAGS
mkdir -p build ; cd build
cmake \\
   -DCMAKE_INSTALL_PREFIX:PATH=%{_prefix} \\
   -DCMAKE_INSTALL_LIBDIR:PATH=%{_libdir} \\
   -DINCLUDE_INSTALL_DIR:PATH=%{_includedir} \\
   -DLIB_INSTALL_DIR:PATH=%{_libdir} \\
   -DSYSCONF_INSTALL_DIR:PATH=%{_sysconfdir} \\
   -DSHARE_INSTALL_PREFIX:PATH=%{_datadir} \\
%if "%{?_lib}" == \"lib64\"
    -DLIB_SUFFIX=64 \\
%endif
   -DBUILD_SHARED_LIBS:BOOL=ON ..
"
               fi
               [ -n "$rpm_macro_make" ] &&
                   echo "%make" || echo "$make_bin %{?_smp_mflags}"
            fi
            [[ "$makefile" ]] &&
             { [[ "$rpm_macro_make" ]] &&
                  echo "%make" || echo "$make_bin %{?_smp_mflags}"; }
         ;;
         perl)
            if [[ -e $tmpdir/$pck_rootdir/Build.PL ]]; then
               echo "\
$perl_bin Build.PL installdirs=vendor
./Build
./Build test"
            elif [[ -e $tmpdir/$pck_rootdir/$perl_Makefile_generator ]]; then
               echo "\
$perl_bin $perl_Makefile_generator PREFIX=%{_prefix} INSTALLDIRS=vendor"
               if [[ "$rpm_macro_make" ]]; then
                  echo "\
%make
%make test"
               else
                  echo "\
$make_bin %{?_smp_mflags}
$make_bin test"
               fi
            fi
         ;;
         python)
            [[ "$(find $tmpdir/$pck_rootdir -type f -name *.c)" ]] &&
               echo "CFLAGS=\"%{optflags}\" %{__python} setup.py build" ||
               echo "%{__python} setup.py build" ;;
      esac
   }

   # 5. %install
   function specfile.write_install() {
      local make_bin perl_bin
      if [ "$format_unix_tools" = "1" ]; then
         make_bin="%{__make}"; rm_bin="%{__rm}"
      else
         make_bin="make"; rm_bin="rm"
      fi

      # look at the prefix variable used in makefiles ('DESTDIR' or 'prefix')
      local makeinstall_cmd
      if [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ]; then
         [ -n "$rpm_macro_makeinstall_cmake" ] &&
            makeinstall_cmd="$rpm_macro_makeinstall_cmake" ||
            makeinstall_cmd="$make_bin install DESTDIR=\"%{buildroot}\" #-C build"
      elif [ -n "$makefile" ]; then
         if [[ "`grep -c "DESTDIR[ ]*=[ ]*" $makefile`" ]]; then
            [[ "$rpm_macro_makeinstall" ]] &&
               makeinstall_cmd="%makeinstall" ||
               makeinstall_cmd="$make_bin install DESTDIR=\"%{buildroot}\""
         elif [[ "`grep -c "prefix[ ]*=[ ]*" $makefile`" ]]; then
            if [[ "$rpm_macro_makeoldinstall" ]]; then
               makeinstall_cmd="%makeoldinstall"
            elif [[ "$rpm_macro_makeinstall" ]]; then
               makeinstall_cmd="%makeinstall"
            else
               makeinstall_cmd="$make_bin prefix=\"%{buildroot}\""
            fi
         else
            notify.warning "neither \`DESTDIR' nor \`prefix' variables found"
         fi
      fi

      echo "
%install
[ \"%{buildroot}\" != / ] && $rm_bin -rf \"%{buildroot}\""

      case $spec_type in
         standard | library)
            [ "$makeinstall_cmd" ] && echo "$makeinstall_cmd"
            [[ "$(specfile.i18n_support --exist)" = "1" ]] && echo "
%find_lang %{name}"
         ;;
         perl)
            if [ -e $tmpdir/$pck_rootdir/Build.PL ]; then
               echo "\
./Build install \\
   destdir=\"%{buildroot}\" \\
   --install_path bindoc=\"%{_mandir}/man1\" \\
   --install_path libdoc=\"%{_mandir}/man3\"

packlist=\`find %{buildroot} -name .packlist\`
[ -z \"\$packlist\" ] && exit 1 || cat \$packlist | \\
   sed \"s,%buildroot,,g;s,.*/man/.*,&.gz,g\" | \\
   sort -u > .packlist && rm \$packlist

find %{buildroot}%{perl_vendorlib} \\
   -type d -depth -exec rmdir {} 2>/dev/null \\;

strid=\`echo \$packlist | sed 's,.*auto\(.*\)/.packlist,\1,'\`
for dir in \`find %{buildroot} -type d | grep \$strid\`; do
   echo "%dir \${dir#%buildroot}" >> .packlist
done"
            else
               echo "\
%makeinstall_perl
packlist=\`find %{buildroot} -name .packlist\`
[ -z \"\$packlist\" ] && exit 1 || cat \$packlist | \\
   sed \"s,%buildroot,,g;s,.*/man/.*,&.gz,g\" | \\
   sort -u > .packlist && rm \$packlist

strid=\`echo \$packlist | sed 's,.*auto\(.*\)/.packlist,\1,'\`
for dir in \`find %{buildroot} -type d | grep \$strid\`; do
   echo \"%dir \${dir#%buildroot}\" >> .packlist
done"
            fi
         ;;
         python)
            echo "\
%{__python} setup.py install \\
   -O1 --skip-build \\
   --root=\"%{buildroot}\" \\
   --install-headers=%{_includedir}/python \\
   --install-lib=${python_install_lib_path:-%_libdir/site-python} \\
   --single-version-externally-managed \\
   --record=%{name}.filelist

sed -i \"\,\.egg-info/,d;s,.*/man/.*,&.gz,\" %{name}.filelist"
         ;;
      esac
   }

   # 6. %clean
   function specfile.write_clean() {
      if [ "$format_unix_tools" = "1" ]; then
         echo "
%clean
[ \"%{buildroot}\" != / ] && %{__rm} -rf \"%{buildroot}\""
      else
         echo "
%clean
[ \"%{buildroot}\" != / ] && rm -rf \"%{buildroot}\""
      fi

      if [ "$spec_type" = "perl" ]; then
         [ "$format_unix_tools" = "1" ] &&
            echo "%{__rm} -f .packlist" || echo "rm -f .packlist"
      fi
   }

   # 7. specfile scripts
   function specfile.write_scripts() {
      if [[ $(specfile.infopages --exist) = 1 ]]; then
         local infofile
         echo "
%post"

         # FIXME : <info>, <info>-1, <info>-2: install only the first one
         for infofile in $(specfile.infopages --list); do
            if [[ "$rpm_macro_installinfo" ]]; then
               # %{_infodir}/foo.info.gz --> foo.info
               infofile="$(\
echo "$infofile" | sed "s,.*/,,;s,$info_compress_ext\$,,")"
               echo "$rpm_macro_installinfo $infofile"
            else
               echo "\
if [ \"\$1\" = \"0\" ]; then
   ${path_installinfo:-/sbin/install-info} $infofile %{_infodir}/dir
fi"
            fi
         done
         [[ "$spec_type" = library ]] &&
            echo "${path_ldconfig:-/sbin/ldconfig}"

         echo "exit 0"
         echo "
%preun"
         # FIXME : <info>, <info>-1, <info>-2: install only the first one
         for infofile in $(specfile.infopages --list); do
            if [[ "$rpm_macro_uninstallinfo" ]]; then
               infofile="$(\
echo "$infofile" | sed "s,.*/,,;s,$info_compress_ext\$,,")"
               echo "$rpm_macro_uninstallinfo $infofile"
            else
               echo "\
${path_installinfo:-/sbin/install-info} --delete $infofile %{_infodir}/dir"
            fi
         done
         [[ "$spec_type" = library ]] &&
            echo "${path_ldconfig:-/sbin/ldconfig}"
         echo "exit 0"
      else
         [[ "$spec_type" = library ]] && echo "
%post -p ${path_ldconfig:-/sbin/ldconfig}
%postun -p ${path_ldconfig:-/sbin/ldconfig}"
      fi
   }

   # 8. %files
   function specfile.write_files() {
      # standard text documentation files (see 'automake --help')
      # + some other documentation files found in some packages
      # NOTE : the 'INSTALL' file may eventually be added
      local docs std_docs='
         AUTHORS
         BACKLOG
         BUGS
         CHANGES
         COPYING
         COPYING.DOC
         COPYING.LESSER
         COPYING.LIB
         CREDITS
         ChangeLog*
         LICENCE
         LICENSE
         MANUAL
         NEWS
         README*
         THANKS
         TODO
         WHATSNEW
         WHERE'

      # do not add the generic GNU INSTALL in the list of docs
      [ -f "$tmpdir/$pck_rootdir/INSTALL" ] &&
      case $(sed 5q $tmpdir/$pck_rootdir/INSTALL) in
      *"These are generic installation instructions."*)
         std_docs=$(echo $std_docs | sed 's/INSTALL //') ;;
      *) : ;;
      esac

      local docs_curr doc_curr
      for std_doc in $std_docs; do
         # `ls' if used to support strings like `ChangeLog*'
         docs_curr=$(cd $tmpdir/$pck_rootdir && ls $std_doc 2>/dev/null)
         for doc_curr in $docs_curr; do
            # ignore empty documentation files
            [[ -s $tmpdir/$pck_rootdir/$doc_curr ]] && docs="$docs $doc_curr"
         done
      done
      # split the list of docs into multiple lines if necessary
      [ "$docs" ] && docs=`echo $docs | fmt -u -w 77 | sed 's,.*,%doc &,'`

      # info pages
      infos=`
      case $info_condensed_list in
         0) specfile.infopages --list | sort ;;
         1) echo "%{_infodir}/*" ;;
         *) notify.error "\
"$"(bug)"" -- $FUNCNAME: "$"illegal value for"" 'info_condensed_list' \
($info_condensed_list)" ;;
      esac`

      # man pages
      mans=`
      case $man_condensed_list in
         0) for man_group in $(specfile.manpages --groups); do
               specfile.manpages --list $man_group | sort
            done ;;
         1) for man_group in $(specfile.manpages --groups); do
               echo "%{_mandir}/man${man_group}/*"
            done ;;
         2) [[ $(specfile.manpages --exist) = 1 ]] &&
               echo "%{_mandir}/man?/*" ;;
         *) notify.error "\
"$"(bug)"" -- $FUNCNAME: "$"illegal value for"" 'man_condensed_list' \
($man_condensed_list)" ;;
      esac`

      case $spec_type in
         standard)
            [[ `specfile.i18n_support --exist` = 1 ]] &&
               echo -e "\n%files -f %{name}.lang" || echo -e "\n%files"

            echo "\
%defattr(-,root,root)"
# find for i18n files
#[[ "$i18n_found" ]] && echo "%{_datadir}/locale/*/LC_MESSAGES/*"
# package documentation
for doc in infos mans docs; do
   [[ "${!doc}" ]] && echo -e "${!doc}"
done

            if [[ `specfile.devel_exist` -eq 1 ]]; then
               echo "
%files devel
%defattr(-,root,root)"
               [[ `specfile.includedir --exist` -eq 1 ]] &&
                  echo -e "`specfile.includedir --dir`"
               [[ `specfile.pkgconfig --exist` -eq 1 ]] &&
                  echo "`specfile.pkgconfig --dir`"
            fi
         ;;
         library)
            [[ `specfile.i18n_support --exist` = 1 ]] &&
               echo -e "\n%files -f %{name}.lang" || echo -e "\n%files"

            echo "\
%defattr(-,root,root)
%{_libdir}/*.so.*"
# package documentation
for doc in infos mans docs; do
   [[ "${!doc}" ]] && echo -e "${!doc}"
done

echo -e "
%files devel
%defattr(-,root,root)
$(specfile.includedir)
%{_libdir}/*.a
%{_libdir}/*.la
%{_libdir}/*.so"
[[ `specfile.pkgconfig --exist` = 1 ]] && echo "`specfile.pkgconfig --dir`"
         ;;
         perl)
            echo "
%files -f .packlist
%defattr(-,root,root)"
         ;;
         python)
            echo "
%files -f %{name}.filelist
%defattr(-,root,root)"
         ;;
         esac
   }

   # 9. %changelog
   function specfile.write_changelog() {
      echo "
%changelog
* `LC_ALL="C" date "+%a %b %d %Y"` $packager_fullname <$packager_email> $pck_version-1$DISTRO_rpm
- package created by @package@"
   }

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

      check_vals=(
         "Summary"            summary_defvalue
         "Group"              group_defvalue
         "URL"                url_defvalue
         "License"            license_defvalue
         "%description"       description_defval
         "%description devel" description_devel_defval
         "%changelog"         changelog_samever_defvalue
      )

      for i in `seq 1 1 $(( ${#check_vals[@]} / 2 ))`; do
         id="${check_vals[($i-1)*2]}"
         value="${check_vals[($i-1)*2+1]}"
         case "$id" in
            # for the id starting by '%' we must consider the first two lines
            # after its line number (three lines from the id and the first
            # blank line found)
            %*) sed -n "/^$id$/,/^$/p" $specfile | sed 3q | \
                   grep -q "${!value}" ;;
            *)  sed -n "/%description/q;{/^$id/p}" $specfile | \
                   grep -q "${!value}" ;;
         esac
         [ $? -eq 0 ] && notify.warning $"\
remember to modify the value for \`${NOTE}$id${NORM}'"
      done
   }

   local spec_source \
         spec_group \
         spec_url \
         spec_buildrequires \
         spec_requires \
         spec_buildroot

   local spec_type="$1"
   case $spec_type in
      standard|library|perl|python) ;;
      gnome|kde3|kde4|librarytools)
         notify.error \
$"FIXME: sorry, not implemented yet..."" "$"(see $templatedir)" ;;
      *) notify.error $"unknown specfile --type"" \`$spec_type'" ;;
   esac

   # 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
   #  3. specfile.write_preamble()
   #        spec_license (default:"$license_defvalue")
   #        spec_buildrequires
   #        perl_module_name
   #        spec_summary
   #        spec_group
   #        spec_source
   #        spec_url
   #        spec_buildrequires
   #        spec_requires

   # 'pck_tarball' = absolute path of '$1'
   local pck_tarball
   case "$2" in
      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 "pck_tarball = $pck_tarball"
   notify.debug "spec_source = $spec_source"

   [ "$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
   local pck_name=${3:-`echo $2 | 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_newver//[0-9\.]/}" ]] &&
      notify.error $"invalid version number"" -- \`$pck_newver'"

   local pck_version=${4:-`echo $2 | 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 "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 $"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}"

   # check the name structure of the library and perl packages
   case $spec_type in
      library)
         [[ "$pck_name" =~ $library_name_structure ]] || notify.error $"\
libraries must have this name structure (use \`-n'):"" \
\`$library_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 -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 ;;
      *) notify.error $"unsupported package compression method" ;;
   esac
   popd >/dev/null

   # find the root directory of the uncompressed tarball
   local pck_rootdir=`\
      LANG=C find $tmpdir -mindepth 1 -maxdepth 1 -type d -printf "%f"`

   local pck_rootdir_4spec

   # hack for packages without a root directory
   notify.debug "pck_rootdir = \"$pck_rootdir\""
   if [ ! -d "$tmpdir/$pck_rootdir" ]; then
      pck_rootdir=""
      pck_rootdir_4spec="-c %{name}-%{version}"
   else
      pck_rootdir_4spec=`echo $pck_rootdir | \
         sed "s/$pck_name/%{name}/;s/$pck_version/%{version}/"`
   fi
   notify.debug "pck_rootdir = \"$pck_rootdir\""
   notify.debug "pck_rootdir_4spec = \"$pck_rootdir_4spec\""

   ############ BEGIN FIXME: move code to a better place ############
   # check if a makefile exists
   local makefile
   for f in $tmpdir/$pck_rootdir/{Makefile,Makefile.in}; do
      [[ -e $f ]] && makefile=$f
   done
   case "$spec_type" in
      # note: perl packages usually use the perl script Makefile.PL
      #       python modules don't use Makefiles at all
      perl | python) : ;;
      *) if [ -e $tmpdir/$pck_rootdir/CMakeLists.txt ]; then
            :
         elif [ -z "$makefile" ]; then
            notify.warning $"\
neither \`Makefile' nor \`Makefile.in' has been found"
         fi
         [[ -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)"
         [[ -e $tmpdir/$pck_rootdir/setup.py ]] &&
            notify.warning $"\
looks like a python module (use \`-t python' if this is true)"
      ;;
   esac
   ############ END FIXME: move code to a better place ##############

   # write the resulting specfile

   specfile.write_preamble
   specfile.write_packages
   specfile.write_setup
   specfile.write_build
   specfile.write_install
   specfile.write_clean
   specfile.write_scripts
   specfile.write_files
   specfile.write_changelog

   [[ "$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"