Hello community,

here is the log from the commit of package ocaml-rpm-macros for 
openSUSE:Factory checked in at 2020-02-26 15:01:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ocaml-rpm-macros (Old)
 and      /work/SRC/openSUSE:Factory/.ocaml-rpm-macros.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ocaml-rpm-macros"

Wed Feb 26 15:01:43 2020 rev:5 rq:778683 version:20200220

Changes:
--------
--- /work/SRC/openSUSE:Factory/ocaml-rpm-macros/ocaml-rpm-macros.changes        
2019-11-30 10:35:44.916183957 +0100
+++ 
/work/SRC/openSUSE:Factory/.ocaml-rpm-macros.new.26092/ocaml-rpm-macros.changes 
    2020-02-26 15:01:44.784796126 +0100
@@ -1,0 +2,17 @@
+Thu Feb 20 20:20:20 UTC 2020 - [email protected]
+
+- Add ocaml-ocaml.rpm.prov_req.attr.sh
+  New script for rpm Provides/Requires, replacement for rpm
+  built-in ocaml(NAME)=hash, which covers bytecode and interfaces
+  Now it covers also native code via ocamlx(NAME)=HASH (bsc#1154874)
+- Update the filelist generator
+  Use awk to match directories in ocamls built-in ld.conf
+  C stublibs in default locations do not need a ld.so.conf entry
+  Remaining ld.so.conf files for stublibs go to the devel package
+- Disable debug in ocamlfind() Provides/Requires generator
+  Update META parser to handle multiline statements and ppx
+- Provide a ocaml_standard_library macro
+- Explicitly preserve debuginfo in .cmxs, already enforced by dune
+- Install also COPYRIGHT.txt as license, needed for some JaneStreet pkgs
+
+-------------------------------------------------------------------

New:
----
  ocaml-ocaml.rpm.prov_req.attr.sh

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ocaml-rpm-macros.spec ++++++
--- /var/tmp/diff_new_pack.MhIsiE/_old  2020-02-26 15:01:45.300797156 +0100
+++ /var/tmp/diff_new_pack.MhIsiE/_new  2020-02-26 15:01:45.300797156 +0100
@@ -16,14 +16,16 @@
 #
 
 Name:           ocaml-rpm-macros
-Version:        20191101
+Version:        20200220
 Release:        0
 Summary:        RPM macros for building OCaml source packages
 License:        GPL-2.0-only
 Group:          Development/Languages/OCaml
 Url:            https://build.opensuse.org/project/show/devel:languages:ocaml
+Source0:        ocaml-ocaml.rpm.prov_req.attr.sh
 Source1:        ocaml-findlib.rpm.prov_req.attr.sh
 
+%define ocaml_standard_library %{_libdir}/ocaml
 %define do_opt 0
 # macros to be set in prjconf:
 #Macros:
@@ -60,13 +62,25 @@
 %build
 
 %install
+# map ocamlobjinfo output to rpm Provides/Requires
+tag="ocaml"
+mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
+tee %{buildroot}%{_rpmconfigdir}/fileattrs/z${tag}.attr <<_EOF_
+%__${tag}_provides %%{_rpmconfigdir}/${tag}.sh --provides
+%__${tag}_requires %%{_rpmconfigdir}/${tag}.sh --requires
+%__${tag}_magic    ^(ELF|Objective caml|OCaml) .*$
+%__${tag}_path     .(cma|cmi|cmo|cmx|cmxa|cmxs)$
+_EOF_
+#
+tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE0}
+
 # map findlib names to rpm Provides/Requires
 tag="ocamlfind"
 mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
 tee %{buildroot}%{_rpmconfigdir}/fileattrs/${tag}.attr <<_EOF_
 %__${tag}_provides %%{_rpmconfigdir}/${tag}.sh -prov
 %__${tag}_requires %%{_rpmconfigdir}/${tag}.sh -req
-%__${tag}_path     ^%%{_libdir}/ocaml/.*/META$|^%%{_libdir}/ocaml/META$
+%__${tag}_path     
^%{ocaml_standard_library}/.*/META$|^%{ocaml_standard_library}/META$
 _EOF_
 #
 tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1}
@@ -74,12 +88,23 @@
 # install OCaml macros
 mkdir -vp %{buildroot}%{_rpmmacrodir}
 tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_'
+# Guidelines:
+# - Providing applications written in OCaml is the main goal of our packaging.
+# - Applications written in OCaml are static binaries.
+# - A concept of shared libraries does not exist, beside the Dynlink module
+# - All binaries go into the main package, in case they are produced.
+# - All modules go into the -devel subpackage
+# - Helper applications below %{ocaml_standard_library} go into the -devel 
subpackage
+# - License files go into the main package.
+# - To aid debugging of cmxs files, their debuginfo is preserved by removing 
the executable bit.
+# 
 # get rid of %{_rpmconfigdir}/find-debuginfo.sh
 # strip kills the bytecode part of ELF binaries
 #
 # provide empty _find_debuginfo_dwz_opts
 # the .dwz files contains identical contents, which leads to identical
 # checksums, which leads to file conflicts due to identical symlinks
+%%ocaml_standard_library %{ocaml_standard_library}
 %if %{do_opt}
 %%ocaml_preserve_bytecode \
        %%define _lto_cflags %%{nil} \
@@ -108,12 +133,13 @@
        COPYING \\\
        COPYING.txt \\\
        COPYRIGHT \\\
+       COPYRIGHT.txt \\\
        Copyright \\\
+       LGPL \\\
        LICENCE \\\
        LICENSE \\\
        LICENSE.md \\\
        LICENSE.txt \\\
-       LGPL \\\
        ;\
        do\
 %if 0%{?suse_version} > 1315
@@ -123,103 +149,178 @@
 %endif
          test -f "${license}" && echo "%%%%${license_macro} ${license}" >> 
'%%{name}.files.license' ;\
        done ;\
-       find %%{buildroot}$(ocamlc -where) | sed -ne '\
-       s@^%%{buildroot}@@\
-       #\
+       find %%{buildroot}%%{ocaml_standard_library} -name '*.cmxs' -exec chmod 
-v a-x '{}' +\
+       find %%{buildroot}%%{ocaml_standard_library} ! -type d | awk\\\
+               -v "buildroot=%%{buildroot}"\\\
+               -v "ocaml_standard_library=%%{ocaml_standard_library}"\\\
+               -v "out_files_devel=%%{name}.files.devel"\\\
+               -v "out_files_ldconf=%%{name}.files.ldsoconf"\\\
+               -v "out_files_unhandled=%%{name}.files.unhandled"\\\
+               -v "ocaml_ldconf=$(ls -1d %%{ocaml_standard_library}/ld.conf || 
: ld.conf not found)"\\\
+               '\
+       BEGIN {\
+               nr=0\
+               if (ocaml_ldconf != "") {\
+                       do {\
+                               r = getline < ocaml_ldconf\
+                               if (r > 0) {\
+                                       ldconf[nr++]=$0\
+                               }\
+                       } while (r > 0)\
+               }\
+       }\
+       function _split (line) {\
+               file_path=substr(line, length(buildroot) + 1)\
+               m=match(file_path, "/[^/]+$")\
+               dirname=substr(file_path, 0, m - 1)\
+               basename=substr(file_path, m + 1)\
+               if (dirname == ocaml_standard_library) {\
+                       # do not package above standard_library\
+                       parent_dir=""\
+               } else {\
+                       m=match(dirname, "/[^/]+$")\
+                       parent_dir=substr(dirname, 0, m - 1)\
+               }\
+       }\
+       function files_ldconf(line) {\
+               _split(line)\
+               print file_path >> out_files_devel\
+               print "%%dir " dirname >> out_files_devel\
+               for (ldconf_dir in ldconf) {\
+                       if (dirname == ldconf[ldconf_dir]) {\
+                               # done with this cycle, ocaml ld.conf covers it\
+                               next\
+                       }\
+               }\
+               print dirname >> out_files_ldconf\
+               next\
+       }\
+       function files_devel(line) {\
+               _split(line)\
+               print file_path >> out_files_devel\
+               print "%%dir " dirname >> out_files_devel\
+               if (parent_dir != "") {\
+                       print "%%dir " parent_dir >> out_files_devel\
+               }\
+               next\
+       }\
+       function files_unhandled(line) {\
+               _split(line)\
+               print file_path >> out_files_unhandled\
+               next\
+       }\
        # for findlib, describing a package\
-       /\\/META$/{ b files_devel }\
+       /\\/META$/{\
+               files_devel($0)\
+       }\
        # stub ELF library\
-       /\\/[^/]\\+\\.so$/{       b files_ldsoconf }\
+       /\\/[^/]+\.so$/{\
+               files_ldconf($0)\
+       }\
        # stub ELF library\
-       /\\/[^/]\\+\\.so.owner$/{ b files_ldsoconf }\
+       /\\/[^/]+\.so.owner$/{\
+               files_ldconf($0)\
+       }\
        # ELF archive with object files\
-       /\\/[^/]\\+\\.a$/{     b files_devel }\
+       /\\/[^/]+\.a$/{\
+               files_devel($0)\
+       }\
        # OCaml legacy source code annotations, produced via -annot\
-       /\\/[^/]\\+\\.annot$/{ b files_devel }\
+       /\\/[^/]+\.annot$/{\
+               files_devel($0)\
+       }\
        # OCaml library file with bytecode\
-       /\\/[^/]\\+\\.cma$/{   b files_devel }\
+       /\\/[^/]+\.cma$/{\
+               files_devel($0)\
+       }\
        # OCaml compiled header file\
-       /\\/[^/]\\+\\.cmi$/{   b files_devel }\
+       /\\/[^/]+\.cmi$/{\
+               files_devel($0)\
+       }\
        # OCaml object file with bytecode\
-       /\\/[^/]\\+\\.cmo$/{   b files_devel }\
+       /\\/[^/]+\.cmo$/{\
+               files_devel($0)\
+       }\
        # OCaml source code annotations, produced via -bin-annot from source 
files\
-       /\\/[^/]\\+\\.cmt$/{   b files_devel }\
+       /\\/[^/]+\.cmt$/{\
+               files_devel($0)\
+       }\
        # OCaml source code annotations, produced via -bin-annot from header 
files\
-       /\\/[^/]\\+\\.cmti$/{  b files_devel }\
+       /\\/[^/]+\.cmti$/{\
+                files_devel($0)\
+       }\
        # OCaml object file with native code\
-       /\\/[^/]\\+\\.cmx$/{   b files_devel }\
+       /\\/[^/]+\.cmx$/{\
+               files_devel($0)\
+       }\
        # OCaml library file with native code\
-       /\\/[^/]\\+\\.cmxa$/{  b files_devel }\
+       /\\/[^/]+\.cmxa$/{\
+               files_devel($0)\
+       }\
        # ELF shared library with native code\
-       /\\/[^/]\\+\\.cmxs$/{  b files_devel }\
+       /\\/[^/]+\.cmxs$/{\
+               files_devel($0)\
+       }\
        # Some helper binary\
-       /\\/[^/]\\+\\.exe$/{   b files_devel }\
+       /\\/[^/]+\.exe$/{\
+               files_devel($0)\
+       }\
        # C header\
-       /\\/[^/]\\+\\.h$/{     b files_devel }\
+       /\\/[^/]+\.h$/{\
+               files_devel($0)\
+       }\
        #\
-       /\\/[^/]\\+\\.js$/{    b files_devel }\
+       /\\/[^/]+\.js$/{\
+               files_devel($0)\
+       }\
        # OCaml source code, source file\
-       /\\/[^/]\\+\\.ml$/{    b files_devel }\
+       /\\/[^/]+\.ml$/{\
+               files_devel($0)\
+       }\
        # OCaml source code, header file\
-       /\\/[^/]\\+\\.mli$/{   b files_devel }\
+       /\\/[^/]+\.mli$/{\
+               files_devel($0)\
+       }\
        # ELF object file\
-       /\\/[^/]\\+\\.o$/{     b files_devel }\
+       /\\/[^/]+\.o$/{\
+               files_devel($0)\
+       }\
        #\
-       /\\/[^/]\\+\\.sml$/{   b files_devel }\
-       #\
-       /\\/dune-package$/{    b files_devel }\
-       #\
-       /\\/opam$/{            b files_devel }\
+       /\\/[^/]+\.sml$/{\
+               files_devel($0)\
+       }\
+       # generated by dune\
+       /\\/dune-package$/{\
+               files_devel($0)\
+       }\
+       # generated by dune\
+       /\\/opam$/{\
+               files_devel($0)\
+       }\
        #\
        # record unknown paths\
-       w %%{name}.files.unhandled\
-       d\
-       #\
-       : files_devel\
-       # full path for file\
-       w %%{name}.files.devel\
-       # tag + dirname\
-       s@\\/[^/]\\+$@@\
-       : tag_dirname\
-       s@^@%%dir @\
-       w %%{name}.files.devel\
-       # parent directory\
-       s@\\/[^/]\\+$@@\
-       w %%{name}.files.devel\
-       d\
-       #\
-       : files_ldsoconf\
-       # full path for file\
-       w %%{name}.files.devel\
-       # dirname for ld.so.conf\
-       s@\\/[^/]\\+$@@\
-       w %%{name}.files.ldsoconf\
-       b tag_dirname\
-       ' ;\
-       cat '%%{name}.files.license' >> '%%{name}.files' ; \
-       for i in \\\
-       %%{name}.files \\\
-       %%{name}.files.devel \\\
-       %%{name}.files.ldsoconf \\\
-       %%{name}.files.unhandled \\\
+       files_unhandled($0)\
+       END {\
        ;\
-       do\
-         sort -u $i > $$ ;\
-         mv $$ $i ;\
-       done ;\
+       }' ;\
+       cat '%%{name}.files.license' >> '%%{name}.files' ;\
        if test -s %%{name}.files.ldsoconf ;\
-       then \
+       then\
                ldsoconfd='/etc/ld.so.conf.d' ;\
                mkdir -vp "%%{buildroot}${ldsoconfd}" ;\
                tee "%%{buildroot}${ldsoconfd}/%%{name}.conf" < 
%%{name}.files.ldsoconf ;\
-               echo "%config ${ldsoconfd}/%%{name}.conf" >> %%{name}.files ;\
+               echo "%config ${ldsoconfd}/%%{name}.conf" >> 
%%{name}.files.devel ;\
        fi ;\
-       head -n 1234 \\\
+       for i in \\\
        %%{name}.files \\\
        %%{name}.files.devel \\\
        %%{name}.files.ldsoconf \\\
        %%{name}.files.unhandled \\\
        ;\
+       do\
+         sort -u $i > $$ ;\
+         mv $$ $i ;\
+       done ;\
        %%{nil}
 
 # setup.ml comes from oasis, but this is here for libs oasis depends on
@@ -277,7 +378,7 @@
 %%ocaml_oasis_install \
        ocaml setup.ml -install
 %%ocaml_oasis_findlib_install \
-       export OCAMLFIND_DESTDIR=%%{buildroot}`ocamlc -where` ; \
+       export OCAMLFIND_DESTDIR=%%{buildroot}%%{ocaml_standard_library} ; \
        export OCAMLFIND_LDCONF=/dev/null ; \
        mkdir -p $OCAMLFIND_DESTDIR ; \
        ocaml setup.ml -install
@@ -322,22 +423,22 @@
 %ifarch ppc64 ppc64le
        ulimit -s $((1024 * 64)) ; \
 %endif
-       dune_for_release= ; \
+       dune_for_release= ;\
        if test -f dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
        then \
                read dune_release_pkgs < 
dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
                
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
-       fi ; \
+       fi ;\
        dune install \\\
                --verbose \\\
                ${dune_for_release} \\\
                %%{?_smp_mflags} \\\
                --prefix=%%{_prefix} \\\
-               --libdir=$(ocamlc -where) \\\
+               --libdir=%%{ocaml_standard_library} \\\
                --destdir=%%{buildroot} \\\
                ${dune_release_pkgs//,/ } \\\
-               $OCAML_DUNE_INSTALL_ARGS ; \
-       rm -rfv %%{buildroot}%%{_prefix}/doc ; \
+               $OCAML_DUNE_INSTALL_ARGS ;\
+       rm -rfv %%{buildroot}%%{_prefix}/doc ;\
        if test -d %%{buildroot}%%{_prefix}/man ; then \
                mkdir -vp %%{buildroot}%%{_datadir} ; \
                mv -vt %%{buildroot}%%{_datadir} %%{buildroot}%%{_prefix}/man ; 
\

++++++ ocaml-findlib.rpm.prov_req.attr.sh ++++++
--- /var/tmp/diff_new_pack.MhIsiE/_old  2020-02-26 15:01:45.324797204 +0100
+++ /var/tmp/diff_new_pack.MhIsiE/_new  2020-02-26 15:01:45.324797204 +0100
@@ -33,14 +33,15 @@
       cmd="${cmd}" \
     awk '
       BEGIN {
-        dbg=1;
+        dbg=0;
         count=1;
         depth=0;
         pkg_name=ENVIRON["pkg_name"];
         cmd=ENVIRON["cmd"];
         
         if(dbg) printf "bEGIN \\"%s\\" cmd: %s\n", pkg_name, cmd > 
"/dev/stderr" ;
-        reqs[pkg_name]=""
+        requires[pkg_name]=""
+        ppx_runtime_deps[pkg_name]=""
         pkg_names[depth]=pkg_name
       }
       
@@ -73,8 +74,8 @@
             }
             if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
             if (candidate != pkg_name) {
-              reqs[candidate] = reqs[pkg_name];
-              delete reqs[pkg_name];
+              requires[candidate] = requires[pkg_name];
+              delete requires[pkg_name];
               pkg_name = candidate;
               if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > 
"/dev/stderr" ;
               pkg_names[depth]=pkg_name
@@ -86,14 +87,76 @@
         next
       }
 
-      /^[[:blank:]]*requires.*[[:blank:]]*=/ {
+      /^[[:blank:]]*requires(|\([^)]+\))[[:blank:]]*(+=|=)/ {
         if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
-        x = split($0, a, "\\"");
+        done=0
+        requires_line = ""
+        do {
+          need_next_line = 1
+          line = $0
+          requires_line = sprintf("%s%s", requires_line, line)
+          l = length(requires_line)
+          qm = index(requires_line, "\\"")
+          if (l > qm) {
+            line = substr(requires_line, qm + 1)
+            qm = index(line, "\\"")
+            need_next_line = qm == 0
+          }
+
+          if (need_next_line) {
+            done = getline == 0
+          } else {
+            done = 1
+          }
+        } while (done == 0)
+
+        x = split(requires_line, a, "\\"");
         if ( a[2] ) {
           if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
           x = gsub("[[:blank:]]+", ",", a[2]);
           if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
-          reqs[pkg_name] = a[2];
+          if (requires[pkg_name] == "") {
+            requires[pkg_name] = a[2]
+          } else {
+            requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2])
+          }
+        }
+        next
+      }
+
+      /^[[:blank:]]*ppx_runtime_deps[[:blank:]]*(+=|=)/ {
+        if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
+        done=0
+        ppx_runtime_deps_line = ""
+        do {
+          need_next_line = 1
+          line = $0
+          ppx_runtime_deps_line = sprintf("%s%s", ppx_runtime_deps_line, line)
+          l = length(ppx_runtime_deps_line)
+          qm = index(ppx_runtime_deps_line, "\\"")
+          if (l > qm) {
+            line = substr(ppx_runtime_deps_line, qm + 1)
+            qm = index(line, "\\"")
+            need_next_line = qm == 0
+          }
+
+          if (need_next_line) {
+            done = getline == 0
+          } else {
+            done = 1
+          }
+        } while (done == 0)
+
+        x = split(ppx_runtime_deps_line, a, "\\"");
+        if ( a[2] ) {
+          if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
+          x = gsub("[[:blank:]]+", ",", a[2]);
+          if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
+          if (ppx_runtime_deps[pkg_name] == "") {
+            ppx_runtime_deps[pkg_name] = a[2]
+          } else {
+            requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2])
+          }
         }
         next
       }
@@ -106,7 +169,7 @@
         if ( a[2] ) {
           if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
           pkg_name = pkg_name"."a[2];
-          reqs[pkg_name]=""
+          requires[pkg_name]=""
           pkg_names[depth]=pkg_name
           if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
         }
@@ -124,10 +187,15 @@
       
       END {
         if(dbg) printf "eND \\"%s\\"\n", pkg_name > "/dev/stderr" ;
-        for (req in reqs) {
+        for (req in requires) {
+          if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
+          # format: provides:requires
+          printf "%s:%s\n", req, requires[req];
+        }
+        for (req in ppx_runtime_deps) {
           if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
           # format: provides:requires
-          printf "%s:%s\n", req, reqs[req];
+          printf "%s:%s\n", req, ppx_runtime_deps[req];
         }
         if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ;
       }
@@ -158,3 +226,4 @@
     *) ;;
   esac
 done
+# vim: tw=666 ts=2 shiftwidth=2 et

++++++ ocaml-ocaml.rpm.prov_req.attr.sh ++++++
#!/bin/bash
# This is a helper for rpm which collects 'Provides' and 'Requires' information 
from OCaml files.
# It reads a list of filenames from STDIN.
# It expects as argument either '--provides|-P' or '--requires|-R'.
# Additional optional arguments are:
# -f "ocamlobjinfo command"
# -c # ignored, recognized just for compat reasons
# -i NAME # omit the Requires/Provides for this bytecode unit name
# -x NAME # omit the Requires/Provides for this native unit name
#
# OCaml object files contain either bytecode or native code.
# Each bytecode variant provides a certain interface, which is represented by a 
hash.
# Each native variant provides a certain interface and a certain 
implementation, which are represented by hashes.
# Each variant may also require a certain interface and/or implementation 
provided by other files.
# The details for each file can be inspected with 'ocamlobjinfo'.
#
# Each file contains at least one module.
# Information about each module follows after a line starting with "Name:" or 
"Unit name:":
#
# cma/cmi/cmo (bytecode):
#   Unit name: NAME
#   Interfaces imported:
#     HASH NAME
#     HASH NAME_FROM_OTHER_MODULE
#
# cmx/cmxa/cmxs (native):
#   Name: NAME
#   CRC of implementation: HASH
#   Interfaces imported:
#     HASH NAME
#     HASH NAME_FROM_OTHER_MODULE
#   Implementations imported:
#     HASH NAME_FROM_OTHER_MODULE
#
# The hash may contain just '-', in which case it is ignored.
#
# Output:
# ocaml(NAME) = HASH # for interfaces (bytecode and native)
# ocamlx(NAME) = HASH # for implementations (native)

set -e
#
OCAMLOBJINFO=ocamlobjinfo
rpm_prefix_interface='ocaml'
rpm_prefix_implementation='ocamlx'
#
parse() {
  local filename="$1"

  ${OCAMLOBJINFO} "${filename}" | awk '
  BEGIN {
    debug=0
    mode=ENVIRON["mode"]
    RPM_BUILD_ROOT=ENVIRON["RPM_BUILD_ROOT"]
    rpm_prefix_interface=ENVIRON["rpm_prefix_interface"]
    rpm_prefix_implementation=ENVIRON["rpm_prefix_implementation"]
    state="find"
    unit=""

    split(ENVIRON["ignore_implementation"], ignore_implementation_a)
    for (i in ignore_implementation_a) {
      val=ignore_implementation_a[i]
      if (debug)
        printf "INFO: ignore_implementation %s\n", val  > "/dev/stderr"
      ignore_implementation[val]=1
    }
    split(ENVIRON["ignore_interface"], ignore_interface_a)
    for (i in ignore_interface_a) {
      val=ignore_interface_a[i]
      if (debug)
        printf "INFO: ignore_interface %s\n", val  > "/dev/stderr"
      ignore_interface[val]=1
    }
  }

  /^File / {
    if (RPM_BUILD_ROOT != "" ) {
      file=substr($2,length(RPM_BUILD_ROOT)+1)
    } else {
      file=$2
    }
    state="file"
    next
  }
  /^Unit name:/ {
    unit=$3
    state="cma"
    next
  }
  /^Name:/ {
    unit=$2
    state="cmx"
    next
  }

  /^CRC of implementation:/ {
    if (state == "cmx") {
      if (ignore_implementation[unit] != "") {
        if (ignore_implementation[unit] != "seen") {
          printf "INFO: ignoring Provides %s(%s)=%s from %s\n", 
rpm_prefix_implementation, unit, $4, file  > "/dev/stderr"
          ignore_implementation[unit]="seen"
        }
      } else {
        implementation_provides[unit]=$4
      }
    } else {
      printf "WARN: state %s, expected cmx, got %s\n", state, $0 > "/dev/stderr"
    }
    state="crc"
    next
  }

  /^Interfaces imported:/ {
    state="interface"
    next
  }

  /^Implementations imported:/ {
    state="implementation"
    next
  }

  /^\t/ {
    if (state == "interface" && NF > 1 && match($1, "^-") == 0) {
      if (unit == $2) {
        if (ignore_interface[unit] != "") {
          if (ignore_interface[unit] != "seen") {
            printf "INFO: ignoring Provides %s(%s)=%s from %s\n", 
rpm_prefix_interface, unit, $1, file  > "/dev/stderr"
            ignore_interface[unit]="seen"
          }
        } else {
          interface_provides[unit]=$1
        }
      } else {
        if (ignore_interface[$2] != "") {
          if (ignore_interface[$2] != "seen") {
            printf "INFO: ignoring Requires %s(%s)=%s from %s\n", 
rpm_prefix_interface, $2, $1, file  > "/dev/stderr"
            ignore_interface[$2]="seen"
          }
        } else {
          interface_requires[$2]=$1
        }
      }
      next
    } else if (state == "implementation" && NF > 1 && match($1, "^-") == 0) {
      if (unit == $2) {
        if (ignore_implementation[unit] != "") {
          if (ignore_implementation[unit] != "seen") {
            printf "INFO: ignoring Provides %s(%s)=%s from %s\n", 
rpm_prefix_implementation, unit, $1, file  > "/dev/stderr"
            ignore_implementation[unit]="seen"
          }
        } else {
          implementation_provides[unit]=$1
        }
      } else {
        if (ignore_implementation[$2] != "") {
          if (ignore_implementation[$2] != "seen") {
            printf "INFO: ignoring Requires %s(%s)=%s from %s\n", 
rpm_prefix_implementation, $2, $1, file  > "/dev/stderr"
            ignore_implementation[$2]="seen"
          }
        } else {
          implementation_requires[$2]=$1
        }
      }
      next
    } else  {
      next
    }
  }
  /^.*/ {
    state="find"
  }

  END {
    if (mode == "provides") {
      for (i in interface_provides) {
        printf "%s(%s) = %s\n", rpm_prefix_interface, i, interface_provides[i]
      }
      for (i in implementation_provides) {
        printf "%s(%s) = %s\n", rpm_prefix_implementation, i, 
implementation_provides[i]
      }
    }
    if (mode == "requires") {
      for (i in interface_requires) {
        printf "%s(%s) = %s\n", rpm_prefix_interface, i, interface_requires[i]
      }
      for (i in implementation_requires) {
        printf "%s(%s) = %s\n", rpm_prefix_implementation, i, 
implementation_requires[i]
      }
    }
  }
  '
}
#
#
usage() {
    echo >&2 "Usage: ${0##*/} -provides|-requires [-f 'ocamlobjinfo cmd']"
}
#
mode=
ignore_implementation_a=()
ignore_interface_a=()
while test "$#" -gt 0
do
  : "${1}" "${2}"
  case "${1}" in
    -P|--provides) mode='provides' ;;
    -R|--requires) mode='requires' ;;
    -i) ignore_interface_a+=("$2") ; shift ;;
    -x) ignore_implementation_a+=("$2") ; shift ;;
    -f) OCAMLOBJINFO="$2"; shift ;;
    -h|--help) usage ; exit 0 ;;
    -c) ;; # ignored
    --) break ;;
    *) usage ; exit 1 ;;
  esac
  shift
done
if test -z "${mode}" 
then
  usage
  exit 1
fi
#
export rpm_prefix_interface
export rpm_prefix_implementation
export mode
export ignore_implementation="${ignore_implementation_a[@]}"
export ignore_interface="${ignore_interface_a[@]}"
#
while read filename
do
  case "${filename}" in
  *.cma)  parse "${filename}" ;;
  *.cmi)  parse "${filename}" ;;
  *.cmo)  parse "${filename}" ;;
  *.cmx)  parse "${filename}" ;;
  *.cmxa) parse "${filename}" ;;
  *.cmxs) parse "${filename}" ;;
  *) continue ;;
  esac
done
# vim: tw=666 ts=2 shiftwidth=2 et

Reply via email to