rpm  5.4.4
ruby/rpmmc-rb.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include "rpm-rb.h"
00007 #include "rpmmc-rb.h"
00008 
00009 #define _MACRO_INTERNAL
00010 #include <rpmmacro.h>
00011 #include <rpmio/argv.h>
00012 
00013 #include "../debug.h"
00014 
00015 
00016 typedef MacroContext rpmmc;
00017 
00018 VALUE rpmmcClass;
00019 
00020 /*@unchecked@*/
00021 static int _debug = 0;
00022 
00023 
00027 static rpmmc
00028 _rpmmc_get_mc(VALUE self)
00029 {
00030     rpmmc mc;
00031     Data_Get_Struct(self, struct MacroContext_s, mc);
00032     return mc;
00033 }
00034 
00035 
00047 static VALUE
00048 rpmmc_add(VALUE self, VALUE macro)
00049 {
00050     Check_Type(macro, T_STRING);
00051 
00052     rpmmc mc = _rpmmc_get_mc(self);
00053     int lvl = 0;
00054     
00055     if (_debug)
00056         fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p\n",
00057             __FUNCTION__, self, macro, mc);
00058     
00059     int error = rpmDefineMacro(mc, RSTRING_PTR(macro), lvl);
00060     if(error)
00061         rpm_rb_raise(error, "Macro definition failed");
00062     return self;
00063 }
00064 
00065 
00076 static VALUE
00077 rpmmc_del(VALUE self, VALUE macro)
00078 {
00079     Check_Type(macro, T_STRING);
00080 
00081     rpmmc mc = _rpmmc_get_mc(self);
00082     
00083     if (_debug)
00084         fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p\n",
00085             __FUNCTION__, self, macro, mc);
00086     
00087     int error = rpmUndefineMacro(mc, StringValueCStr(macro));
00088     if(error)
00089         rpm_rb_raise(error, "Macro deletion failed");
00090     return self;
00091 }
00092 
00093 
00104 static VALUE
00105 rpmmc_list(VALUE self)
00106 {
00107     rpmmc mc = _rpmmc_get_mc(self);
00108 
00109     void * _mire = NULL;
00110     VALUE v = rb_ary_new();
00111     int used = -1;
00112     const char ** av = NULL;
00113     int ac = rpmGetMacroEntries(mc, _mire, used, &av);
00114 
00115     if (_debug)
00116         fprintf(stderr, "==> %s(0x%lx) ptr %p\n", __FUNCTION__, self, mc);
00117 
00118     if (ac > 0 && av != NULL && av[0] != NULL) {
00119         int i;
00120         for (i = 0; i < ac; i++) {
00121             /* Parse out "%name(opts)\tbody" into n/o/b strings. */
00122 
00123             char *name = (char *)av[i];
00124             char *body = strchr(name, '\t');
00125             assert(body != NULL);
00126             char *opts = ((body > name && body[-1] == ')') ?
00127                 strchr(name, '(') : NULL);
00128 
00129                 if (*name == '%') name++;
00130                 if (opts != NULL && *opts == '(') {
00131                 body[-1] = '\0';
00132                 opts++;
00133                 opts[-1] = '\0';
00134             } else {
00135                 body[0] = '\0';
00136                 opts = "";
00137             }
00138             body++;
00139 
00140             VALUE nob_ary = rb_ary_new3(3, rb_str_new2(name),
00141                 rb_str_new2(opts), rb_str_new2(body));
00142             rb_ary_push(v, nob_ary);
00143         }
00144     }
00145 
00146     argvFree(av);
00147     return v;
00148 }
00149 
00150 
00160 static VALUE
00161 rpmmc_expand(VALUE self, VALUE macro)
00162 {
00163     rpmmc mc = _rpmmc_get_mc(self);
00164     char *vstr = StringValueCStr(macro);
00165 
00166     if (_debug)
00167         fprintf(stderr, "==> %s(0x%lx, 0x%lx) ptr %p \"%s\"\n",
00168             __FUNCTION__, self, macro, mc, vstr);
00169     return rb_str_new2(rpmMCExpand(mc, vstr, NULL));
00170 }
00171 
00172 
00184 static VALUE
00185 rpmmc_load_macro_file(VALUE self, VALUE fn_v, VALUE nesting_v)
00186 {
00187     rpmmc mc = _rpmmc_get_mc(self);
00188 
00189     Check_Type(fn_v, T_STRING);
00190     Check_Type(nesting_v, T_FIXNUM);
00191 
00192     int error = rpmLoadMacroFile(mc, RSTRING_PTR(fn_v), FIX2INT(nesting_v));
00193     if(error)
00194         rpm_rb_raise(error, "Loading macro file failed");
00195     return self;
00196 }
00197 
00198 
00209 static VALUE
00210 rpmmc_init_macros(VALUE self, VALUE macrofiles_v)
00211 {
00212     Check_Type(macrofiles_v, T_STRING);
00213 
00214     rpmmc mc = _rpmmc_get_mc(self);
00215 
00216     rpmInitMacros(mc, RSTRING_PTR(macrofiles_v));
00217     return self;
00218 }
00219 
00220 
00221 static void
00222 initMethods(VALUE klass)
00223 {
00224     rb_define_method(klass, "add", &rpmmc_add, 1);
00225     rb_define_method(klass, "del", &rpmmc_del, 1);
00226     rb_define_method(klass, "list", &rpmmc_list, 0);
00227     rb_define_method(klass, "expand", &rpmmc_expand, 1);
00228     rb_define_method(klass, "load_macro_file", &rpmmc_load_macro_file, 2);
00229     rb_define_method(klass, "init_macros", &rpmmc_init_macros, 1);
00230 }
00231 
00232 
00233 /* --- Object properties */
00234 
00243 static VALUE
00244 rpmmc_debug_get(VALUE s)
00245 {
00246     if (_debug)
00247         fprintf(stderr, "==> %s(0x%lx)\n", __FUNCTION__, s);
00248     return INT2FIX(_debug);
00249 }
00250 
00251 
00260 static VALUE
00261 rpmmc_debug_set(VALUE s, VALUE v)
00262 {
00263     if (_debug)
00264         fprintf(stderr, "==> %s(0x%lx, 0x%lx)\n", __FUNCTION__, s, v);
00265     return INT2FIX(_debug = FIX2INT(v));
00266 }
00267 
00268 
00278 static VALUE
00279 rpmmc_get_global_mc(void)
00280 {
00281     return rpmmc_wrap(rpmGlobalMacroContext);
00282 }
00283 
00284 
00293 static VALUE
00294 rpmmc_get_cli_mc(void)
00295 {
00296     return rpmmc_wrap(rpmCLIMacroContext);
00297 }
00298 
00299 
00300 static void
00301 initProperties(VALUE klass)
00302 {
00303     rb_define_method(klass, "debug", rpmmc_debug_get, 0);
00304     rb_define_method(klass, "debug=", rpmmc_debug_set, 1);
00305     rb_define_singleton_method(klass, "global_context", 
00306         rpmmc_get_global_mc, 0);
00307     rb_define_singleton_method(klass, "cli_context", rpmmc_get_cli_mc, 0);
00308 }
00309 
00310 
00311 /* --- Object ctors/dtors */
00312 
00313 static void
00314 _rpmmc_free(rpmmc mc)
00315 {
00316     /* Don't free the global or CLI macro context */
00317     if(mc == rpmGlobalMacroContext || mc == rpmCLIMacroContext) return;
00318 
00319     rpmFreeMacros(mc);
00320     mc = _free(mc);
00321 }
00322 
00323 
00324 VALUE
00325 rpmmc_wrap(rpmmc mc)
00326 {
00327     if (_debug)
00328         fprintf(stderr, "==> %s(%p)\n", __FUNCTION__, mc);
00329     return Data_Wrap_Struct(rpmmcClass, 0, &_rpmmc_free, mc);
00330 }
00331 
00332 
00333 static VALUE
00334 rpmmc_alloc(VALUE klass)
00335 {
00336     rpmmc mc = xcalloc(1, sizeof(*mc));
00337     VALUE obj = rpmmc_wrap(mc);
00338     if (_debug)
00339         fprintf(stderr, "==> %s(0x%lx) obj 0x%lx mc %p\n",
00340             __FUNCTION__, klass, obj, mc);
00341     return obj;
00342 }
00343 
00344 
00345 /* --- Class initialization */
00346 
00347 void
00348 Init_rpmmc(void)
00349 {
00350     rpmmcClass = rb_define_class_under(rpmModule, "Mc", rb_cObject);
00351     if (_debug)
00352         fprintf(stderr, "==> %s() rpmmcClass 0x%lx\n", __FUNCTION__, rpmmcClass);
00353     rb_define_alloc_func(rpmmcClass, rpmmc_alloc);
00354     initProperties(rpmmcClass);
00355     initMethods(rpmmcClass);
00356 }