Nice! There's a _LOT_ that can be with a macro context object
as a bag of KEY:VALUE string pairs for templating.

There's a fair amount of work to use multiple macro contexts
with RPM itself for hysterical reasons. But macro expansions
are a cheap means to use any of the embeddings, and there's
always %(...) to fire up helpers.

hth

73 de Jeff

On Oct 30, 2010, at 7:31 PM, Eric Veith wrote:

>  RPM Package Manager, CVS Repository
>  http://rpm5.org/cvs/
>  ____________________________________________________________________________
> 
>  Server: rpm5.org                         Name:   Eric Veith
>  Root:   /v/rpm/cvs                       Email:  eve...@rpm5.org
>  Module: rpm                              Date:   31-Oct-2010 01:31:26
>  Branch: HEAD                             Handle: 2010103023312600
> 
>  Modified files:
>    rpm/ruby                rpmmc-rb.c
> 
>  Log:
>    Add macro name/opts/body split code from lua to rpmmc-rb.c's list code
>    - Add split code from rpmio/rpmlua.c
>    - Add more type checking with Ruby's Check_Type macro
> 
>  Summary:
>    Revision    Changes     Path
>    1.4         +127 -29    rpm/ruby/rpmmc-rb.c
>  ____________________________________________________________________________
> 
>  patch -p0 <<'@@ .'
>  Index: rpm/ruby/rpmmc-rb.c
>  ============================================================================
>  $ cvs diff -u -r1.3 -r1.4 rpmmc-rb.c
>  --- rpm/ruby/rpmmc-rb.c      2 May 2009 17:16:25 -0000       1.3
>  +++ rpm/ruby/rpmmc-rb.c      30 Oct 2010 23:31:26 -0000      1.4
>  @@ -9,9 +9,11 @@
> 
>   #define     _MACRO_INTERNAL
>   #include <rpmmacro.h>
>  +#include <rpmio/argv.h>
> 
>   #include "../debug.h"
> 
>  +
>   typedef MacroContext rpmmc;
> 
>   VALUE rpmmcClass;
>  @@ -19,7 +21,9 @@
>   /*...@unchecked@*/
>   static int _debug = 0;
> 
>  +
>   /* --- helpers */
>  +
>   static void *
>   rpmmc_ptr(VALUE s)
>   {
>  @@ -28,65 +32,142 @@
>       return ptr;
>   }
> 
>  +
>   /* --- Object methods */
>  +
>  +/**
>  + * Adds a new macro definition to the Macro Context.
>  + *
>  + * call-seq:
>  + *  RPM::Mc#add(macro) -> nil
>  + *
>  + * @param macro The macro definition in string form just like it would be 
> done
>  + *  in a macro definition file, but minus the %define stanza.
>  + * @see         rpmDefineMacro()
>  + */
>   static VALUE
>   rpmmc_add(VALUE s, VALUE v)
>   {
>  +    Check_Type(v, T_STRING);
>  +
>       void *ptr = rpmmc_ptr(s);
>       rpmmc mc = ptr;
>       int lvl = 0;
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p\n", __FUNCTION__, s, v, ptr);
>  +    
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p\n",
>  +            __FUNCTION__, s, v, ptr);
>  +    
>       (void) rpmDefineMacro(mc, StringValueCStr(v), lvl);
>  -    return Qtrue;
>  +    return Qnil;
>   }
> 
>  +
>  +/**
>  + * Deletes a macro definition.
>  + *
>  + * call-seq:
>  + *  RPM::Mc#del(macro) -> nil
>  + *
>  + * @param macro The macro name
>  + * @see         rpmUndefineMacro()
>  + */
>   static VALUE
>   rpmmc_del(VALUE s, VALUE v)
>   {
>  +    Check_Type(v, T_STRING);
>  +
>       void *ptr = rpmmc_ptr(s);
>       rpmmc mc = ptr;
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p\n", __FUNCTION__, s, v, ptr);
>  +    
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p\n",
>  +            __FUNCTION__, s, v, ptr);
>  +    
>       (void) rpmUndefineMacro(mc, StringValueCStr(v));
>  -    return Qtrue;
>  +    return Qnil;
>   }
> 
>  +
>  +/**
>  + * List all macro definitions in the corresponding Macro Context.
>  + *
>  + * call-seq:
>  + *  RPM::Mc#list() -> Array
>  + *
>  + * @return  A list of all macro definitions in form of an array of arrays,
>  + *  where each nested arry contains the macro's name, arguments (or an empty
>  + *  string) and the macro body.
>  + */
>   static VALUE
>   rpmmc_list(VALUE s)
>   {
>       void *ptr = rpmmc_ptr(s);
>       rpmmc mc = ptr;
>  -    VALUE v = rb_ary_new();
>       void * _mire = NULL;
>  +    VALUE v = rb_ary_new();
>       int used = -1;
>       const char ** av = NULL;
>       int ac = rpmGetMacroEntries(mc, _mire, used, &av);
> 
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx) ptr %p\n", __FUNCTION__, s, ptr);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx) ptr %p\n", __FUNCTION__, s, ptr);
> 
>       if (ac > 0 && av != NULL && av[0] != NULL) {
>  -    int i;
>  -    for (i = 0; i < ac; i++) {
>  -        /* XXX lua splits into {name,opts,body} triple. */
>  -        rb_ary_push(v, rb_str_new2(av[i]));
>  -    }
>  +        int i;
>  +        for (i = 0; i < ac; i++) {
>  +            /* Parse out "%name(opts)\tbody" into n/o/b strings. */
>  +
>  +            char *name = (char *)av[i];
>  +            char *body = strchr(name, '\t');
>  +            assert(body != NULL);
>  +            char *opts = ((body > name && body[-1] == ')') ?
>  +                strchr(name, '(') : NULL);
>  +
>  +            if (*name == '%') name++;
>  +            if (opts != NULL && *opts == '(') {
>  +                body[-1] = '\0';
>  +                opts++;
>  +                opts[-1] = '\0';
>  +            } else {
>  +                body[0] = '\0';
>  +                opts = "";
>  +            }
>  +            body++;
>  +
>  +            VALUE nob_ary = rb_ary_new3(3, rb_str_new2(name),
>  +                rb_str_new2(opts), rb_str_new2(body));
>  +            rb_ary_push(v, nob_ary);
>  +        }
>       }
>  +
>  +    argvFree(av);
>       return v;
>   }
> 
>  +
>  +/**
>  + * Expands a macro.
>  + *
>  + * call-seq:
>  + *  RPM::Mc#expand(macro) -> String
>  + *
>  + * @param macro The macro name (with leading % sign)
>  + * @return      The result of the expansion
>  + */
>   static VALUE
>   rpmmc_expand(VALUE s, VALUE v)
>   {
>       void *ptr = rpmmc_ptr(s);
>       rpmmc mc = ptr;
>       char * vstr = StringValueCStr(v);
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p \"%s\"\n", __FUNCTION__, s, v, 
> ptr, vstr);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p \"%s\"\n",
>  +            __FUNCTION__, s, v, ptr, vstr);
>       return rb_str_new2(rpmMCExpand(mc, vstr, NULL));
>   }
> 
>  +
>   static void
>   initMethods(VALUE klass)
>   {
>  @@ -96,23 +177,35 @@
>       rb_define_method(klass, "expand", rpmmc_expand, 1);
>   }
> 
>  +
>   /* --- Object properties */
>  +
>  +/**
>  + * Get debugging log level
>  + *
>  + * call-seq:
>  + *  RPM::Mc#debug -> Fixnum
>  + *
>  + * @return The debugging level
>  + */
>   static VALUE
>   rpmmc_debug_get(VALUE s)
>   {
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx)\n", __FUNCTION__, s);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx)\n", __FUNCTION__, s);
>       return INT2FIX(_debug);
>   }
> 
>  +
>   static VALUE
>   rpmmc_debug_set(VALUE s, VALUE v)
>   {
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx, 0x%lx)\n", __FUNCTION__, s, v);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx, 0x%lx)\n", __FUNCTION__, s, v);
>       return INT2FIX(_debug = FIX2INT(v));
>   }
> 
>  +
>   static void
>   initProperties(VALUE klass)
>   {
>  @@ -120,37 +213,42 @@
>       rb_define_method(klass, "debug=", rpmmc_debug_set, 1);
>   }
> 
>  +
>   /* --- Object ctors/dtors */
>  +
>   static void
>   rpmmc_free(rpmmc mc)
>   {
>  -if (_debug)
>  -fprintf(stderr, "==> %s(%p)\n", __FUNCTION__, mc);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(%p)\n", __FUNCTION__, mc);
> 
>       if (!(mc == rpmGlobalMacroContext || mc == rpmCLIMacroContext)) {
>  -    rpmFreeMacros(mc);
>  -    mc = _free(mc);
>  +        rpmFreeMacros(mc);
>  +        mc = _free(mc);
>       }
>   }
> 
>  +
>   static VALUE
>   rpmmc_alloc(VALUE klass)
>   {
>       rpmmc mc = xcalloc(1, sizeof(*mc));
>       VALUE obj = Data_Wrap_Struct(klass, 0, rpmmc_free, mc);
>  -if (_debug)
>  -fprintf(stderr, "==> %s(0x%lx) obj 0x%lx mc %p\n", __FUNCTION__, klass, 
> obj, mc);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s(0x%lx) obj 0x%lx mc %p\n",
>  +            __FUNCTION__, klass, obj, mc);
>       return obj;
>   }
> 
>  +
>   /* --- Class initialization */
> 
>   void
>   Init_rpmmc(void)
>   {
>  -    rpmmcClass = rb_define_class("Mc", rb_cObject);
>  -if (_debug)
>  -fprintf(stderr, "==> %s() rpmmcClass 0x%lx\n", __FUNCTION__, rpmmcClass);
>  +    rpmmcClass = rb_define_class_under(rpmModule, "Mc", rb_cObject);
>  +    if (_debug)
>  +        fprintf(stderr, "==> %s() rpmmcClass 0x%lx\n", __FUNCTION__, 
> rpmmcClass);
>       rb_define_alloc_func(rpmmcClass, rpmmc_alloc);
>       initProperties(rpmmcClass);
>       initMethods(rpmmcClass);
>  @@ .
> ______________________________________________________________________
> RPM Package Manager                                    http://rpm5.org
> CVS Sources Repository                                rpm-...@rpm5.org

______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
Developer Communication List                        rpm-devel@rpm5.org

Reply via email to