From 2b0222bf310ddfd221e18d0bae46e803c04db1d2 Mon Sep 17 00:00:00 2001 From: Christiaan Welvaart Date: Thu, 7 Jul 2011 16:29:04 +0000 Subject: - extract gobject introspection typelib interdependencies using a helper program --- Makefile.am | 11 +++++-- NEWS | 3 ++ configure.ac | 2 +- g-ir-extract-deps.c | 68 +++++++++++++++++++++++++++++++++++++++ gi-find-deps.sh | 85 ------------------------------------------------- gi-find-deps.sh.in | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 89 deletions(-) create mode 100644 g-ir-extract-deps.c delete mode 100755 gi-find-deps.sh create mode 100755 gi-find-deps.sh.in diff --git a/Makefile.am b/Makefile.am index aa517c1..73750d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,19 +51,20 @@ pkg_scripts = \ pythoneggs.py \ rubygems.rb \ desktop-file.prov \ - fontconfig.prov \ - gi-find-deps.sh + fontconfig.prov pkg_gscripts = \ find-provides \ find-requires \ - find-provides.perl + find-provides.perl \ + gi-find-deps.sh pkg_scripts_in = $(pkg_gscripts:=.in) BUILT_SOURCES = macros-perarch make_arch_macrosfiles.sh rpmgenplatform pkglibdir = @RPMVENDORDIR@ +pkglibexecdir = @RPMVENDORDIR@ noinst_PROGRAMS = rpmeval @@ -71,6 +72,10 @@ rpmeval_SOURCES = rpmeval.c rpmeval_LDFLAGS = -lrpm +pkglibexec_PROGRAMS = g-ir-extract-deps + +g_ir_extract_deps_SOURCES = g-ir-extract-deps.c + noinst_DATA = $(pkg_gconfig) pkglib_DATA = \ diff --git a/NEWS b/NEWS index 05272cc..0097ae4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +Version 1.137 - 7 July 2011, by Christiaan Welvaart +- extract gobject introspection typelib interdependencies using a helper program + Version 1.136 - 6 July 2011, by Nicolas Vigier - fix typo added in find-requires script diff --git a/configure.ac b/configure.ac index 10acd63..c3aef0b 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ # $Id: configure.ac 271266 2010-11-04 10:43:28Z fwang $ AC_PREREQ(2.59) -AC_INIT(rpm-mageia-setup, 1.136, boklm@mars-attacks.org) +AC_INIT(rpm-mageia-setup, 1.137, boklm@mars-attacks.org) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(1.9 -Wno-portability) AC_CONFIG_SRCDIR diff --git a/g-ir-extract-deps.c b/g-ir-extract-deps.c new file mode 100644 index 0000000..1c1735d --- /dev/null +++ b/g-ir-extract-deps.c @@ -0,0 +1,68 @@ +/* + extract the dependencies string from a GObject Introspection 1.0 typelib file + and print it on stdout +*/ + +#include +#include +#include + +#define G_IR_MAGIC "GOBJ\nMETADATA\r\n\032" + +int main(int argc, char ** argv) +{ + FILE * typelib; + char * magic; + uint32_t deps_offset; + char * deps; + + if (argc < 2) + { + fprintf(stderr, "too few arguments\n"); + exit(1); + } + + typelib = fopen(argv[1], "r"); + if (typelib == NULL) + { + fprintf(stderr, "failed to open %s\n", argv[1]); + exit(1); + } + magic = malloc(16); + deps = malloc(8192); + if ((magic == NULL) || (deps == NULL)) + { + fprintf(stderr, "failed to allocate memory\n"); + exit(1); + } + if (fread(magic, 16, 1, typelib) < 1) + { + fprintf(stderr, "failed to read magic from typelib\n"); + exit(1); + } + if (strcmp(magic, G_IR_MAGIC)) + { + fprintf(stderr, "magic mismatch, not a typelib?\n"); + exit(1); + } + + fseek(typelib, 36, SEEK_SET); + if (fread(&deps_offset, 4, 1, typelib) < 1) + { + fprintf(stderr, "failed to read deps offset from typelib\n"); + exit(1); + } + fseek(typelib, deps_offset, SEEK_SET); + if (fscanf(typelib, "%8191s", deps) < 1) + { + fprintf(stderr, "failed to read deps from typelib\n"); + exit(1); + } + + free(deps); + free(magic); + fclose(typelib); + + printf("%s\n", deps); + return 0; +} diff --git a/gi-find-deps.sh b/gi-find-deps.sh deleted file mode 100755 index 5cb3905..0000000 --- a/gi-find-deps.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/sh - -# Automatically find Provides and Requires for typelib() gobject-introspection bindings. -# can be started with -R (Requires) and -P (Provides) - -# Copyright 2011 by Dominique Leuenberger, Amsterdam, Netherlands (dimstar [at] opensuse.org) -# This file is released under the GPLv2 or later. - -function split_name_version { -base=$1 -tsymbol=${base%-*} -# Sometimes we get a Requires on Gdk.Settings.foo, bebause you can directly use imports.gi.Gdk.Settings.Foo in Javascript. -# We know that the symbol in this case is call Gdk, so we cut everything after the . away. -symbol=$(echo $tsymbol | awk -F. '{print $1}') -version=${base#*-} -# In case there is no '-' in the filename, then the split above 'fails' and version == symbol (thus: no version specified) -if [ "$tsymbol" = "$version" ]; then - unset version -fi -} - -function print_req_prov { -echo -n "typelib($symbol)" -if [ ! -z "$version" ]; then - echo " = ${version}" -else - echo "" -fi -} - -function find_provides { -while read file; do - case $file in - *.typelib) - split_name_version $(basename $file | sed 's,.typelib$,,') - print_req_prov - ;; - esac -done -} - -function find_requires { -# FIXME: There are multiple ways gi bindings can be imported. We only catch the 'basic' one -# Currently, we detect: -# - in python: -# . from gi.repository import foo [Unversioned requirement of 'foo'] -# . from gi.repository import foo-1.0 [versioned requirement] -# . And we do not stumble over: -# from gi.repository import foo as _bar -# from gi.repository import foo, bar -# - in JS: -# . imports.gi.foo; [unversioned requirement of 'foo'] -# . imports.gi.goo-1.0; [versioned requirement] -# . The imports can be listed on one line, and we catch them. -# Forms currently not detected: -# - js: imports.gi.versions.Gtk = '3.0'; -# - py: gi.require_version('Gtk', '3.0') - -while read file; do - case $file in - *.js) - for module in $(grep -h -P -o "imports.gi.([^\s'\";]+)" $file | grep -v "imports.gi.version" | sed 's,imports.gi.,,'); do - split_name_version $module - print_req_prov - done - ;; - *.py) - for module in $(grep -h -P "from gi.repository import (\w+)" $file | sed 's:#.*::' | sed -e 's,from gi.repository import,,' -r -e 's:\s+as\s+\w+::g' -e 's:,::g'); do - split_name_version $module - print_req_prov - done - ;; - esac -done -} - -case $1 in - -P) - find_provides - ;; - -R) - find_requires - ;; -esac - diff --git a/gi-find-deps.sh.in b/gi-find-deps.sh.in new file mode 100755 index 0000000..0a356c2 --- /dev/null +++ b/gi-find-deps.sh.in @@ -0,0 +1,91 @@ +#!/bin/sh + +# Automatically find Provides and Requires for typelib() gobject-introspection bindings. +# can be started with -R (Requires) and -P (Provides) + +# Copyright 2011 by Dominique Leuenberger, Amsterdam, Netherlands (dimstar [at] opensuse.org) +# This file is released under the GPLv2 or later. + +function split_name_version { +base=$1 +tsymbol=${base%-*} +# Sometimes we get a Requires on Gdk.Settings.foo, bebause you can directly use imports.gi.Gdk.Settings.Foo in Javascript. +# We know that the symbol in this case is call Gdk, so we cut everything after the . away. +symbol=$(echo $tsymbol | awk -F. '{print $1}') +version=${base#*-} +# In case there is no '-' in the filename, then the split above 'fails' and version == symbol (thus: no version specified) +if [ "$tsymbol" = "$version" ]; then + unset version +fi +} + +function print_req_prov { +echo -n "typelib($symbol)" +if [ ! -z "$version" ]; then + echo " = ${version}" +else + echo "" +fi +} + +function find_provides { +while read file; do + case $file in + *.typelib) + split_name_version $(basename $file | sed 's,.typelib$,,') + print_req_prov + ;; + esac +done +} + +function find_requires { +# FIXME: There are multiple ways gi bindings can be imported. We only catch the 'basic' one +# Currently, we detect: +# - in python: +# . from gi.repository import foo [Unversioned requirement of 'foo'] +# . from gi.repository import foo-1.0 [versioned requirement] +# . And we do not stumble over: +# from gi.repository import foo as _bar +# from gi.repository import foo, bar +# - in JS: +# . imports.gi.foo; [unversioned requirement of 'foo'] +# . imports.gi.goo-1.0; [versioned requirement] +# . The imports can be listed on one line, and we catch them. +# Forms currently not detected: +# - js: imports.gi.versions.Gtk = '3.0'; +# - py: gi.require_version('Gtk', '3.0') + +while read file; do + case $file in + *.js) + for module in $(grep -h -P -o "imports.gi.([^\s'\";]+)" $file | grep -v "imports.gi.version" | sed 's,imports.gi.,,'); do + split_name_version $module + print_req_prov + done + ;; + *.py) + for module in $(grep -h -P "from gi.repository import (\w+)" $file | sed 's:#.*::' | sed -e 's,from gi.repository import,,' -r -e 's:\s+as\s+\w+::g' -e 's:,::g'); do + split_name_version $module + print_req_prov + done + ;; + *.typelib) + for module in $(@RPMVENDORDIR@/g-ir-extract-deps $file | tr '|' ' '); do + split_name_version $module + print_req_prov + done + ;; + esac +done +} + +case $1 in + -P) + find_provides + ;; + -R) + find_requires + ;; +esac + -- cgit v1.2.1