[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, ¯os);
+ 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, ¯os);
+ 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