[Rpm-maint] [patch 1/2] exposing macros to scriptlets and bindings as a dictionary.

Peter Jones pjones at redhat.com
Fri Nov 2 14:45:14 UTC 2007


This patch exposes a copy of the current set of defined macros to python 
and lua as a dictionary and a table, respectively.  The next patch will 
add fairly simple macros %patches and %sources to macros.in .

vroomfondel:~/devel/rpm$ hg diff
diff -r fbafe05f41e0 python/rpmmodule.c
--- a/python/rpmmodule.c        Fri Nov 02 09:25:33 2007 -0400
+++ b/python/rpmmodule.c        Fri Nov 02 10:44:01 2007 -0400
@@ -44,6 +44,104 @@ static PyObject * expandMacro(PyObject *

  /**
   */
+static PyObject * getMacros(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    char *kwlist[] = { NULL };
+    PyObject *macroDict;
+
+    rpmMacroEntry *macros = NULL;
+    int nmacros, i;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, ":getMacros", kwlist))
+        return NULL;
+
+    macroDict = PyDict_New();
+    if (!macroDict) {
+        PyErr_SetString(pyrpmError, "out of memory");
+        return NULL;
+    }
+
+    nmacros = rpmGetMacroEntries(NULL, &macros);
+    if (nmacros < 0) {
+        Py_DECREF(macroDict);
+        PyErr_SetString(pyrpmError, "out of memory");
+        return NULL;
+    } else if (nmacros == 0) {
+        free(macros);
+        return macroDict;
+    }
+
+    PyObject *used = PyString_FromString("used");
+    PyObject *level = PyString_FromString("level");
+    PyObject *opts = PyString_FromString("opts");
+    PyObject *body = PyString_FromString("body");
+
+    if (used && level && opts && body) {
+        for (i = 0; i < nmacros; i++) {
+            rpmMacroEntry me = macros[i];
+            PyObject *dict;
+            PyObject *name;
+            PyObject *value;
+            int failed = 0;
+
+            name = PyString_FromString(me->name);
+            if (!name)
+                break;
+
+            dict = PyDict_New();
+            if (!dict) {
+                Py_DECREF(name);
+                break;
+            }
+
+            PyDict_SetItem(macroDict, name, dict);
+            Py_DECREF(dict);
+
+            if ((value = PyInt_FromLong(me->used)))
+                PyDict_SetItem(dict, used, value);
+            else
+                failed = 1;
+            Py_XDECREF(value);
+
+            if ((value = PyInt_FromLong(me->level)))
+                PyDict_SetItem(dict, level, value);
+            else
+                failed = 1;
+            Py_XDECREF(value);
+
+            if (me->opts) {
+                if ((value = PyString_FromString(me->opts)))
+                    PyDict_SetItem(dict, opts, value);
+                else
+                    failed = 1;
+                Py_XDECREF(value);
+            }
+
+            if (me->body) {
+                if ((value = PyString_FromString(me->body)))
+                    PyDict_SetItem(dict, body, value);
+                else
+                    failed = 1;
+                Py_XDECREF(value);
+            }
+
+            if (failed)
+                PyDict_DelItem(macroDict, name);
+            Py_DECREF(name);
+        }
+    }
+
+    Py_XDECREF(used);
+    Py_XDECREF(level);
+    Py_XDECREF(opts);
+    Py_XDECREF(body);
+
+    free(macros);
+    return macroDict;
+}
+
+/**
+ */
  static PyObject * archScore(PyObject * self, PyObject * args, PyObject 
* kwds)
  {
      char * arch;
@@ -189,6 +287,8 @@ static PyMethodDef rpmModuleMethods[] =
         NULL },
      { "expandMacro", (PyCFunction) expandMacro, 
METH_VARARGS|METH_KEYWORDS,
         NULL },
+    { "getMacros", (PyCFunction) getMacros, METH_VARARGS|METH_KEYWORDS,
+        NULL },

      { "archscore", (PyCFunction) archScore, METH_VARARGS|METH_KEYWORDS,
         NULL },
diff -r fbafe05f41e0 rpmio/macro.c
--- a/rpmio/macro.c     Fri Nov 02 09:25:33 2007 -0400
+++ b/rpmio/macro.c     Fri Nov 02 10:44:01 2007 -0400
@@ -179,6 +179,36 @@ rpmDumpMacroTable(rpmMacroContext mc, FI
      }
      fprintf(fp, _("======================== active %d empty %d\n"),
                 nactive, nempty);
+}
+
+int
+rpmGetMacroEntries(rpmMacroContext mc, rpmMacroEntry **entries)
+{
+    int ret = 0;
+    rpmMacroEntry *rets = NULL;
+
+    if (mc == NULL)
+        mc = rpmGlobalMacroContext;
+
+    rets = malloc( (ret+1) * sizeof (rpmMacroEntry));
+    if (!rets)
+        return -1;
+
+    if (mc->macroTable != NULL) {
+        int i;
+        for (i = 0; i < mc->firstFree; i++) {
+            rpmMacroEntry me;
+            if ((me = mc->macroTable[i]) == NULL)
+                continue;
+            *entries = rets;
+            rets[ret++] = me;
+            rets = realloc(rets, (ret+1) * sizeof (rpmMacroEntry));
+            if (!rets)
+                return ret;
+        }
+    }
+
+    return ret;
  }

  /**
diff -r fbafe05f41e0 rpmio/rpmlua.c
--- a/rpmio/rpmlua.c    Fri Nov 02 09:25:33 2007 -0400
+++ b/rpmio/rpmlua.c    Fri Nov 02 10:44:01 2007 -0400
@@ -559,6 +559,47 @@ void rpmluaInteractive(rpmlua _lua)
  /* ------------------------------------------------------------------ */
  /* Lua API */

+static int rpm_macros(lua_State *L)
+{
+    int i;
+    rpmMacroEntry *macros;
+    int nmacros;
+
+    lua_newtable(L);
+
+    nmacros = rpmGetMacroEntries(NULL, &macros);
+    if (nmacros < 1) {
+        if (nmacros == 0)
+            free(macros);
+        return 1;
+    }
+
+    for (i = 0; i < nmacros; i++) {
+        rpmMacroEntry me = macros[i];
+        lua_pushstring(L, me->name);
+        lua_newtable(L);
+        lua_pushstring(L, "used");
+        lua_pushnumber(L, me->used);
+        lua_settable(L, -3);
+        lua_pushstring(L, "level");
+        lua_pushnumber(L, me->level);
+        lua_settable(L, -3);
+        if (me->opts) {
+            lua_pushstring(L, "opts");
+            lua_pushstring(L, me->opts);
+            lua_settable(L, -3);
+        }
+        if (me->body) {
+            lua_pushstring(L, "body");
+            lua_pushstring(L, me->body);
+            lua_settable(L, -3);
+        }
+        lua_settable(L, -3);
+    }
+    free(macros);
+    return 1;
+}
+
  static int rpm_expand(lua_State *L)
  {
      const char *str = luaL_checkstring(L, 1);
@@ -761,6 +802,7 @@ static const luaL_reg rpmlib[] = {
  static const luaL_reg rpmlib[] = {
      {"expand", rpm_expand},
      {"define", rpm_define},
+    {"getMacros", rpm_macros},
      {"register", rpm_register},
      {"unregister", rpm_unregister},
      {"call", rpm_call},
diff -r fbafe05f41e0 rpmio/rpmmacro.h
--- a/rpmio/rpmmacro.h  Fri Nov 02 09:25:33 2007 -0400
+++ b/rpmio/rpmmacro.h  Fri Nov 02 10:44:01 2007 -0400
@@ -44,6 +44,14 @@ extern const char * macrofiles;
   */
  void   rpmDumpMacroTable       (rpmMacroContext mc,
                                         FILE * fp);
+
+/**
+ * Get a list of all the extant macro table entries.
+ * @param mc            macro context (NULL uses global context).
+ * @return **entries    array of entries (malloc'd list of pointers)
+ * @return              number of entries or -1 on failure.
+ */
+int rpmGetMacroEntries(rpmMacroContext mc, rpmMacroEntry **entries);

  /**
   * Return URL path(s) from a (URL prefixed) pattern glob.

-- 
   Peter



More information about the Rpm-maint mailing list