]> git.ipfire.org Git - pakfire.git/commitdiff
python: Add simply Parser module
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 13 Feb 2021 16:34:31 +0000 (16:34 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 13 Feb 2021 16:34:31 +0000 (16:34 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/_pakfire/_pakfiremodule.c
src/_pakfire/parser.c [new file with mode: 0644]
src/_pakfire/parser.h [new file with mode: 0644]
src/libpakfire/include/pakfire/parser.h
src/libpakfire/libpakfire.sym
src/libpakfire/parser.c
tests/python/parser.py [new file with mode: 0755]

index e5e6ebea116c4dba337f01fa5152e315db805af7..0af8ae7967ba1d0a6a1e9c4ecc4218eddf75bc2b 100644 (file)
@@ -186,6 +186,8 @@ _pakfire_la_SOURCES = \
        src/_pakfire/package.h \
        src/_pakfire/pakfire.c \
        src/_pakfire/pakfire.h \
+       src/_pakfire/parser.c \
+       src/_pakfire/parser.h \
        src/_pakfire/problem.c \
        src/_pakfire/problem.h \
        src/_pakfire/relation.c \
@@ -625,6 +627,7 @@ TESTS_ENVIRONMENT = \
 dist_check_SCRIPTS = \
        tests/python/cgroups.py \
        tests/python/execute.py \
+       tests/python/parser.py \
        tests/python/test.py
 
 TESTS = \
index 9d2c3b11971c1b0299900b0d40b498e8a94741e8..7357c52ed7466730d5a7ceb15ff88c60ed89177e 100644 (file)
@@ -37,6 +37,7 @@
 #include "key.h"
 #include "package.h"
 #include "pakfire.h"
+#include "parser.h"
 #include "problem.h"
 #include "relation.h"
 #include "repo.h"
@@ -187,6 +188,13 @@ PyMODINIT_FUNC PyInit__pakfire(void) {
        Py_INCREF(&PackageType);
        PyModule_AddObject(module, "Package", (PyObject *)&PackageType);
 
+       // Parser
+       if (PyType_Ready(&ParserType) < 0)
+               return NULL;
+
+       Py_INCREF(&ParserType);
+       PyModule_AddObject(module, "Parser", (PyObject *)&ParserType);
+
        // Problem
        if (PyType_Ready(&ProblemType) < 0)
                return NULL;
diff --git a/src/_pakfire/parser.c b/src/_pakfire/parser.c
new file mode 100644 (file)
index 0000000..e022e98
--- /dev/null
@@ -0,0 +1,152 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2021 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <Python.h>
+
+#include <pakfire/parser.h>
+
+#include "pakfire.h"
+#include "parser.h"
+
+static ParserObject* Parser_new_core(PyTypeObject* type, PakfireParser parser) {
+       ParserObject* self = (ParserObject *)type->tp_alloc(type, 0);
+       if (self) {
+               self->parser = parser;
+       }
+
+       return self;
+}
+
+PyObject* new_parser(PakfireParser parser) {
+       ParserObject* p = Parser_new_core(&ParserType, parser);
+
+       return (PyObject*)p;
+}
+
+static PyObject* Parser_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
+       ParserObject* self = Parser_new_core(type, NULL);
+
+       return (PyObject *)self;
+}
+
+static void Parser_dealloc(ParserObject* self) {
+       pakfire_parser_unref(self->parser);
+
+       Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int Parser_init(ParserObject* self, PyObject* args, PyObject* kwds) {
+       PakfireObject* pakfire = NULL;
+       const char* namespace = NULL;
+
+       if (!PyArg_ParseTuple(args, "O!|z", &PakfireType, &pakfire, &namespace))
+               return -1;
+
+       // Allocate a new parser
+       self->parser = pakfire_parser_create(pakfire->pakfire, NULL, namespace);
+       if (!self->parser) {
+               // What went wrong here?
+               return -1;
+       }
+
+       return 0;
+}
+
+static PyObject* Parser_repr(ParserObject* self) {
+       const char* namespace = pakfire_parser_get_namespace(self->parser);
+
+       return PyUnicode_FromFormat("<_pakfire.Parser %s>", namespace);
+}
+
+static PyObject* Parser_str(ParserObject* self) {
+       char* s = pakfire_parser_dump(self->parser);
+       if (!s) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
+
+       PyObject* ret = PyUnicode_FromString(s);
+       free(s);
+
+       return ret;
+}
+
+static PyObject* Parser_parse(ParserObject* self, PyObject* args) {
+       const char* data = NULL;
+
+       if (!PyArg_ParseTuple(args, "s", &data))
+               return NULL;
+
+       int r = pakfire_parser_parse(self->parser, data, strlen(data));
+       if (r) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
+
+       Py_RETURN_NONE;
+}
+
+static PyObject* Parser_get(ParserObject* self, PyObject* args) {
+       const char* key = NULL;
+
+       if (!PyArg_ParseTuple(args, "s", &key))
+               return NULL;
+
+       char* value = pakfire_parser_get(self->parser, key);
+       if (!value) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
+
+       PyObject* ret = PyUnicode_FromString(value);
+       free(value);
+
+       return ret;
+}
+
+static struct PyMethodDef Parser_methods[] = {
+       {
+               "parse",
+               (PyCFunction)Parser_parse,
+               METH_VARARGS,
+               NULL,
+       },
+       {
+               "get",
+               (PyCFunction)Parser_get,
+               METH_VARARGS,
+               NULL,
+       },
+       { NULL },
+};
+
+PyTypeObject ParserType = {
+       PyVarObject_HEAD_INIT(NULL, 0)
+       tp_name:            "_pakfire.Parser",
+       tp_basicsize:       sizeof(ParserObject),
+       tp_flags:           Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+       tp_new:             Parser_new,
+       tp_dealloc:         (destructor)Parser_dealloc,
+       tp_init:            (initproc)Parser_init,
+       tp_doc:             "Parser Object",
+       tp_methods:         Parser_methods,
+       tp_repr:            (reprfunc)Parser_repr,
+       tp_str:             (reprfunc)Parser_str,
+};
diff --git a/src/_pakfire/parser.h b/src/_pakfire/parser.h
new file mode 100644 (file)
index 0000000..3636d12
--- /dev/null
@@ -0,0 +1,37 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2021 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef PYTHON_PAKFIRE_PARSER_H
+#define PYTHON_PAKFIRE_PARSER_H
+
+#include <Python.h>
+
+#include <pakfire/parser.h>
+
+typedef struct {
+       PyObject_HEAD
+       PakfireParser parser;
+} ParserObject;
+
+extern PyTypeObject ParserType;
+
+PyObject* new_parser(PakfireParser parser);
+
+#endif /* PYTHON_PAKFIRE_PARSER_H */
index ab0c1f68d2675b9dea06b5721adf1cd04e2b961e..98e4ba81cc5a351020ba08cb895a910fef6c22a5 100644 (file)
@@ -44,8 +44,11 @@ char* pakfire_parser_get(PakfireParser parser, const char* name);
 PakfireParser pakfire_parser_merge(PakfireParser parser1, PakfireParser parser2);
 
 int pakfire_parser_read(PakfireParser parser, FILE* f);
+int pakfire_parser_parse(PakfireParser parser, const char* data, size_t size);
 char* pakfire_parser_dump(PakfireParser parser);
 
+const char* pakfire_parser_get_namespace(PakfireParser parser);
+
 #ifdef PAKFIRE_PRIVATE
 
 Pakfire pakfire_parser_get_pakfire(PakfireParser parser);
index e69f8861cb44fdb0adce6e04490bf9bd696e6a34..695e25931abde1f3c070e7336096839c5e22ed8c 100644 (file)
@@ -252,9 +252,10 @@ global:
        pakfire_parser_dump;
        pakfire_parser_expand;
        pakfire_parser_get;
+       pakfire_parser_get_namespace;
        pakfire_parser_get_parent;
        pakfire_parser_merge;
-       pakfire_parser_parse_data;
+       pakfire_parser_parse;
        pakfire_parser_read;
        pakfire_parser_ref;
        pakfire_parser_set;
index 4d9eecffd745cd3ddea2082a99d2bca28e0a86c8..06a78e49e8ccce345e4cf6140244523c881d01f7 100644 (file)
@@ -462,6 +462,10 @@ PAKFIRE_EXPORT int pakfire_parser_read(PakfireParser parser, FILE* f) {
        return r;
 }
 
+PAKFIRE_EXPORT int pakfire_parser_parse(PakfireParser parser, const char* data, size_t size) {
+       return pakfire_parser_parse_data(parser, data, size);
+}
+
 PAKFIRE_EXPORT char* pakfire_parser_dump(PakfireParser parser) {
        char* s = NULL;
 
@@ -478,3 +482,7 @@ PAKFIRE_EXPORT char* pakfire_parser_dump(PakfireParser parser) {
 
        return s;
 }
+
+PAKFIRE_EXPORT const char* pakfire_parser_get_namespace(PakfireParser parser) {
+       return parser->namespace;
+}
diff --git a/tests/python/parser.py b/tests/python/parser.py
new file mode 100755 (executable)
index 0000000..51d42d5
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/python3
+
+import pakfire
+import unittest
+
+from pakfire._pakfire import Parser
+
+class Test(unittest.TestCase):
+       """
+               This tests the parser command
+       """
+       def setUp(self):
+               self.pakfire = pakfire.Pakfire("/")
+
+       def test_simple_parse(self):
+               p = Parser(self.pakfire)
+
+               # Parse something simple
+               p.parse("""
+                       a = 1
+                       b = 2
+               """)
+
+               # Read back a
+               a = p.get("a")
+               self.assertEqual(a, "1")
+
+               # Read back b
+               b = p.get("b")
+               self.assertEqual(b, "2")
+
+       def test_dump(self):
+               p = Parser(self.pakfire)
+
+               # Parse something simple
+               p.parse("""
+                       a = 1
+                       b = 2
+               """)
+
+               dump = "%s" % p
+
+if __name__ == "__main__":
+       unittest.main()