public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     fa75018c1432d0aaaf4674b502fe6cafdfd5156c
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Sun Jul 11 16:28:07 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Sun Jul 11 16:28:07 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=fa75018c

Get the proper layman Python library and fix BareConfig constructor to
take a Message class as first argument.

---
 src/config.c     |   67 +++++++++++++++++-----
 src/config.h     |   18 +++++-
 src/laymanapi.c  |   18 +++++-
 src/laymanapi.h  |    4 +-
 src/message.c    |   23 +++++---
 src/overlay.c    |  170 ------------------------------------------------------
 src/overlay.h    |   20 ------
 src/stringlist.c |   18 ++++++-
 src/stringlist.h |    2 +
 src/tester.c     |   36 ++++++++---
 10 files changed, 147 insertions(+), 229 deletions(-)

diff --git a/src/config.c b/src/config.c
index db632f2..624f1ab 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1,33 +1,72 @@
+#include <Python.h>
+
 #include "config.h"
 #include "interpreter.h"
-#include <Python.h>
 
-struct Config
+struct BareConfig
 {
 	PyObject *object;
 };
 
-PyObject *_object(Config *c)
+PyObject *_bareConfigObject(BareConfig *c)
 {
-	return c ? c->object : NULL;
+	if (c && c->object)
+		return c->object;
+	else
+		Py_RETURN_NONE;
 }
 
-Config *createConfig(const char *argv[], int argc)
+BareConfig *bareConfigCreate(Message *m, FILE* outFd, FILE* inFd, FILE* errFd)
 {
-	PyObject *pyargs = PyList_New(argc);
-	for (int i = 0; i < argc; i++)
-	{
-		PyObject *arg = PyBytes_FromString(argv[i]);
-		PyList_Insert(pyargs, i, arg);
-	}
+	PyObject *pyout = PyFile_FromFile(((!outFd || fileno(outFd) <= 0) ? stdout : outFd),
+				"", "w", 0);
+	PyObject *pyin = PyFile_FromFile(((!inFd || fileno(inFd) <= 0) ? stdin : inFd),
+				"", "r", 0);
+	PyObject *pyerr = PyFile_FromFile(((!errFd || fileno(errFd) <= 0) ? stderr : errFd),
+				"", "w", 0);
+
+	PyObject *obj = executeFunction("layman.config", "BareConfig", "OOOO", _messageObject(m), pyout, pyin, pyerr);
+	Py_DECREF(pyout);
+	Py_DECREF(pyin);
+	Py_DECREF(pyerr);
 
-	PyObject *obj = executeFunction("layman.config", "Config", "O", pyargs);
-	Py_DECREF(pyargs);
 	if (!obj)
 		return NULL;
 
-	Config *ret = malloc(sizeof(Config));
+	BareConfig *ret = malloc(sizeof(BareConfig));
 	ret->object = obj;
 
 	return ret;
 }
+
+void bareConfigFree(BareConfig* cfg)
+{
+	if (cfg && cfg->object)
+	{
+		Py_DECREF(cfg->object);
+	}
+
+	if (cfg)
+		free(cfg);
+}
+
+const char* bareConfigGetDefaultValue(BareConfig* cfg, const char* opt)
+{
+	PyObject *obj = PyObject_CallMethod(cfg->object, "get_defaults", NULL);
+	if (!obj)
+		return NULL;
+
+	if (PyDict_Contains(obj, PyBytes_FromString(opt)))
+		return PyBytes_AsString(PyDict_GetItem(obj, PyBytes_FromString(opt)));
+	else
+		return "";
+}
+
+int bareConfigSetOptionValue(BareConfig* cfg, const char* opt, const char* val)
+{
+	PyObject *obj = PyObject_CallMethod(cfg->object, "set_option", "(zz)", opt, val);
+	if (obj)
+		return 1;
+	else
+		return 0;
+}

diff --git a/src/config.h b/src/config.h
index e977cdc..33bfd1e 100644
--- a/src/config.h
+++ b/src/config.h
@@ -3,10 +3,22 @@
 
 #include <Python.h>
 
-typedef struct Config Config;
+#include "stringlist.h"
+#include "message.h"
 
-Config *createConfig(const char *argv[], int argc);
+typedef struct BareConfig BareConfig;
 
-PyObject *_object(Config*);
+BareConfig*	bareConfigCreate(Message* m, FILE* outFd, FILE* inFd, FILE* errFd);
+
+/*
+ * FIXME : could the Python lib work the same way ?
+ */
+
+const char*	bareConfigGetDefaultValue(BareConfig* cfg, const char*);
+int 		bareConfigSetOptionValue(BareConfig* cfg, const char*, const char*);
+
+PyObject* 	_bareConfigObject(BareConfig*);
+
+void 		bareConfigFree(BareConfig*);
 
 #endif

diff --git a/src/laymanapi.c b/src/laymanapi.c
index ae4b2eb..328a572 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -2,6 +2,10 @@
 #include "interpreter.h"
 #include "laymanapi.h"
 
+/*
+ * FIXME: free memory !!!
+ */
+
 struct LaymanAPI
 {
 	PyObject *object;
@@ -13,9 +17,9 @@ OverlayInfo strToInfo(const char* str)
 	return ret;
 }
 
-LaymanAPI* laymanAPICreate(Config* config, int report_error, int output)
+LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
-	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "OII", _configObject(config), report_error, output);
+	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "OII", _bareConfigObject(config), report_error, output);
 	if (!obj)
 		return NULL;
 
@@ -113,3 +117,13 @@ const char* laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 	//TODO:also return 'official' an 'supported' (see laymanapi.h)
 }
 
+void laymanAPIFree(LaymanAPI* l)
+{
+	if (l && l->object)
+	{
+		Py_DECREF(l->object);
+	}
+
+	if (l)
+		free(l);
+}

diff --git a/src/laymanapi.h b/src/laymanapi.h
index 42c0058..c89d3a4 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -24,7 +24,7 @@ typedef struct OverlayInfo
 } OverlayInfo;
 
 
-LaymanAPI*	laymanAPICreate(Config*, int, int);
+LaymanAPI*	laymanAPICreate(BareConfig*, int, int);
 StringList*	laymanAPIGetAvailable(LaymanAPI*);
 StringList*	laymanAPIGetInstalled(LaymanAPI*);
 
@@ -44,4 +44,6 @@ int 		laymanAPISync(LaymanAPI*, const char*);
 int 		laymanAPIFetchRemoteList(LaymanAPI*);
 const char*	laymanAPIGetInfo(LaymanAPI*, const char*);
 
+void laymanAPIFree(LaymanAPI*);
+
 #endif

diff --git a/src/message.c b/src/message.c
index bc0ee56..85a1717 100644
--- a/src/message.c
+++ b/src/message.c
@@ -7,6 +7,11 @@ struct Message
 	PyObject *object;
 };
 
+/*
+ * TODO: This constructor is too big.
+ * 	 Create a little constructor that uses default values
+ * 	 and add helper functions to set the values
+ */
 Message *messageCreate(const char* module,
 			FILE* out,
 			FILE* err,
@@ -22,13 +27,12 @@ Message *messageCreate(const char* module,
 {
 	PyObject *pyout, *pyerr, *pydbg, *pymth, *pyobj, *pyvar;
 
-	pyout = PyFile_FromFile((fileno(out) <= 0 ? stdout : out),
-				NULL, "w", 0);
-	pyerr = PyFile_FromFile((fileno(err) <= 0 ? stderr : err),
-				NULL, "w", 0);
-	pydbg = PyFile_FromFile((fileno(dbg) <= 0 ? stderr : dbg),
-				NULL, "w", 0);
-	
+	pyout = PyFile_FromFile(((!out || fileno(out) <= 0) ? stdout : out),
+				"", "w", 0);
+	pyerr = PyFile_FromFile(((!err || fileno(err) <= 0) <= 0 ? stderr : err),
+				"", "w", 0);
+	pydbg = PyFile_FromFile(((!dbg || fileno(dbg) <= 0) ? stderr : dbg),
+				"", "w", 0);
 
 	pymth = cListToPyList(mth);
 	pyobj = cListToPyList(obj);
@@ -67,5 +71,8 @@ Message *messageCreate(const char* module,
 
 PyObject *_messageObject(Message* m)
 {
-	return m ? m->object : NULL;
+	if (m && m->object)
+		return m->object;
+	else
+		Py_RETURN_NONE;
 }

diff --git a/src/overlay.c b/src/overlay.c
deleted file mode 100644
index 9b2b2f7..0000000
--- a/src/overlay.c
+++ /dev/null
@@ -1,170 +0,0 @@
-#include <Python.h>
-
-#include "interpreter.h"
-#include "overlay.h"
-
-struct Overlay
-{
-	PyObject *object;
-};
-
-/*
- * FIXME: should the xml argument be an expat element ?
- */
-Overlay *createOverlay(const char *xml, const char *config, int ignore, int quiet)
-{
-	//First argument must be a xml.etree.Element
-	//PyObject *elem = executeFunction("layman.overlays.overlay", "testfunc", NULL);
-	PyObject *elem = executeFunction("xml.etree.ElementTree", "fromstring", "(s)", xml);
-	if (!elem)
-		return NULL;
-
-	config = config;
-	PyObject *cfg = PyDict_New();
-	if (!cfg)
-		return NULL;
-
-	PyObject *overlay = executeFunction("layman.overlays.overlay", "Overlay", "(OOIb)", elem, cfg, ignore, quiet);
-	if (!overlay)
-		return NULL;
-	Overlay *ret = malloc(sizeof(Overlay));
-	ret->object = overlay;
-
-	return ret;
-}
-
-const char *overlayName(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *name = PyObject_GetAttrString(o->object, "name");
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(name);
-}
-
-const char *overlayOwnerEmail(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *ret = PyObject_GetAttrString(o->object, "owner_email");
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(ret);
-}
-
-int overlayPriority(Overlay *o)
-{
-	if (!o || !o->object)
-		return -1;
-
-	PyObject *prio = PyObject_GetAttrString(o->object, "priority");
-
-	//TODO:Py_DECREF me !
-
-	return (int) PyLong_AsLong(prio);
-}
-
-const char *overlayDescription(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *desc = PyObject_GetAttrString(o->object, "description");
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(desc);
-}
-
-int overlayIsOfficial(Overlay *o)
-{
-	if (!o || !o->object)
-		return -1;
-
-	PyObject *iso = PyObject_CallMethod(o->object, "is_official", NULL);
-
-	//TODO:Py_DECREF me !
-
-	return (int) PyLong_AsLong(iso);
-}
-
-int overlayIsSupported(Overlay *o)
-{
-	if (!o || !o->object)
-		return -1;
-
-	PyObject *iss = PyObject_CallMethod(o->object, "is_supported", NULL);
-
-	//TODO:Py_DECREF me !
-
-	return (int) PyLong_AsLong(iss);
-}
-
-const char *overlayShortList(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *sl = PyObject_CallMethod(o->object, "short_list", NULL);
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(sl);
-}
-
-const char *overlayStr(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *str = PyObject_CallMethod(o->object, "str", NULL);
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(str);
-}
-
-const char *overlayToXml(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *element = PyObject_CallMethod(o->object, "to_xml", NULL);
-	PyObject *str = executeFunction("xml.etree.ElementTree", "tostring", "(O)", element);
-
-	Py_DECREF(element);
-
-	return PyBytes_AsString(str);
-}
-
-void overlaySetPriority(Overlay *o, int priority)
-{
-	if (!o || !o->object)
-		return;
-
-	PyObject_CallMethod(o->object, "set_priority", "(I)", priority);
-}
-
-int overlaySame(Overlay *o1, Overlay *o2)
-{
-	PyObject *ret = PyObject_RichCompare(o1->object, o2->object, Py_EQ);
-	if (!ret)
-		return 0;
-
-	return PyObject_IsTrue(ret);
-}
-
-void overlayFree(Overlay *o)
-{
-	if (o && o->object)
-	{
-		Py_DECREF(o->object);
-	}
-	if (o)
-		free(o);
-}

diff --git a/src/overlay.h b/src/overlay.h
deleted file mode 100644
index d6b96fd..0000000
--- a/src/overlay.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef OVERLAY_H
-#define OVERLAY_H
-
-//TODO:document me !
-
-typedef struct Overlay Overlay;
-
-Overlay*	createOverlay(const char*, const char*, int, int);
-const char*	overlayName(Overlay*);
-const char*	overlayOwnerEmail(Overlay*);
-const char*	overlayDescription(Overlay*);
-const char*	overlayShortList(Overlay*);
-const char*	overlayStr(Overlay*);
-const char*	overlayToXml(Overlay*);
-int 		overlayPriority(Overlay*);
-int 		overlayIsOfficial(Overlay*);
-int		overlayIsSupported(Overlay*);
-void		overlayFree(Overlay*);
-
-#endif

diff --git a/src/stringlist.c b/src/stringlist.c
index dc2a45d..22d6ef6 100644
--- a/src/stringlist.c
+++ b/src/stringlist.c
@@ -34,7 +34,7 @@ StringList* listToCList(PyObject* list)
 PyObject* cListToPyList(StringList* list)
 {
 	if (!list)
-		return NULL;
+		Py_RETURN_NONE;
 
 	PyObject *ret = PyList_New(list->count);
 	for(int i = 0; i < list->count; i++)
@@ -45,6 +45,21 @@ PyObject* cListToPyList(StringList* list)
 	return ret;
 }
 
+void stringListPrint(StringList* list)
+{
+	if (!list)
+		return;
+
+	for(int i = 0; i < list->count; i++)
+	{
+		printf("\"%s\"", list->list[i]);
+		if (i < list->count - 1)
+			printf(", ");
+	}
+
+	free(list);
+}
+
 void stringListFree(StringList* list)
 {
 	if (!list)
@@ -57,3 +72,4 @@ void stringListFree(StringList* list)
 
 	free(list);
 }
+

diff --git a/src/stringlist.h b/src/stringlist.h
index cf1c33a..46151a4 100644
--- a/src/stringlist.h
+++ b/src/stringlist.h
@@ -8,5 +8,7 @@ typedef struct StringList StringList;
 StringList* stringListCreate(size_t);
 StringList* listToCList(PyObject* list);
 PyObject* cListToPyList(StringList*);
+void stringListPrint(StringList*);
+void stringListFree(StringList*);
 
 #endif

diff --git a/src/tester.c b/src/tester.c
index 40be2ff..7fc40f9 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -1,25 +1,41 @@
-#include "overlay.h"
+//#include "overlay.h"
 #include "interpreter.h"
+#include "config.h"
+#include "laymanapi.h"
+#include "message.h"
 
 int main(int argc, char *argv[])
 {
 	argc = argc;
 	argv = argv;
+	int ret = 0;
 	interpreterInit();
 	
-	Overlay *o = createOverlay("<overlay type='svn' src='https://overlays.gentoo.org/svn/dev/wrobel' contact='nobody@gentoo.org' name='wrobel' status='official' priorit='10'><description>Test</description></overlay>", "", 1, 0);
-
-	if (!o)
+	Message *msg = messageCreate("layman", 0, 0, 0, 4, 2, 4, 4, 1, NULL, NULL, NULL);
+	BareConfig *cfg = bareConfigCreate(msg, 0, 0, 0);
+	if (!bareConfigSetOptionValue(cfg, "local_list", "/home/detlev/srg/gsoc2010/layman/layman/tests/testfiles/global-overlays.xml"))
+		printf("Error setting config option.\n");
+	//printf("config: %s\n", bareConfigGetDefaultValue(cfg, "config"));
+	//printf("storage: %s\n", bareConfigGetDefaultValue(cfg, "storage"));
+	//printf("local_list: %s\n", bareConfigGetDefaultValue(cfg, "local_list"));
+	
+	LaymanAPI *l = laymanAPICreate(cfg, 0, 0);
+	if (!laymanAPIFetchRemoteList(l))
 	{
-		printf("Error creating overlay.\n");
-		return 0;
+		printf("Unable to fetch the remote list.\n");
+		ret = -1;
+		goto finish;
 	}
-	
-	printf("Overlay name = %s, owner email : %s, description : %s, priority : %d, it is %sofficial.\n", overlayName(o), overlayOwnerEmail(o), overlayDescription(o), overlayPriority(o), overlayIsOfficial(o) ? "" : "not ");
 
-	printf("xml is %s\n", overlayToXml(o));
+	StringList *strs = laymanAPIGetAvailable(l);
+
+	stringListPrint(strs);
+
+finish:
+	bareConfigFree(cfg);
+	laymanAPIFree(l);
 
 	interpreterFinalize();
 
-	return 0;
+	return ret;
 }



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     82813ef426d1a17df69e4daf91c7fb862e4ab26c
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Mon Jul 19 09:59:44 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Jul 19 09:59:44 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=82813ef4

Fix PyObject_IsTrue calls

---
 src/config.c     |    5 +++++
 src/laymanapi.c  |   51 ++++++++++++++++++++++++++++-----------------------
 src/stringlist.c |   30 +++++++++++++++++++++++++++---
 src/tester.c     |   17 ++++++++---------
 4 files changed, 68 insertions(+), 35 deletions(-)

diff --git a/src/config.c b/src/config.c
index c0b5b79..0bb330a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -3,6 +3,8 @@
 #include "config.h"
 #include "internal.h"
 
+#define debug(x)	printf(x)
+
 struct BareConfig
 {
 	PyObject *object;
@@ -38,7 +40,10 @@ BareConfig *bareConfigCreate(Message *m, FILE* outFd, FILE* inFd, FILE* errFd)
 	Py_DECREF(pyerr);
 
 	if (!obj)
+	{
+		debug("The execution failed, Are you sure app-portage/layman-8888 is properly installed ?\n");
 		return NULL;
+	}
 
 	BareConfig *ret = malloc(sizeof(BareConfig));
 	ret->object = obj;

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 74e98bf..6ddbba7 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -2,7 +2,7 @@
 #include "internal.h"
 #include "laymanapi.h"
 
-int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results, const char *overlay);
+static int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results, const char *overlay);
 
 struct LaymanAPI
 {
@@ -16,8 +16,13 @@ struct LaymanAPI
  */
 LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
-	assert(NULL != config);
-	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "Oii", _bareConfigObject(config), report_error, output);
+	PyObject *cfg;
+	if (!config)
+		cfg = Py_None;
+	else
+		cfg = _bareConfigObject(config);
+
+	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "Oii", cfg, report_error, output);
 	if (!obj)
 		return NULL;
 
@@ -42,7 +47,7 @@ int laymanAPIIsRepo(LaymanAPI *l, const char* repo)
 
 	Py_DECREF(obj);
 
-	return !ret;
+	return ret;
 }
 
 int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
@@ -60,7 +65,7 @@ int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
 
 	Py_DECREF(obj);
 
-	return !ret;
+	return ret;
 }
 
 /*
@@ -114,13 +119,13 @@ int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 		return 0;
 
 	int ret = PyObject_IsTrue(obj);
-	
+
 	// ret must be 1 or 0
 	assert(-1 != ret);
-	
+
 	Py_DECREF(obj);
-	
-	return !ret;
+
+	return ret;
 }
 
 /*
@@ -141,7 +146,7 @@ int laymanAPIFetchRemoteList(LaymanAPI* l)
 	
 	Py_DECREF(obj);
 
-	return !ret;
+	return ret;
 }
 
 /*
@@ -207,9 +212,9 @@ int laymanAPIGetInfoStrList(LaymanAPI* l, StringList* overlays, OverlayInfo* res
 		assert(NULL != tmp);
 		results[k].text = strdup(tmp);
 
-		results[k].official = !PyObject_IsTrue(official);
+		results[k].official = PyObject_IsTrue(official);
 		assert(-1 != results[k].official);
-		results[k].supported = !PyObject_IsTrue(supported);
+		results[k].supported = PyObject_IsTrue(supported);
 		assert(-1 != results[k].supported);
 
 		k++;
@@ -381,9 +386,9 @@ int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *resul
 		results[k].srcUris = listToCList(srcUris);
 
 		// If official or supported is neither True or False, abort.
-		results[k].official = !PyObject_IsTrue(official);
+		results[k].official = PyObject_IsTrue(official);
 		assert(-1 != results[k].official);
-		results[k].supported = !PyObject_IsTrue(supported);
+		results[k].supported = PyObject_IsTrue(supported);
 		assert(-1 != results[k].supported);
 
 		k++;
@@ -408,14 +413,14 @@ int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
 
 	// Call the method
 	PyObject *obj = PyObject_CallMethod(l->object, "delete_repos", "(s)", repo);
-	
+
 	// If the call returned NULL, it failed.
 	int ret;
 	if (!obj)
 		ret = 0;
 	else
 		ret = 1;
-	
+
 	Py_DECREF(obj);
 
 	return ret;
@@ -437,14 +442,14 @@ int laymanAPIAddRepoList(LaymanAPI* l, StringList *repos)
 	// Call the method
 	PyObject *obj = PyObject_CallMethod(l->object, "add_repos", "(O)", pyrepos);
 	Py_DECREF(pyrepos);
-	
+
 	// If the call returned NULL, it failed.
 	int ret;
 	if (!obj)
 		ret = 0;
 	else
 		ret = 1;
-	
+
 	Py_DECREF(obj);
 
 	return ret;
@@ -462,14 +467,14 @@ int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
 
 	// Call the method
 	PyObject *obj = PyObject_CallMethod(l->object, "delete_repos", "(s)", repo);
-	
+
 	// If the call returned NULL, it failed.
 	int ret;
 	if (!obj)
 		ret = 0;
 	else
 		ret = 1;
-	
+
 	Py_DECREF(obj);
 
 	return ret;
@@ -487,18 +492,18 @@ int laymanAPIDeleteRepoList(LaymanAPI* l, StringList *repos)
 
 	// Converting the C list to a python list
 	PyObject *pyrepos = cListToPyList(repos);
-	
+
 	// Call the method
 	PyObject *obj = PyObject_CallMethod(l->object, "delete_repos", "(O)", pyrepos);
 	Py_DECREF(pyrepos);
-	
+
 	// If the call returned NULL, it failed.
 	int ret;
 	if (!obj)
 		ret = 0;
 	else
 		ret = 1;
-	
+
 	Py_DECREF(obj);
 
 	return ret;

diff --git a/src/stringlist.c b/src/stringlist.c
index 259eabb..915cca4 100644
--- a/src/stringlist.c
+++ b/src/stringlist.c
@@ -8,6 +8,8 @@ struct StringList
 	unsigned int count;
 };
 
+// Creates a String list to use with the library.
+// len is the number of strings in the list.
 StringList* stringListCreate(size_t len)
 {
 	StringList *ret = malloc(sizeof(StringList));
@@ -17,6 +19,10 @@ StringList* stringListCreate(size_t len)
 	return ret;
 }
 
+/*
+ * Inserts the string str in the list l at position pos.
+ * Return True if it succeeded, False if not.
+ */
 int stringListInsertAt(StringList *l, unsigned int pos, char *str)
 {
 	if(!l || !l->list || l->count < pos)
@@ -27,6 +33,9 @@ int stringListInsertAt(StringList *l, unsigned int pos, char *str)
 	return 1;
 }
 
+/*
+ * Returns the number of strings in the list
+ */
 unsigned int stringListCount(StringList *l)
 {
 	if (!l)
@@ -34,6 +43,9 @@ unsigned int stringListCount(StringList *l)
 	return l->count;
 }
 
+/*
+ * Returns the String at position pos
+ */
 char* stringListGetAt(StringList *l, unsigned int pos)
 {
 	if (!l || !l->list || pos >= l->count)
@@ -42,6 +54,9 @@ char* stringListGetAt(StringList *l, unsigned int pos)
 	return l->list[pos];
 }
 
+/*
+ * Converts a Python list object to a C String list
+ */
 StringList* listToCList(PyObject* list)
 {
 	if (!list || !PyList_Check(list))
@@ -54,6 +69,8 @@ StringList* listToCList(PyObject* list)
 
 	for (unsigned int i = 0; i < len; i++)
 	{
+		//Item are copied so that the PyObject can be deleted after the call without
+		//destroying the data in the returned list.
 		PyObject *elem = PyList_GetItem(list, i);
 		ret->list[i] = malloc(sizeof(char) * (PyBytes_Size(elem) + 1));
 		strcpy(ret->list[i], PyBytes_AsString(elem));
@@ -62,6 +79,9 @@ StringList* listToCList(PyObject* list)
 	return ret;
 }
 
+/*
+ * Converts a C String list to a Python List object
+ */
 PyObject* cListToPyList(StringList* list)
 {
 	if (!list)
@@ -76,6 +96,9 @@ PyObject* cListToPyList(StringList* list)
 	return ret;
 }
 
+/*
+ * Prints a C String list.
+ */
 void stringListPrint(StringList* list)
 {
 	if (!list)
@@ -84,16 +107,17 @@ void stringListPrint(StringList* list)
 	for(unsigned int i = 0; i < list->count; i++)
 	{
 		printf("\"%s\"", list->list[i]);
+		// No coma after the last item.
 		if (i < list->count - 1)
 			printf(", ");
 	}
 }
 
+/*
+ * Frees a string list and it's data
+ */
 void stringListFree(StringList* list)
 {
-	if (!list)
-		return;
-
 	if (list && list->list)
 	{
 		for(unsigned int i = 0; i < list->count; i++)

diff --git a/src/tester.c b/src/tester.c
index 049cc61..98dc171 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -22,24 +22,23 @@ int main(int argc, char *argv[])
 	printf("local_list: %s\n", bareConfigGetOptionValue(cfg, "local_list"));*/
 
 	LaymanAPI *l = laymanAPICreate(cfg, 0, 0);
-	/*if (0 == laymanAPIFetchRemoteList(l))
+	if (0 == laymanAPIFetchRemoteList(l))
 	{
 		printf("Unable to fetch the remote list.\n");
 		ret = -1;
-		goto finish;
-	}*/
+	}
 
 	StringList *strs = laymanAPIGetAvailable(l, 0);
 	printf("list:\n");
 	stringListPrint(strs);
-	
+
 	printf("\n");
 
 	unsigned int len = stringListCount(strs);
 	//OverlayInfo *infos = calloc(len, sizeof(OverlayInfo));
 	//int count = laymanAPIGetAllInfos(l, strs, infos);
 	
-	OverlayInfo *oi = laymanAPIGetAllInfo(l, "enlfdsightenment");
+	OverlayInfo *oi = laymanAPIGetAllInfo(l, "kuroo");
 	if (oi)
 	{
 		printf("%s\n~~~~~~~~~~~~~~~~~~~~\n", oi->name);
@@ -47,8 +46,8 @@ int main(int argc, char *argv[])
 		overlayInfoFree(*oi);
 		free(oi);
 	}
-
-	for (unsigned int i = 0; i < len; i++)
+	
+	/*for (unsigned int i = 0; i < len; i++)
 	{
 		OverlayInfo *oi = laymanAPIGetAllInfo(l, stringListGetAt(strs, i));
 		if (!oi)
@@ -57,15 +56,15 @@ int main(int argc, char *argv[])
 		printf("%s\n\n", oi->description);
 		overlayInfoFree(*oi);
 		free(oi);
-	}
+	}*/
 
 	printf("\n");
 
 	//free(infos);
+	stringListFree(strs);
 
 	bareConfigFree(cfg);
 	laymanAPIFree(l);
-	stringListFree(strs);
 
 	interpreterFinalize();
 



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     ba276428647f49fd7031f7a7f96f1d75458b523e
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Mon Jul 19 11:24:48 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Jul 19 11:24:48 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=ba276428

Doxygenise message.c

---
 src/message.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 67 insertions(+), 1 deletions(-)

diff --git a/src/message.c b/src/message.c
index b7ebb7d..a0ed050 100644
--- a/src/message.c
+++ b/src/message.c
@@ -7,9 +7,16 @@ struct Message
 	PyObject *object;
 };
 
-/*
+/**
  * Creates a Message instance with default values.
  * To modify those values, use the corresponding functions.
+ *
+ * \param module the module to debug. If you don't know, set "layman"
+ * \param out where to write info
+ * \param err where to write errors
+ * \param dbg where to write debug information
+ *
+ * \return a new instance of a Message object. It must be freed with messageFree()
  */
 Message *messageCreate(const char* module,
 			FILE* out,
@@ -49,6 +56,13 @@ Message *messageCreate(const char* module,
 	return ret;
 }
 
+/**
+ * Set the debug level.
+ *
+ * \param debug_level the debug level
+ *
+ * \return True on success, False on failure.
+ */
 int messageSetDebugLevel(Message *m, int debug_level)
 {
 	if (!m || !m->object)
@@ -67,6 +81,13 @@ int messageSetDebugLevel(Message *m, int debug_level)
 	return ret;
 }
 
+/**
+ * Set the debug verbosity.
+ *
+ * \param debug_verbosity the debug verbosity
+ *
+ * \return True on success, False on failure.
+ */
 int messageSetDebugVerbosity(Message *m, int debug_verbosity)
 {
 	if (!m || !m->object)
@@ -85,6 +106,13 @@ int messageSetDebugVerbosity(Message *m, int debug_verbosity)
 	return ret;
 }
 
+/**
+ * Set the info level.
+ *
+ * \param info_level the info level
+ *
+ * \return True on success, False on failure.
+ */
 int messageSetInfoLevel(Message *m, int info_level)
 {
 	if (!m || !m->object)
@@ -103,6 +131,13 @@ int messageSetInfoLevel(Message *m, int info_level)
 	return ret;
 }
 
+/**
+ * Set the warning level.
+ *
+ * \param warn_level the warning level
+ *
+ * \return True on success, False on failure.
+ */
 int messageSetWarnLevel(Message *m, int warn_level)
 {
 	if (!m || !m->object)
@@ -121,6 +156,11 @@ int messageSetWarnLevel(Message *m, int warn_level)
 	return ret;
 }
 
+/**
+ * Activates colors in the output
+ *
+ * \return 1 on success, 0 on failure
+ */
 int messageSetColorsOn(Message *m)
 {
 	if (!m || !m->object)
@@ -139,6 +179,11 @@ int messageSetColorsOn(Message *m)
 	return ret;
 }
 
+/**
+ * Deactivates colors in the output
+ *
+ * \return 1 on success, 0 on failure
+ */
 int messageSetColorsOff(Message *m)
 {
 	if (!m || !m->object)
@@ -157,6 +202,13 @@ int messageSetColorsOff(Message *m)
 	return ret;
 }
 
+/**
+ * Sets the methods to be debugged.
+ *
+ * \param mth the list of methods to be debugged, separated by comas
+ *
+ * \return 1 on success, 0 on failure
+ */
 int messageSetDebugMethods(Message *m, const char* mth)
 {
 	if (!m || !m->object)
@@ -175,6 +227,13 @@ int messageSetDebugMethods(Message *m, const char* mth)
 	return ret;
 }
 
+/**
+ * Sets the classes to be debugged.
+ *
+ * \param mth the list of classes to be debugged, separated by comas
+ *
+ * \return 1 on success, 0 on failure
+ */
 int messageSetDebugClasses(Message *m, const char* cla)
 {
 	if (!m || !m->object)
@@ -193,6 +252,13 @@ int messageSetDebugClasses(Message *m, const char* cla)
 	return ret;
 }
 
+/**
+ * Sets the variables to be debugged.
+ *
+ * \param mth the list of variables to be debugged, separated by comas
+ *
+ * \return 1 on success, 0 on failure
+ */
 int messageSetDebugVariables(Message *m, const char* var)
 {
 	if (!m || !m->object)



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     be2dff08d523dc75196146e4bfd650e898d1f8bd
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Mon Jul 19 10:28:04 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Jul 19 10:28:04 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=be2dff08

Doxygenise config.c and laymanAPI.c

---
 src/config.c    |   26 ++++++++++++-
 src/laymanapi.c |  110 +++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 110 insertions(+), 26 deletions(-)

diff --git a/src/config.c b/src/config.c
index 0bb330a..eed3b7e 100644
--- a/src/config.c
+++ b/src/config.c
@@ -18,8 +18,14 @@ PyObject *_bareConfigObject(BareConfig *c)
 		Py_RETURN_NONE;
 }
 
-/*
+/**
  * Creates a bare config object with default values.
+ *
+ * \param outFd where information must be written to
+ * \param inFd where information must be read from
+ * \param errFd where errors must be written to
+ *
+ * \return a new instance of a BareConfig object. It must be freed with bareConfigFree()
  */
 BareConfig *bareConfigCreate(Message *m, FILE* outFd, FILE* inFd, FILE* errFd)
 {
@@ -51,6 +57,9 @@ BareConfig *bareConfigCreate(Message *m, FILE* outFd, FILE* inFd, FILE* errFd)
 	return ret;
 }
 
+/**
+ * Frees a BareConfig object.
+ */
 void bareConfigFree(BareConfig* cfg)
 {
 	if (cfg && cfg->object)
@@ -63,7 +72,11 @@ void bareConfigFree(BareConfig* cfg)
 }
 
 /*
- * Returns an option's default value
+ * Get an option's default value.
+ *
+ * \param opt the name of the option
+ * 
+ * \return the value or NULL on failure.
  */
 const char* bareConfigGetDefaultValue(BareConfig* cfg, const char* opt)
 {
@@ -89,6 +102,10 @@ const char* bareConfigGetDefaultValue(BareConfig* cfg, const char* opt)
 
 /*
  * Get an option's current value.
+ *
+ * \param opt the name of the option
+ *
+ * \return the value or NULL on failure
  */
 const char* bareConfigGetOptionValue(BareConfig* cfg, const char* opt)
 {
@@ -105,6 +122,11 @@ const char* bareConfigGetOptionValue(BareConfig* cfg, const char* opt)
 
 /*
  * Modifies an option's value
+ *
+ * \param opt the name of the option
+ * \param val the new value for this option
+ *
+ * \return True on success, 0 on failure
  */
 int bareConfigSetOptionValue(BareConfig* cfg, const char* opt, const char* val)
 {

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 6ddbba7..75f8363 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -9,10 +9,13 @@ struct LaymanAPI
 	PyObject *object;
 };
 
-/*
+/**
  * Creates a LaymanAPI object that must be used in all function in this file.
  *
- * The BareConfig argument must not be NULL.
+ * \param config a BareConfig object that contains all configuration options. If NULL, the default configuration will be used.
+ * \param report_error if True, errors reporting on stdout will be activated.
+ * \param output ?
+ * \return a new instance of the LaymanAPI class, to be freed with laymanAPIFree()
  */
 LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
@@ -32,6 +35,14 @@ LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 	return ret;
 }
 
+/**
+ * Check if the given string is a valid repository
+ *
+ * \param l the LaymanAPI object.
+ * \param repo the repository to be checked.
+ *
+ * \return True if the repository is valid, False if not
+ */
 int laymanAPIIsRepo(LaymanAPI *l, const char* repo)
 {
 	if (!l || !l->object)
@@ -50,6 +61,14 @@ int laymanAPIIsRepo(LaymanAPI *l, const char* repo)
 	return ret;
 }
 
+/**
+ * Check if the given string is a valid and installed repository
+ *
+ * \param l the LaymanAPI object.
+ * \param repo the repository to be checked.
+ *
+ * \return True if the repository is valid and installed, False if not
+ */
 int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
 {
 	if (!l || !l->object)
@@ -68,8 +87,13 @@ int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
 	return ret;
 }
 
-/*
+/**
  * Returns a list of the available overlays.
+ *
+ * \param l the LaymanAPI object.
+ * \param reload if True, reloads the list
+ *
+ * \return the list of available overlays
  */
 StringList* laymanAPIGetAvailable(LaymanAPI* l, int reload)
 {
@@ -87,8 +111,13 @@ StringList* laymanAPIGetAvailable(LaymanAPI* l, int reload)
 	return ret;
 }
 
-/*
+/**
  * Returns a list of the installed overlays.
+ *
+ * \param l the LaymanAPI object.
+ * \param reload if True, reloads the list
+ *
+ * \return the list of installed overlays
  */
 StringList* laymanAPIGetInstalled(LaymanAPI* l, int reload)
 {
@@ -105,9 +134,13 @@ StringList* laymanAPIGetInstalled(LaymanAPI* l, int reload)
 	return ret;
 }
 
-/*
+/**
  * Syncs an overlay.
- * It returns true if it succeeded, false if not.
+ * 
+ * \param overlay The name of the overlay to sync
+ * \param verbose if True, the output will be more verbose.
+ *
+ * \return True if it succeeded, False if not.
  */
 int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 {
@@ -128,9 +161,10 @@ int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 	return ret;
 }
 
-/*
+/**
  * Updates the local overlay list.
- * It returns true if it succeeded, false if not.
+ *
+ * \return True if it succeeded, False if not.
  */
 int laymanAPIFetchRemoteList(LaymanAPI* l)
 {
@@ -149,12 +183,16 @@ int laymanAPIFetchRemoteList(LaymanAPI* l)
 	return ret;
 }
 
-/*
+/**
  * Gets the information from the overlays given in the StringList overlays.
  * The results are stored in the results table which must be initialized with N structures,
  * N being the number of overlays in the overlays StringList.
+ * This function fills the name, text, supported and official fields of the OverlayInfo structure.
  * 
- * It returns the number of results structures that have been filled.
+ * \param overlays the list of overlays to get information from
+ * \param results a pointer to a table of OverlayInfo structures
+ *
+ * \return the number of results structures that have been filled
  */
 int laymanAPIGetInfoStrList(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
 {
@@ -226,9 +264,12 @@ int laymanAPIGetInfoStrList(LaymanAPI* l, StringList* overlays, OverlayInfo* res
 	return k;
 }
 
-/*
+/**
  * Provided for convenience, this function get the information for only 1 overlay.
- * Returns NULL if it fails, an OverlayInfo struct if not.
+ *
+ * \param overlay the overlay name to get info from
+ *
+ * \return NULL if it fails, an OverlayInfo struct if not.
  */
 OverlayInfo *laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay)
 {
@@ -249,6 +290,14 @@ OverlayInfo *laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay)
 	return oi;
 }
 
+/**
+ * Get all information from an overlay.
+ * This function fills every fields but the text field of the OverlayInfo structure.
+ *
+ * \param overlay the overlay name to get info from
+ *
+ * \return NULL if it fails, an OverlayInfo struct if not.
+ */
 OverlayInfo *laymanAPIGetAllInfo(LaymanAPI* l, const char* overlay)
 {
 	// Check input data.
@@ -269,21 +318,26 @@ OverlayInfo *laymanAPIGetAllInfo(LaymanAPI* l, const char* overlay)
 	return ret;
 }
 
-/*
+/**
  * Gives a list of OverlayInfo's from the overaly names found in the overlays StringList.
  * results must be allocated and initialized with zeroes.
  * 
  * If an information is unavailable (no owner email for example),
  * the correpsonding field will stay to NULL
  * 
- * Returns the number of OverlayInfo structures filled.
+ * This function fills every fields but the text field of the OverlayInfo structure.
+ * 
+ * \param overlays the list of overlays to get information from
+ * \param results a pointer to a table of OverlayInfo structures
+ *
+ * \return the number of OverlayInfo structures filled.
  */
 int laymanAPIGetAllInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo *results)
 {
 	return _laymanAPIGetAllInfos(l, overlays, results, NULL);
 }
 
-/*
+/**
  * Gives a list of OverlayInfo's from the overaly names found in the overlays StringList if it's not NULL
  * If it's NULL, and overlay is not NULL, the information for Overlay will be fetched.
  * results must be allocated and initialized with zeroes.
@@ -291,7 +345,7 @@ int laymanAPIGetAllInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo *res
  * If an information is unavailable (no owner email for example),
  * the correpsonding field will stay to NULL
  * 
- * Returns the number of OverlayInfo structures filled.
+ * \return the number of OverlayInfo structures filled.
  */
 int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results, const char *overlay)
 {
@@ -401,10 +455,12 @@ int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *resul
 	return k;
 }
 
-/*
+/**
  * Adds an overlay to layman
  *
- * Return True if it succeeded, False if not
+ * \param repo the name of the repository to add
+ *
+ * \return True if it succeeded, False if not
  */
 int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
 {
@@ -426,9 +482,11 @@ int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
 	return ret;
 }
 
-/*
+/**
  * Adds a list of overlays to layman
  *
+ * \param repo the list of the repositories to add
+ *
  * Return True if it succeeded, False if not
  */
 int laymanAPIAddRepoList(LaymanAPI* l, StringList *repos)
@@ -455,10 +513,12 @@ int laymanAPIAddRepoList(LaymanAPI* l, StringList *repos)
 	return ret;
 }
 
-/*
+/**
  * Deletes an overlay from layman
  *
- * Return True if it succeeded, False if not
+ * \param repo the name of the repository to delete
+ *
+ * \return True if it succeeded, False if not
  */
 int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
 {
@@ -480,10 +540,12 @@ int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
 	return ret;
 }
 
-/*
+/**
  * Deletes a list of overlays from layman
  *
- * Return True if it succeeded, False if not
+ * \param repo the list of the repositories to delete
+ *
+ * \return True if it succeeded, False if not
  */
 int laymanAPIDeleteRepoList(LaymanAPI* l, StringList *repos)
 {
@@ -509,7 +571,7 @@ int laymanAPIDeleteRepoList(LaymanAPI* l, StringList *repos)
 	return ret;
 }
 
-/*
+/**
  * Frees a LaymanAPI object from memory
  */
 void laymanAPIFree(LaymanAPI* l)



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     181ddc8237bb313b61073e1e97a2e7f4b097a608
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Sat Jul 17 12:50:37 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Sat Jul 17 12:50:37 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=181ddc82

Change functions name to be more explicit

---
 src/laymanapi.c |   10 +++++-----
 src/laymanapi.h |    8 ++++----
 src/tester.c    |    2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 848a096..74e98bf 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -151,7 +151,7 @@ int laymanAPIFetchRemoteList(LaymanAPI* l)
  * 
  * It returns the number of results structures that have been filled.
  */
-int laymanAPIGetInfosStr(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
+int laymanAPIGetInfoStrList(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
 {
 	// Check input data.
 	if (!l || !l->object || !overlays || !results)
@@ -236,7 +236,7 @@ OverlayInfo *laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay)
 	stringListInsertAt(olist, 0, overlay);
 
 	OverlayInfo *oi = malloc(sizeof(OverlayInfo));
-	int count = laymanAPIGetInfosStr(l, olist, oi);
+	int count = laymanAPIGetInfoStrList(l, olist, oi);
 	assert(1 != count);
 
 	stringListFree(olist);
@@ -273,7 +273,7 @@ OverlayInfo *laymanAPIGetAllInfo(LaymanAPI* l, const char* overlay)
  * 
  * Returns the number of OverlayInfo structures filled.
  */
-int laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results)
+int laymanAPIGetAllInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo *results)
 {
 	return _laymanAPIGetAllInfos(l, overlays, results, NULL);
 }
@@ -426,7 +426,7 @@ int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
  *
  * Return True if it succeeded, False if not
  */
-int laymanAPIAddRepos(LaymanAPI* l, StringList *repos)
+int laymanAPIAddRepoList(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
 		return 0;
@@ -480,7 +480,7 @@ int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
  *
  * Return True if it succeeded, False if not
  */
-int laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos)
+int laymanAPIDeleteRepoList(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
 		return 0;

diff --git a/src/laymanapi.h b/src/laymanapi.h
index 94b0591..38d6207 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -29,14 +29,14 @@ StringList*	laymanAPIGetAvailable(LaymanAPI*, int reload);
 StringList*	laymanAPIGetInstalled(LaymanAPI*, int reload);
 int		laymanAPISync(LaymanAPI* l, const char* overlay, int verbose);
 int 		laymanAPIFetchRemoteList(LaymanAPI*);
-int		laymanAPIGetInfosStr(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
+int		laymanAPIGetInfoStrList(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
 OverlayInfo*	laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay);
-int		laymanAPIGetAllInfos(LaymanAPI* l, StringList*, OverlayInfo*);
+int		laymanAPIGetAllInfoList(LaymanAPI* l, StringList*, OverlayInfo*);
 OverlayInfo*	laymanAPIGetAllInfo(LaymanAPI* l, const char*);
 int		laymanAPIAddRepo(LaymanAPI* l, const char *repo);
-int		laymanAPIAddRepos(LaymanAPI* l, StringList *repos);
+int		laymanAPIAddRepoList(LaymanAPI* l, StringList *repos);
 int		laymanAPIDeleteRepo(LaymanAPI* l, const char *repo);
-int		laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos);
+int		laymanAPIDeleteRepoList(LaymanAPI* l, StringList *repos);
 OverlayInfo*	laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
 void		laymanAPIFree(LaymanAPI*);
 void		overlayInfoFree(OverlayInfo oi);

diff --git a/src/tester.c b/src/tester.c
index f7c7701..049cc61 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
 	//OverlayInfo *infos = calloc(len, sizeof(OverlayInfo));
 	//int count = laymanAPIGetAllInfos(l, strs, infos);
 	
-	OverlayInfo *oi = laymanAPIGetAllInfo(l, "enlightenment");
+	OverlayInfo *oi = laymanAPIGetAllInfo(l, "enlfdsightenment");
 	if (oi)
 	{
 		printf("%s\n~~~~~~~~~~~~~~~~~~~~\n", oi->name);



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     5ee230352df6d06cdba6f48da3d83a608847785c
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul 16 20:52:58 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul 16 20:52:58 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=5ee23035

Add comment to newly added functions

---
 src/laymanapi.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 9048921..8458c38 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -389,13 +389,19 @@ int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *resul
 
 		k++;
 	}
-
+	
+	//The returned value is not necessary anymore.
 	Py_DECREF(obj);
 
 	//Return the number of structures that have been filled.
 	return k;
 }
 
+/*
+ * Adds an overlay to layman
+ *
+ * Return True if it succeeded, False if not
+ */
 int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
 {
 	if (!l || !l->object || !repo)
@@ -416,6 +422,11 @@ int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
 	return ret;
 }
 
+/*
+ * Adds a list of overlays to layman
+ *
+ * Return True if it succeeded, False if not
+ */
 int laymanAPIAddRepos(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
@@ -440,6 +451,11 @@ int laymanAPIAddRepos(LaymanAPI* l, StringList *repos)
 	return ret;
 }
 
+/*
+ * Deletes an overlay from layman
+ *
+ * Return True if it succeeded, False if not
+ */
 int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
 {
 	if (!l || !l->object || !repo)
@@ -460,6 +476,11 @@ int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
 	return ret;
 }
 
+/*
+ * Deletes a list of overlays from layman
+ *
+ * Return True if it succeeded, False if not
+ */
 int laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     1a7e7b2b1550e79052cf52cb6c8154ee53420730
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul 16 19:23:34 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul 16 19:23:34 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=1a7e7b2b

Add laymanAPIIsRepo, laymanAPIIsInstalled, laymanAPIGetInfosStr,
laymanAPIGetInfoStr, laymanAPIGetAllInfos, laymanAPIAddRepos,
laymanAPIDeleteRepos and overlayInfoFree
Add comments

---
 src/laymanapi.c  |  221 ++++++++++++++++++++++++++++++++++++++++++++----------
 src/laymanapi.h  |   28 +++++--
 src/stringlist.c |    2 +-
 src/stringlist.h |    2 +-
 src/tester.c     |   11 +--
 5 files changed, 210 insertions(+), 54 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index cf4cb1d..f524ce8 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -26,6 +26,42 @@ LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 	return ret;
 }
 
+int laymanAPIIsRepo(LaymanAPI *l, const char* repo)
+{
+	if (!l || !l->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(l->object, "is_repo", "(s)", repo);
+	if (!obj)
+		return 0;
+
+	int ret = PyObject_IsTrue(obj);
+	// ret must be 1 or 0
+	assert(-1 != ret);
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
+{
+	if (!l || !l->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(l->object, "is_installed", "(s)", repo);
+	if (!obj)
+		return 0;
+
+	int ret = PyObject_IsTrue(obj);
+	// ret must be 1 or 0
+	assert(-1 != ret);
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
 /*
  * Returns a list of the available overlays.
  */
@@ -38,6 +74,7 @@ StringList* laymanAPIGetAvailable(LaymanAPI* l, int reload)
 	if (!obj)
 		return NULL;
 
+	//listToCList() will return Type_NONE if the python list is not valid.
 	StringList *ret = listToCList(obj);
 	Py_DECREF(obj);
 
@@ -66,7 +103,6 @@ StringList* laymanAPIGetInstalled(LaymanAPI* l, int reload)
  * Syncs an overlay.
  * It returns true if it succeeded, false if not.
  */
-
 int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 {
 	if (!l || !l->object)
@@ -77,7 +113,9 @@ int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 		return 0;
 
 	int ret = PyObject_IsTrue(obj);
-	assert(-1 == ret);
+	
+	// ret must be 1 or 0
+	assert(-1 != ret);
 	
 	Py_DECREF(obj);
 	
@@ -98,7 +136,7 @@ int laymanAPIFetchRemoteList(LaymanAPI* l)
 		return 0;
 
 	int ret = PyObject_IsTrue(obj);
-	assert(-1 == ret);
+	assert(-1 != ret);
 	
 	Py_DECREF(obj);
 
@@ -112,7 +150,7 @@ int laymanAPIFetchRemoteList(LaymanAPI* l)
  * 
  * It returns the number of results structures that have been filled.
  */
-int laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
+int laymanAPIGetInfosStr(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
 {
 	// Check input data.
 	if (!l || !l->object || !overlays || !results)
@@ -122,7 +160,7 @@ int laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* result
 	PyObject *list = cListToPyList(overlays);
 
 	// Call the method
-	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
+	PyObject *obj = PyObject_CallMethod(l->object, "get_info_str", "(O)", list);
 	Py_DECREF(list);
 
 	// Check if the returned value is a dict as expected.
@@ -186,19 +224,45 @@ int laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* result
  * Provided for convenience, this function get the information for only 1 overlay.
  * Returns NULL if it fails, an OverlayInfo struct if not.
  */
-OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
+OverlayInfo *laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay)
 {
 	// Check input data.
 	if (!l || !l->object || !overlay)
 		return NULL;
 	
 	// Create a list containing the overlay string
-	PyObject *list = PyList_New(1);
-	PyList_SetItem(list, 0, PyString_FromString(overlay));
-	//FIXME:directly call laymanAPIGetInfoList()
+	StringList *olist = stringListCreate(1);
+	stringListInsertAt(olist, 0, overlay);
+
+	OverlayInfo *oi = malloc(sizeof(OverlayInfo));
+	int count = laymanAPIGetInfosStr(l, olist, oi);
+	assert(1 != count);
+
+	stringListFree(olist);
+
+	return oi;
+}
+
+/*
+ * Gives a list of OverlayInfo's from the overaly names found in the overlays StringList.
+ * results must be allocated and initialized with zeroes.
+ * 
+ * If an information is unavailable (no owner email for example),
+ * the correpsonding field will stay to NULL
+ * 
+ * Returns the number of OverlayInfo structures filled.
+ */
+int laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results)
+{
+	// Check input data.
+	if (!l || !l->object || !overlays || !results)
+		return 0;
+
+	// Convert the StringList to a Python list object.
+	PyObject *list = cListToPyList(overlays);
 
 	// Call the method
-	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
+	PyObject *obj = PyObject_CallMethod(l->object, "get_all_info", "(O)", list);
 	Py_DECREF(list);
 
 	// Check if the returned value is a dict as expected.
@@ -208,68 +272,121 @@ OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 		{
 			Py_DECREF(obj);
 		}
-		return NULL;
+		return 0;
 	}
 
-	// Get the tuple corresponding to the overlay and check if it is a tuple.
-	PyObject *tuple = PyDict_GetItemString(obj, overlay);
+	PyObject *name, *dict;
+	Py_ssize_t i = 0;
+
+	int k = 0;
 
-	if (!tuple || !PyTuple_Check(tuple))
+	// Loop in the dict to get all dicts.
+	while (PyDict_Next(obj, &i, &name, &dict))
 	{
-		if (tuple)
-		{
-			Py_DECREF(tuple);
-		}
-		Py_DECREF(obj);
+		// If it's not a dict, it's ignored
+		// FIXME:should an assert be used ?
+		dict = PySequence_GetItem(dict, 0);
+		if (!dict || !PyDict_Check(dict))
+			continue;
 
-		return NULL;
-	}
+		PyObject *official = PyDict_GetItemString(dict, "official");
+		PyObject *supported = PyDict_GetItemString(dict, "supported");
+		PyObject *ownerName = PyDict_GetItemString(dict, "owner_name");
+		PyObject *ownerEmail = PyDict_GetItemString(dict, "owner_email");
+		PyObject *homepage = PyDict_GetItemString(dict, "homepage");
+		PyObject *description = PyDict_GetItemString(dict, "description");
+		PyObject *srcUris = PyDict_GetItemString(dict, "src_uris");
+		PyObject *srcType = PyDict_GetItemString(dict, "src_type");
+		PyObject *priority = PyDict_GetItemString(dict, "priority");
+		PyObject *quality = PyDict_GetItemString(dict, "quality");
+//'status':?? TODO
 
-	// Create the structure to return and fill it.
-	PyObject *text = PyTuple_GetItem(tuple, 0);
-	PyObject *official = PyTuple_GetItem(tuple, 1);
-	PyObject *supported = PyTuple_GetItem(tuple, 2);
+		// Copy values in the kth structure of the results.
+		char* tmp = PyString_AsString(name);
+		assert(NULL != tmp); //name must not be NULL
+		results[k].name = strdup(tmp);
 
-	OverlayInfo *oi = malloc(sizeof(OverlayInfo));
+		tmp = PyString_AsString(ownerName);
+		if (tmp != NULL)
+			results[k].ownerName = strdup(tmp);
+
+		tmp = PyString_AsString(ownerEmail);
+		if (tmp != NULL)
+			results[k].ownerEmail = strdup(tmp);
+
+		tmp = PyString_AsString(homepage);
+		if (tmp != NULL)
+			results[k].homepage = strdup(tmp);
 
-	char* tmp = PyString_AsString(text);
-	assert(NULL != tmp);
-	oi->text = strdup(tmp);
+		tmp = PyString_AsString(description);
+		if (tmp != NULL)
+			results[k].description = strdup(tmp);
 
-	oi->name = strdup(overlay);
+		tmp = PyString_AsString(srcType);
+		if (tmp != NULL)
+			results[k].srcType = strdup(tmp);
 
-	oi->official = PyObject_IsTrue(official);
-	assert(-1 == oi->official);
-	oi->supported = PyObject_IsTrue(supported);
-	assert(-1 == oi->supported);
+		tmp = PyString_AsString(quality);
+		if (tmp != NULL)
+			results[k].quality = strdup(tmp);
+
+		results[k].priority = PyLong_AsLong(priority);
+
+		results[k].srcUris = listToCList(srcUris);
+
+		// If official or supported is neither True or False, abort.
+		results[k].official = PyObject_IsTrue(official);
+		assert(-1 != results[k].official);
+		results[k].supported = PyObject_IsTrue(supported);
+		assert(-1 != results[k].supported);
+
+		k++;
+	}
 
 	Py_DECREF(obj);
 
-	return oi;
+	//Return the number of structures that have been filled.
+	return k;
 }
 
-int laymanAPIAddRepo(LaymanAPI* l, StringList *repos)
+/*
+ * TODO:implement the same for only 1 repo
+ */
+int laymanAPIAddRepos(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
 		return 0;
 
+	// Converting the C list to a python list
 	PyObject *pyrepos = cListToPyList(repos);
-	PyObject *obj = PyObject_CallMethod(l->object, "add_repo", "(O)", pyrepos);
+
+	// Call the method
+	PyObject *obj = PyObject_CallMethod(l->object, "add_repos", "(O)", pyrepos);
 	Py_DECREF(pyrepos);
+	
+	// If the call returned NULL, it failed.
 	if (!obj)
 		return 0;
 
 	return 1;
 }
 
-int laymanAPIDeleteRepo(LaymanAPI* l, StringList *repos)
+/*
+ * TODO:implement the same for only 1 repo
+ */
+int laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
 		return 0;
 
+	// Converting the C list to a python list
 	PyObject *pyrepos = cListToPyList(repos);
-	PyObject *obj = PyObject_CallMethod(l->object, "delete_repo", "(O)", pyrepos);
+	
+	// Call the method
+	PyObject *obj = PyObject_CallMethod(l->object, "delete_repos", "(O)", pyrepos);
 	Py_DECREF(pyrepos);
+	
+	// If the call returned NULL, it failed.
 	if (!obj)
 		return 0;
 
@@ -289,3 +406,29 @@ void laymanAPIFree(LaymanAPI* l)
 	if (l)
 		free(l);
 }
+
+
+/*
+ * Function that properly frees an OverlayInfo structure's data
+ */
+void overlayInfoFree(OverlayInfo oi)
+{
+	if (oi.name)
+		free(oi.name);
+	if (oi.text)
+		free(oi.text);
+	if (oi.ownerEmail)
+		free(oi.ownerEmail);
+	if (oi.ownerName)
+		free(oi.ownerName);
+	if (oi.homepage)
+		free(oi.homepage);
+	if (oi.description)
+		free(oi.description);
+	if (oi.srcType)
+		free(oi.srcType);
+	if (oi.quality)
+		free(oi.quality);
+	if (oi.srcUris)
+		stringListFree(oi.srcUris);
+}

diff --git a/src/laymanapi.h b/src/laymanapi.h
index 8ef90b3..f18d588 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -8,21 +8,35 @@ typedef struct LaymanAPI LaymanAPI;
 
 typedef struct OverlayInfo
 {
-	char *name;
-	char *text;
-	int official;
-	int supported;
+	char*		name;
+	char*		text;
+	char*		ownerEmail;
+	char*		ownerName;
+	char*		homepage;
+	char*		description;
+	char*		srcType;
+	char*		quality;
+	int		priority;
+	StringList*	srcUris;
+	int		official;
+	int		supported;
 } OverlayInfo;
 
 LaymanAPI*	laymanAPICreate(BareConfig*, int, int);
+int		laymanAPIIsRepo(LaymanAPI *l, const char* repo)
+int		laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
 StringList*	laymanAPIGetAvailable(LaymanAPI*, int reload);
 StringList*	laymanAPIGetInstalled(LaymanAPI*, int reload);
 int		laymanAPISync(LaymanAPI* l, const char* overlay, int verbose);
 int 		laymanAPIFetchRemoteList(LaymanAPI*);
-int		laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
-int		laymanAPIAddRepo(LaymanAPI* l, StringList *repos);
-int		laymanAPIDeleteRepo(LaymanAPI* l, StringList *repos);
+int		laymanAPIGetInfosStr(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
+OverlayInfo*	laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay);
+int		laymanAPIGetAllInfos(LaymanAPI* l, StringList*, OverlayInfo*);
+//OverlayInfo*	laymanAPIGetAllInfo(LaymanAPI* l, const char*);
+int		laymanAPIAddRepos(LaymanAPI* l, StringList *repos);
+int		laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos);
 OverlayInfo*	laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
 void		laymanAPIFree(LaymanAPI*);
+void		overlayInfoFree(OverlayInfo oi);
 
 #endif

diff --git a/src/stringlist.c b/src/stringlist.c
index 96762a1..82cd5a8 100644
--- a/src/stringlist.c
+++ b/src/stringlist.c
@@ -15,7 +15,7 @@ StringList* stringListCreate(size_t len)
 	return ret;
 }
 
-int stringListInsertAt(StringList *l, unsigned int pos, char *str)
+int stringListInsertAt(StringList *l, unsigned int pos, const char *str)
 {
 	if(!l || !l->list || l->count < pos)
 		return 0;

diff --git a/src/stringlist.h b/src/stringlist.h
index 00b4e76..8c2722e 100644
--- a/src/stringlist.h
+++ b/src/stringlist.h
@@ -7,7 +7,7 @@ typedef struct StringList StringList;
 
 StringList*	stringListCreate(size_t);
 unsigned int	stringListCount(StringList*);
-int		stringListInsertAt(StringList*, unsigned int, char*);
+int		stringListInsertAt(StringList*, unsigned int, const char*);
 char*		stringListGetAt(StringList*, unsigned int);
 StringList*	listToCList(PyObject* list);
 PyObject*	cListToPyList(StringList*);

diff --git a/src/tester.c b/src/tester.c
index cb9ae4f..3a80ec2 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -1,4 +1,3 @@
-//#include "overlay.h"
 #include "interpreter.h"
 #include "config.h"
 #include "laymanapi.h"
@@ -36,14 +35,14 @@ int main(int argc, char *argv[])
 	printf("\n");
 
 	unsigned int len = stringListCount(strs);
-	OverlayInfo *infos = malloc(sizeof(OverlayInfo) * len);
-	int count = laymanAPIGetInfoList(l, strs, infos);
+	OverlayInfo *infos = calloc(len, sizeof(OverlayInfo));
+	int count = laymanAPIGetAllInfos(l, strs, infos);
 	
 	for (unsigned int i = 0; i < count; i++)
 	{
-		printf("%s\n", infos[i].text);
-		free(infos[i].text);
-		free(infos[i].name);
+		printf("%s\n~~~~~~~~~~~~~~~~~~~~\n", infos[i].name);
+		printf("%s\n\n", infos[i].description);
+		overlayInfoFree(infos[i]);
 	}
 
 	printf("\n");



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     4c0f86834a9350a99bfe6952dfb51f6a7e6532f6
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul 16 21:14:34 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul 16 21:14:34 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=4c0f8683

Remove an obsolete workaround

---
 src/laymanapi.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 8458c38..fc79d68 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -332,7 +332,6 @@ int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *resul
 	{
 		// If it's not a dict, it's ignored
 		// FIXME:should an assert be used ?
-		dict = PySequence_GetItem(dict, 0);
 		if (!dict || !PyDict_Check(dict))
 			continue;
 



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     70bb12ccf8a86e3531826ae7bc2211061da8880a
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul 16 20:23:57 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul 16 20:23:57 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=70bb12cc

Use correct value when using PyObject_IsTrue
Add function laymanAPIGetAllInfo()
Make use of _laymanAPIGetAllInfos() as a common base for both
laymanAPIGetAllInfo() and laymanAPIGetAllInfos()
Add function laymanAPIAddRepo and laymanAPIDeleteRepo

---
 src/laymanapi.c |  135 ++++++++++++++++++++++++++++++++++++++++++++++---------
 src/laymanapi.h |    8 ++-
 src/tester.c    |   27 ++++++++---
 3 files changed, 138 insertions(+), 32 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index f524ce8..9048921 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -2,6 +2,8 @@
 #include "interpreter.h"
 #include "laymanapi.h"
 
+int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results, const char *overlay);
+
 struct LaymanAPI
 {
 	PyObject *object;
@@ -12,7 +14,6 @@ struct LaymanAPI
  *
  * The BareConfig argument must not be NULL.
  */
-
 LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
 	assert(NULL != config);
@@ -41,7 +42,7 @@ int laymanAPIIsRepo(LaymanAPI *l, const char* repo)
 
 	Py_DECREF(obj);
 
-	return ret;
+	return !ret;
 }
 
 int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
@@ -59,7 +60,7 @@ int laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
 
 	Py_DECREF(obj);
 
-	return ret;
+	return !ret;
 }
 
 /*
@@ -206,9 +207,9 @@ int laymanAPIGetInfosStr(LaymanAPI* l, StringList* overlays, OverlayInfo* result
 		assert(NULL != tmp);
 		results[k].text = strdup(tmp);
 
-		results[k].official = PyObject_IsTrue(official);
+		results[k].official = !PyObject_IsTrue(official);
 		assert(-1 != results[k].official);
-		results[k].supported = PyObject_IsTrue(supported);
+		results[k].supported = !PyObject_IsTrue(supported);
 		assert(-1 != results[k].supported);
 
 		k++;
@@ -243,6 +244,26 @@ OverlayInfo *laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay)
 	return oi;
 }
 
+OverlayInfo *laymanAPIGetAllInfo(LaymanAPI* l, const char* overlay)
+{
+	// Check input data.
+	if (!l || !l->object || !overlay)
+		return NULL;
+	
+	// Prepare the structure to be returned.
+	OverlayInfo *ret = calloc(1, sizeof(OverlayInfo));
+	
+	// Fill it in.
+	if (0 == _laymanAPIGetAllInfos(l, NULL, ret, overlay))
+	{
+		free(ret);
+		return NULL;
+	}
+
+	// Return it
+	return ret;
+}
+
 /*
  * Gives a list of OverlayInfo's from the overaly names found in the overlays StringList.
  * results must be allocated and initialized with zeroes.
@@ -254,16 +275,42 @@ OverlayInfo *laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay)
  */
 int laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results)
 {
+	return _laymanAPIGetAllInfos(l, overlays, results, NULL);
+}
+
+/*
+ * Gives a list of OverlayInfo's from the overaly names found in the overlays StringList if it's not NULL
+ * If it's NULL, and overlay is not NULL, the information for Overlay will be fetched.
+ * results must be allocated and initialized with zeroes.
+ * 
+ * If an information is unavailable (no owner email for example),
+ * the correpsonding field will stay to NULL
+ * 
+ * Returns the number of OverlayInfo structures filled.
+ */
+int _laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *results, const char *overlay)
+{
 	// Check input data.
-	if (!l || !l->object || !overlays || !results)
+	if (!l || !l->object || !results || (!overlays && !overlay))
 		return 0;
 
-	// Convert the StringList to a Python list object.
-	PyObject *list = cListToPyList(overlays);
+	PyObject *obj = NULL;
 
-	// Call the method
-	PyObject *obj = PyObject_CallMethod(l->object, "get_all_info", "(O)", list);
-	Py_DECREF(list);
+	// First case : overlay list
+	if (overlays != NULL)
+	{
+		// Convert the StringList to a Python list object.
+		PyObject *list = cListToPyList(overlays);
+
+		// Call the method
+		obj = PyObject_CallMethod(l->object, "get_all_info", "(O)", list);
+		Py_DECREF(list);
+	}
+	// Second case : overlay name
+	else if (overlay != NULL)
+	{
+		obj = PyObject_CallMethod(l->object, "get_all_info", "(s)", overlay);
+	}
 
 	// Check if the returned value is a dict as expected.
 	if (!obj || !PyDict_Check(obj))
@@ -335,9 +382,9 @@ int laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *result
 		results[k].srcUris = listToCList(srcUris);
 
 		// If official or supported is neither True or False, abort.
-		results[k].official = PyObject_IsTrue(official);
+		results[k].official = !PyObject_IsTrue(official);
 		assert(-1 != results[k].official);
-		results[k].supported = PyObject_IsTrue(supported);
+		results[k].supported = !PyObject_IsTrue(supported);
 		assert(-1 != results[k].supported);
 
 		k++;
@@ -349,9 +396,26 @@ int laymanAPIGetAllInfos(LaymanAPI* l, StringList* overlays, OverlayInfo *result
 	return k;
 }
 
-/*
- * TODO:implement the same for only 1 repo
- */
+int laymanAPIAddRepo(LaymanAPI* l, const char *repo)
+{
+	if (!l || !l->object || !repo)
+		return 0;
+
+	// Call the method
+	PyObject *obj = PyObject_CallMethod(l->object, "delete_repos", "(s)", repo);
+	
+	// If the call returned NULL, it failed.
+	int ret;
+	if (!obj)
+		ret = 0;
+	else
+		ret = 1;
+	
+	Py_DECREF(obj);
+
+	return ret;
+}
+
 int laymanAPIAddRepos(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
@@ -365,15 +429,37 @@ int laymanAPIAddRepos(LaymanAPI* l, StringList *repos)
 	Py_DECREF(pyrepos);
 	
 	// If the call returned NULL, it failed.
+	int ret;
 	if (!obj)
+		ret = 0;
+	else
+		ret = 1;
+	
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int laymanAPIDeleteRepo(LaymanAPI* l, const char *repo)
+{
+	if (!l || !l->object || !repo)
 		return 0;
 
-	return 1;
+	// Call the method
+	PyObject *obj = PyObject_CallMethod(l->object, "delete_repos", "(s)", repo);
+	
+	// If the call returned NULL, it failed.
+	int ret;
+	if (!obj)
+		ret = 0;
+	else
+		ret = 1;
+	
+	Py_DECREF(obj);
+
+	return ret;
 }
 
-/*
- * TODO:implement the same for only 1 repo
- */
 int laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos)
 {
 	if (!l || !l->object || !repos)
@@ -387,10 +473,15 @@ int laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos)
 	Py_DECREF(pyrepos);
 	
 	// If the call returned NULL, it failed.
+	int ret;
 	if (!obj)
-		return 0;
+		ret = 0;
+	else
+		ret = 1;
+	
+	Py_DECREF(obj);
 
-	return 1;
+	return ret;
 }
 
 /*

diff --git a/src/laymanapi.h b/src/laymanapi.h
index f18d588..94b0591 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -23,8 +23,8 @@ typedef struct OverlayInfo
 } OverlayInfo;
 
 LaymanAPI*	laymanAPICreate(BareConfig*, int, int);
-int		laymanAPIIsRepo(LaymanAPI *l, const char* repo)
-int		laymanAPIIsInstalled(LaymanAPI *l, const char* repo)
+int		laymanAPIIsRepo(LaymanAPI *l, const char* repo);
+int		laymanAPIIsInstalled(LaymanAPI *l, const char* repo);
 StringList*	laymanAPIGetAvailable(LaymanAPI*, int reload);
 StringList*	laymanAPIGetInstalled(LaymanAPI*, int reload);
 int		laymanAPISync(LaymanAPI* l, const char* overlay, int verbose);
@@ -32,8 +32,10 @@ int 		laymanAPIFetchRemoteList(LaymanAPI*);
 int		laymanAPIGetInfosStr(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
 OverlayInfo*	laymanAPIGetInfoStr(LaymanAPI* l, const char* overlay);
 int		laymanAPIGetAllInfos(LaymanAPI* l, StringList*, OverlayInfo*);
-//OverlayInfo*	laymanAPIGetAllInfo(LaymanAPI* l, const char*);
+OverlayInfo*	laymanAPIGetAllInfo(LaymanAPI* l, const char*);
+int		laymanAPIAddRepo(LaymanAPI* l, const char *repo);
 int		laymanAPIAddRepos(LaymanAPI* l, StringList *repos);
+int		laymanAPIDeleteRepo(LaymanAPI* l, const char *repo);
 int		laymanAPIDeleteRepos(LaymanAPI* l, StringList *repos);
 OverlayInfo*	laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
 void		laymanAPIFree(LaymanAPI*);

diff --git a/src/tester.c b/src/tester.c
index 3a80ec2..3268f66 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -35,19 +35,32 @@ int main(int argc, char *argv[])
 	printf("\n");
 
 	unsigned int len = stringListCount(strs);
-	OverlayInfo *infos = calloc(len, sizeof(OverlayInfo));
-	int count = laymanAPIGetAllInfos(l, strs, infos);
+	//OverlayInfo *infos = calloc(len, sizeof(OverlayInfo));
+	//int count = laymanAPIGetAllInfos(l, strs, infos);
 	
-	for (unsigned int i = 0; i < count; i++)
+	OverlayInfo *oi = laymanAPIGetAllInfo(l, "enlightenment");
+	if (oi)
 	{
-		printf("%s\n~~~~~~~~~~~~~~~~~~~~\n", infos[i].name);
-		printf("%s\n\n", infos[i].description);
-		overlayInfoFree(infos[i]);
+		printf("%s\n~~~~~~~~~~~~~~~~~~~~\n", oi->name);
+		printf("%s\n\n", oi->description);
+		overlayInfoFree(*oi);
+		free(oi);
+	}
+
+	for (unsigned int i = 0; i < len; i++)
+	{
+		OverlayInfo *oi = laymanAPIGetAllInfo(l, stringListGetAt(strs, i));
+		if (!oi)
+			continue;
+		printf("%s\n~~~~~~~~~~~~~~~~~~~~\n", oi->name);
+		printf("%s\n\n", oi->description);
+		overlayInfoFree(*oi);
+		free(oi);
 	}
 
 	printf("\n");
 
-	free(infos);
+	//free(infos);
 
 	bareConfigFree(cfg);
 	laymanAPIFree(l);



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     dfa1e0f4d7b908dc499421cf75d5462a9df8cc37
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Thu Jul 15 11:39:29 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Thu Jul 15 11:39:29 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=dfa1e0f4

Don't DECREF on borrowed references

---
 src/laymanapi.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 4509511..7620869 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -144,10 +144,6 @@ OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 	oi->supported = PyObject_IsTrue(supported);
 
 	Py_DECREF(obj);
-	Py_DECREF(tuple);
-	Py_DECREF(text);
-	Py_DECREF(official);
-	Py_DECREF(supported);
 
 	return oi;
 }



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     2e6f2b74e2c1c66afcadc67af1df1b112ba15cdb
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Thu Jul 15 14:11:49 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Thu Jul 15 14:11:49 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=2e6f2b74

Fix a warning in Dict
Add a method to get info for a list of overlays

---
 src/dict.c       |    6 +----
 src/dict.h       |    2 +-
 src/laymanapi.c  |   71 ++++++++++++++++++++++++++++++++++++++++++++----------
 src/laymanapi.h  |   16 ++----------
 src/stringlist.c |    2 +-
 src/tester.c     |   17 +++++++------
 6 files changed, 73 insertions(+), 41 deletions(-)

diff --git a/src/dict.c b/src/dict.c
index a818a69..0deebe9 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -46,7 +46,7 @@ unsigned int dictCount(Dict *list)
 	return (list ? list->count : 0);
 }
 
-void dictFree(Dict *list, int deref)
+void dictFree(Dict *list)
 {
 	if (!list)
 		return;
@@ -56,10 +56,6 @@ void dictFree(Dict *list, int deref)
 	{
 		DictElem *tmp = node;
 		node = node->next;
-		/*if (deref)
-		{
-			Py_DECREF(tmp->object);
-		}*/
 		free(tmp);
 	}
 

diff --git a/src/dict.h b/src/dict.h
index 844963c..47dd957 100644
--- a/src/dict.h
+++ b/src/dict.h
@@ -7,7 +7,7 @@ typedef struct Dict Dict;
 
 Dict*		dictCreate();
 //char*		tableFind(Dict *table, char* key);
-void		dictFree(Dict *t, int);
+void		dictFree(Dict *t);
 void		dictInsert(Dict* list, const char* key, const char* value);
 unsigned int	dictCount(Dict *table);
 PyObject*	dictToPyDict(Dict *dict);

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 7620869..5de0140 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -11,12 +11,6 @@ struct LaymanAPI
 	PyObject *object;
 };
 
-OverlayInfo strToInfo(const char* str)
-{
-	OverlayInfo ret;
-	return ret;
-}
-
 LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
 	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "Oii", _bareConfigObject(config), report_error, output);
@@ -41,11 +35,6 @@ StringList* laymanAPIGetAvailable(LaymanAPI* l, int reload)
 	return ret;
 }
 
-/*StringList* laymanAPIGetInstalled(LaymanAPI* l)
-{
-	return laymanAPIGetInstalled(l, 0);
-}*/
-
 StringList* laymanAPIGetInstalled(LaymanAPI* l, int reload)
 {
 	if (!l || !l->object)
@@ -97,13 +86,69 @@ int laymanAPIFetchRemoteList(LaymanAPI* l)
 	return ret;
 }
 
+int laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
+{
+	if (!l || !l->object || !overlays || !results)
+		return 0;
+
+	PyObject *list = cListToPyList(overlays);
+	
+	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
+	Py_DECREF(list);
+
+	if (!obj || !PyDict_Check(obj))
+	{
+		if (obj)
+		{
+			Py_DECREF(obj);
+		}
+		return 0;
+	}
+
+	PyObject *name, *tuple;
+	Py_ssize_t i = 0;
+
+	int k = 0;
+
+	while (PyDict_Next(obj, &i, &name, &tuple))
+	{
+		if (!tuple || !PyTuple_Check(tuple))
+		{
+			Py_DECREF(obj);
+			continue;
+		}
+
+		PyObject *text = PyTuple_GetItem(tuple, 0);
+		PyObject *official = PyTuple_GetItem(tuple, 1);
+		PyObject *supported = PyTuple_GetItem(tuple, 2);
+
+		if (!PyString_Check(text) || !PyString_Check(name))
+			continue;
+
+		char* tmp = PyString_AsString(name);
+		results[k].name = malloc((strlen(tmp) + 1) * sizeof(char));
+		strcpy(results[k].name, tmp);
+
+		tmp = PyString_AsString(text);
+		results[k].text = malloc((strlen(tmp) + 1) * sizeof(char));
+		strcpy(results[k].text, tmp);
+
+		results[k].official = PyObject_IsTrue(official);
+		results[k].supported = PyObject_IsTrue(supported);
+		k++;
+	}
+
+	Py_DECREF(obj);
+	return k;
+}
+
 OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 {
 	if (!l || !l->object || !overlay)
 		return NULL;
 
 	PyObject *list = PyList_New(1);
-	PyList_SetItem(list, 0, PyBytes_FromString(overlay));
+	PyList_SetItem(list, 0, PyString_FromString(overlay));
 
 	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
 	Py_DECREF(list);
@@ -136,7 +181,7 @@ OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 
 	OverlayInfo *oi = malloc(sizeof(OverlayInfo));
 
-	char* tmp = PyBytes_AsString(text);
+	char* tmp = PyString_AsString(text);
 	oi->text = malloc((strlen(tmp) + 1) * sizeof(char));
 	strcpy(oi->text, tmp);
 

diff --git a/src/laymanapi.h b/src/laymanapi.h
index 0a38169..43f99e2 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -6,31 +6,21 @@
 
 typedef struct LaymanAPI LaymanAPI;
 
-typedef enum OverlayType {Svn = 0, Git, Bzr} OverlayType;
-typedef enum OverlayQuality {Experimental = 0, Stable, Testing} OverlayQuality;
 typedef struct OverlayInfo
 {
+	char *name;
 	char *text;
-	/*char *name;
-	char *source;
-	char *contact;
-	OverlayType type;
-	int priority;
-	OverlayQuality quality;
-	char *description;
-	char *link;
-	char *feed;*/
 	int official;
 	int supported;
 } OverlayInfo;
 
-
 LaymanAPI*	laymanAPICreate(BareConfig*, int, int);
 StringList*	laymanAPIGetAvailable(LaymanAPI*, int reload);
 StringList*	laymanAPIGetInstalled(LaymanAPI*, int reload);
 int		laymanAPISync(LaymanAPI* l, const char* overlay, int verbose);
 int 		laymanAPIFetchRemoteList(LaymanAPI*);
-OverlayInfo	*laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
+int		laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
+OverlayInfo*	laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
 void		laymanAPIFree(LaymanAPI*);
 
 #endif

diff --git a/src/stringlist.c b/src/stringlist.c
index 7944564..96762a1 100644
--- a/src/stringlist.c
+++ b/src/stringlist.c
@@ -68,7 +68,7 @@ PyObject* cListToPyList(StringList* list)
 	PyObject *ret = PyList_New(list->count);
 	for(unsigned int i = 0; i < list->count; i++)
 	{
-		PyList_Append(ret, PyBytes_FromString(list->list[i]));
+		PyList_SetItem(ret, i, PyBytes_FromString(list->list[i]));
 	}
 
 	return ret;

diff --git a/src/tester.c b/src/tester.c
index 1d31407..61497a7 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -36,19 +36,20 @@ int main(int argc, char *argv[])
 	printf("\n");
 
 	unsigned int len = stringListCount(strs);
-	for (unsigned int i = 0; i < len; i++)
+	OverlayInfo *infos = malloc(sizeof(OverlayInfo) * len);
+	int count = laymanAPIGetInfoList(l, strs, infos);
+	
+	for (unsigned int i = 0; i < count; i++)
 	{
-		OverlayInfo *info = laymanAPIGetInfo(l, stringListGetAt(strs, i));
-		if (!info)
-			continue;
-		printf("%s\n", info->text);
-		free(info->text);
-		free(info);
+		printf("%s\n", infos[i].text);
+		free(infos[i].text);
+		free(infos[i].name);
 	}
 
 	printf("\n");
 
-finish:
+	free(infos);
+
 	bareConfigFree(cfg);
 	laymanAPIFree(l);
 	stringListFree(strs);



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     01ff056a55b198b91ef327d7ca223bab9452034c
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Thu Jul 15 10:09:26 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Thu Jul 15 10:09:26 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=01ff056a

Get to work with the changes in layman.
Fix most of the memory leaks

---
 src/config.c     |   34 ++++++++++++++++--
 src/config.h     |    3 +-
 src/dbbase.c     |   10 +++++
 src/dbbase.h     |    1 +
 src/laymanapi.c  |  105 ++++++++++++++++++++++++++++++++++++------------------
 src/laymanapi.h  |   29 ++++-----------
 src/message.c    |   10 +++++
 src/message.h    |    5 ++-
 src/stringlist.c |   57 +++++++++++++++++++++++------
 src/stringlist.h |   13 ++++---
 src/tester.c     |   36 ++++++++++++++-----
 11 files changed, 214 insertions(+), 89 deletions(-)

diff --git a/src/config.c b/src/config.c
index 624f1ab..47d4437 100644
--- a/src/config.c
+++ b/src/config.c
@@ -57,16 +57,44 @@ const char* bareConfigGetDefaultValue(BareConfig* cfg, const char* opt)
 		return NULL;
 
 	if (PyDict_Contains(obj, PyBytes_FromString(opt)))
-		return PyBytes_AsString(PyDict_GetItem(obj, PyBytes_FromString(opt)));
+	{
+		PyObject *pyopt = PyBytes_FromString(opt);
+		char *tmp = PyBytes_AsString(PyDict_GetItem(obj, pyopt));
+		Py_DECREF(pyopt);
+
+		char *ret = malloc(sizeof(char) * strlen(tmp));
+		strcpy(ret, tmp);
+		Py_DECREF(obj);
+
+		return ret;
+	}
 	else
 		return "";
 }
 
+const char* bareConfigGetOptionValue(BareConfig* cfg, const char* opt)
+{
+	PyObject *obj = PyObject_CallMethod(cfg->object, "get_option", "(z)", opt);
+	char *tmp = PyBytes_AsString(obj);
+	char *ret = malloc(sizeof(char) * (strlen(tmp) + 1));
+
+	strcpy(ret, tmp);
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
 int bareConfigSetOptionValue(BareConfig* cfg, const char* opt, const char* val)
 {
 	PyObject *obj = PyObject_CallMethod(cfg->object, "set_option", "(zz)", opt, val);
+	int ret;
 	if (obj)
-		return 1;
+		ret = 1;
 	else
-		return 0;
+		ret = 0;
+	
+	Py_DECREF(obj);
+
+	return ret;
 }

diff --git a/src/config.h b/src/config.h
index 33bfd1e..a89883b 100644
--- a/src/config.h
+++ b/src/config.h
@@ -15,10 +15,9 @@ BareConfig*	bareConfigCreate(Message* m, FILE* outFd, FILE* inFd, FILE* errFd);
  */
 
 const char*	bareConfigGetDefaultValue(BareConfig* cfg, const char*);
+const char*	bareConfigGetOptionValue(BareConfig* cfg, const char* opt);
 int 		bareConfigSetOptionValue(BareConfig* cfg, const char*, const char*);
-
 PyObject* 	_bareConfigObject(BareConfig*);
-
 void 		bareConfigFree(BareConfig*);
 
 #endif

diff --git a/src/dbbase.c b/src/dbbase.c
index dbff007..fdefac4 100644
--- a/src/dbbase.c
+++ b/src/dbbase.c
@@ -29,3 +29,13 @@ DbBase* createDbBase(const char *paths[], unsigned int pathCount, Dict *dict, in
 
 	return ret;
 }
+
+void dbBaseFree(DbBase* db)
+{
+	if (db && db->object)
+	{
+		Py_DECREF(db->object);
+	}
+	if (db)
+		free(db);
+}

diff --git a/src/dbbase.h b/src/dbbase.h
index 56f9270..bd3786c 100644
--- a/src/dbbase.h
+++ b/src/dbbase.h
@@ -7,5 +7,6 @@
 typedef struct DbBase DbBase;
 
 DbBase* createDbBase(const char *paths[], unsigned int path_count, Dict *c, int ignore, int quiet, int ignore_init_read_errors);
+void dbBaseFree(DbBase*);
 
 #endif

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 328a572..4509511 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -19,7 +19,7 @@ OverlayInfo strToInfo(const char* str)
 
 LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
-	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "OII", _bareConfigObject(config), report_error, output);
+	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "Oii", _bareConfigObject(config), report_error, output);
 	if (!obj)
 		return NULL;
 
@@ -29,92 +29,127 @@ LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 	return ret;
 }
 
-StringList* laymanAPIGetAvailable(LaymanAPI* l)
+StringList* laymanAPIGetAvailable(LaymanAPI* l, int reload)
 {
 	if (!l || !l->object)
 		return NULL;
 
-	PyObject *obj = PyObject_CallMethod(l->object, "get_available", NULL);
-	StringList* ret = listToCList(obj);
+	PyObject *obj = PyObject_CallMethod(l->object, "get_available", "(i)", reload);
+	StringList *ret = listToCList(obj);
 	Py_DECREF(obj);
 
 	return ret;
 }
 
-StringList* laymanAPIGetInstalled(LaymanAPI* l)
+/*StringList* laymanAPIGetInstalled(LaymanAPI* l)
+{
+	return laymanAPIGetInstalled(l, 0);
+}*/
+
+StringList* laymanAPIGetInstalled(LaymanAPI* l, int reload)
 {
 	if (!l || !l->object)
 		return NULL;
 
-	PyObject *obj = PyObject_CallMethod(l->object, "get_installed", NULL);
+	PyObject *obj = PyObject_CallMethod(l->object, "get_installed", "(i)", reload);
 	StringList* ret = listToCList(obj);
 	Py_DECREF(obj);
 
 	return ret;
 }
 
-int laymanAPISync(LaymanAPI* l, const char* overlay)
+int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 {
 	if (!l || !l->object)
-		return EXIT_FAILURE;
-
-	PyObject *list = PyList_New(1);
-	PyList_Insert(list, 0, PyBytes_FromString(overlay));
-
-	PyObject *obj = PyObject_CallMethod(l->object, "sync", "O", list);
-	Py_DECREF(list);
+		return 0;
 
+	PyObject *obj = PyObject_CallMethod(l->object, "sync", "(si)", overlay, verbose);
 	if (!obj)
-		return EXIT_FAILURE;
+		return 0;
 
-	PyObject *success = PyList_GetItem(obj, 1);
-	if (success == Py_None)
-		return EXIT_FAILURE;
+	int ret;
+	if (PyObject_IsTrue(obj))
+		ret = 1;
+	else
+		ret = 0;
+	
+	Py_DECREF(obj);
 	
-	return EXIT_SUCCESS;
+	return ret;
 }
 
 int laymanAPIFetchRemoteList(LaymanAPI* l)
 {
 	if (!l || !l->object)
-		return EXIT_FAILURE;
+		return 0;
 	
 	PyObject *obj = PyObject_CallMethod(l->object, "fetch_remote_list", NULL);
 
 	int ret;
 
-	if (PyObject_IsTrue(obj))
-		ret = EXIT_SUCCESS;
+	if (!PyObject_IsTrue(obj)) //FIXME : does this work ? It seems to return 1 when false and 0 when true
+		ret = 1;
 	else
-		ret = EXIT_FAILURE;
+		ret = 0;
 	
 	Py_DECREF(obj);
 
 	return ret;
 }
 
-const char* laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
+OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 {
-	if (!l || !l->object)
+	if (!l || !l->object || !overlay)
 		return NULL;
 
 	PyObject *list = PyList_New(1);
-	PyList_Insert(list, 0, PyBytes_FromString(overlay));
+	PyList_SetItem(list, 0, PyBytes_FromString(overlay));
 
-	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "O", list);
+	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
 	Py_DECREF(list);
 
-	if (!obj)
+	if (!obj || !PyDict_Check(obj))
+	{
+		if (obj)
+		{
+			Py_DECREF(obj);
+		}
 		return NULL;
+	}
 
-	PyObject *result = PyList_GetItem(obj, 0);
-	char* tmp = PyBytes_AsString(result);
-	char* ret = malloc((strlen(tmp) + 1) * sizeof(char));
-	strcpy(ret, tmp);
-	Py_DECREF(result);
+	PyObject *tuple = PyDict_GetItemString(obj, overlay);
 
-	return ret;
-	//TODO:also return 'official' an 'supported' (see laymanapi.h)
+	if (!tuple || !PyTuple_Check(tuple))
+	{
+		if (tuple)
+		{
+			Py_DECREF(tuple);
+		}
+		Py_DECREF(obj);
+
+		return NULL;
+	}
+
+	PyObject *text = PyTuple_GetItem(tuple, 0);
+	PyObject *official = PyTuple_GetItem(tuple, 1);
+	PyObject *supported = PyTuple_GetItem(tuple, 2);
+
+	OverlayInfo *oi = malloc(sizeof(OverlayInfo));
+
+	char* tmp = PyBytes_AsString(text);
+	oi->text = malloc((strlen(tmp) + 1) * sizeof(char));
+	strcpy(oi->text, tmp);
+
+	oi->official = PyObject_IsTrue(official);
+	oi->supported = PyObject_IsTrue(supported);
+
+	Py_DECREF(obj);
+	Py_DECREF(tuple);
+	Py_DECREF(text);
+	Py_DECREF(official);
+	Py_DECREF(supported);
+
+	return oi;
 }
 
 void laymanAPIFree(LaymanAPI* l)

diff --git a/src/laymanapi.h b/src/laymanapi.h
index c89d3a4..0a38169 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -10,7 +10,8 @@ typedef enum OverlayType {Svn = 0, Git, Bzr} OverlayType;
 typedef enum OverlayQuality {Experimental = 0, Stable, Testing} OverlayQuality;
 typedef struct OverlayInfo
 {
-	char *name;
+	char *text;
+	/*char *name;
 	char *source;
 	char *contact;
 	OverlayType type;
@@ -18,32 +19,18 @@ typedef struct OverlayInfo
 	OverlayQuality quality;
 	char *description;
 	char *link;
-	char *feed;
+	char *feed;*/
 	int official;
 	int supported;
 } OverlayInfo;
 
 
 LaymanAPI*	laymanAPICreate(BareConfig*, int, int);
-StringList*	laymanAPIGetAvailable(LaymanAPI*);
-StringList*	laymanAPIGetInstalled(LaymanAPI*);
-
-/*
- * The Python API returns a list of warnings/sucesses/errors
- * In here, a boolean value is returned.
- * Warnings can be retreived with
- * 	laymanAPIWarnings()
- * 	laymanAPIErrors()
- * As there's only one argument here, there's need to have success results.
- *
- * The reason it's done this way is that the Python way of doing things is not the same as the Python way.
- *
- * FIXME:is it a good idea to have different APIs for different languages ?
- */
-int 		laymanAPISync(LaymanAPI*, const char*);
+StringList*	laymanAPIGetAvailable(LaymanAPI*, int reload);
+StringList*	laymanAPIGetInstalled(LaymanAPI*, int reload);
+int		laymanAPISync(LaymanAPI* l, const char* overlay, int verbose);
 int 		laymanAPIFetchRemoteList(LaymanAPI*);
-const char*	laymanAPIGetInfo(LaymanAPI*, const char*);
-
-void laymanAPIFree(LaymanAPI*);
+OverlayInfo	*laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
+void		laymanAPIFree(LaymanAPI*);
 
 #endif

diff --git a/src/message.c b/src/message.c
index 85a1717..14b211c 100644
--- a/src/message.c
+++ b/src/message.c
@@ -69,6 +69,16 @@ Message *messageCreate(const char* module,
 	return ret;
 }
 
+void messageFree(Message *m)
+{
+	if (m && m->object)
+	{
+		Py_DECREF(m->object);
+	}
+	if (m)
+		free(m);
+}
+
 PyObject *_messageObject(Message* m)
 {
 	if (m && m->object)

diff --git a/src/message.h b/src/message.h
index 15f3e15..33399f6 100644
--- a/src/message.h
+++ b/src/message.h
@@ -9,7 +9,8 @@ typedef struct Message Message;
 /*
  * arguments : module (String), stdout (fd), stderr (fd), stderr (fd), debug_level, debug_verbosity, info_level, warn_level, ?, ?, ?, ?
  */
-Message *messageCreate(const char*, FILE*, FILE*, FILE*, int, int, int, int, int, StringList*, StringList*, StringList*);
-PyObject *_messageObject(Message* m);
+Message*	messageCreate(const char*, FILE*, FILE*, FILE*, int, int, int, int, int, StringList*, StringList*, StringList*);
+PyObject*	_messageObject(Message* m);
+void		messageFree(Message *m);
 
 #endif

diff --git a/src/stringlist.c b/src/stringlist.c
index 22d6ef6..7944564 100644
--- a/src/stringlist.c
+++ b/src/stringlist.c
@@ -3,12 +3,41 @@
 struct StringList
 {
 	char **list;
-	int count;
+	unsigned int count;
 };
 
-StringList* stringListCreate(size_t count)
+StringList* stringListCreate(size_t len)
 {
-	return NULL;
+	StringList *ret = malloc(sizeof(StringList));
+	ret->count = len;
+	ret->list = malloc(sizeof(char*) * len);
+
+	return ret;
+}
+
+int stringListInsertAt(StringList *l, unsigned int pos, char *str)
+{
+	if(!l || !l->list || l->count < pos)
+		return 0;
+	
+	l->list[pos] = str;
+
+	return 1;
+}
+
+unsigned int stringListCount(StringList *l)
+{
+	if (!l)
+		return 0;
+	return l->count;
+}
+
+char* stringListGetAt(StringList *l, unsigned int pos)
+{
+	if (!l || !l->list || pos >= l->count)
+		return NULL;
+	
+	return l->list[pos];
 }
 
 StringList* listToCList(PyObject* list)
@@ -16,12 +45,12 @@ StringList* listToCList(PyObject* list)
 	if (!list || !PyList_Check(list))
 		return NULL;
 
-	int len = PyList_Size(list);
+	unsigned int len = PyList_Size(list);
 	StringList *ret = malloc(sizeof(StringList));
 	ret->count = len;
 	ret->list = malloc(sizeof(char*) * len);
 
-	for (int i = 0; i < len; i++)
+	for (unsigned int i = 0; i < len; i++)
 	{
 		PyObject *elem = PyList_GetItem(list, i);
 		ret->list[i] = malloc(sizeof(char) * (PyBytes_Size(elem) + 1));
@@ -37,7 +66,7 @@ PyObject* cListToPyList(StringList* list)
 		Py_RETURN_NONE;
 
 	PyObject *ret = PyList_New(list->count);
-	for(int i = 0; i < list->count; i++)
+	for(unsigned int i = 0; i < list->count; i++)
 	{
 		PyList_Append(ret, PyBytes_FromString(list->list[i]));
 	}
@@ -50,14 +79,12 @@ void stringListPrint(StringList* list)
 	if (!list)
 		return;
 
-	for(int i = 0; i < list->count; i++)
+	for(unsigned int i = 0; i < list->count; i++)
 	{
 		printf("\"%s\"", list->list[i]);
 		if (i < list->count - 1)
 			printf(", ");
 	}
-
-	free(list);
 }
 
 void stringListFree(StringList* list)
@@ -65,11 +92,17 @@ void stringListFree(StringList* list)
 	if (!list)
 		return;
 
-	for(int i = 0; i < list->count; i++)
+	if (list && list->list)
 	{
-		free(list->list[i]);
+		for(unsigned int i = 0; i < list->count; i++)
+		{
+			free(list->list[i]);
+		}
+
+		free(list->list);
 	}
 
-	free(list);
+	if (list)
+		free(list);
 }
 

diff --git a/src/stringlist.h b/src/stringlist.h
index 46151a4..00b4e76 100644
--- a/src/stringlist.h
+++ b/src/stringlist.h
@@ -5,10 +5,13 @@
 
 typedef struct StringList StringList;
 
-StringList* stringListCreate(size_t);
-StringList* listToCList(PyObject* list);
-PyObject* cListToPyList(StringList*);
-void stringListPrint(StringList*);
-void stringListFree(StringList*);
+StringList*	stringListCreate(size_t);
+unsigned int	stringListCount(StringList*);
+int		stringListInsertAt(StringList*, unsigned int, char*);
+char*		stringListGetAt(StringList*, unsigned int);
+StringList*	listToCList(PyObject* list);
+PyObject*	cListToPyList(StringList*);
+void		stringListPrint(StringList*);
+void		stringListFree(StringList*);
 
 #endif

diff --git a/src/tester.c b/src/tester.c
index 7fc40f9..1d31407 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -13,27 +13,45 @@ int main(int argc, char *argv[])
 	
 	Message *msg = messageCreate("layman", 0, 0, 0, 4, 2, 4, 4, 1, NULL, NULL, NULL);
 	BareConfig *cfg = bareConfigCreate(msg, 0, 0, 0);
-	if (!bareConfigSetOptionValue(cfg, "local_list", "/home/detlev/srg/gsoc2010/layman/layman/tests/testfiles/global-overlays.xml"))
+	/*if (!bareConfigSetOptionValue(cfg, "local_list", "/home/detlev/src/gsoc2010/layman/layman/tests/testfiles/global-overlays.xml"))
 		printf("Error setting config option.\n");
-	//printf("config: %s\n", bareConfigGetDefaultValue(cfg, "config"));
-	//printf("storage: %s\n", bareConfigGetDefaultValue(cfg, "storage"));
-	//printf("local_list: %s\n", bareConfigGetDefaultValue(cfg, "local_list"));
-	
+	if (!bareConfigSetOptionValue(cfg, "storage", "/home/detlev/gsoc2010/layman-test"))
+		printf("Error setting config option.\n");
+	printf("config: %s\n", bareConfigGetOptionValue(cfg, "config"));
+	printf("storage: %s\n", bareConfigGetOptionValue(cfg, "storage"));
+	printf("local_list: %s\n", bareConfigGetOptionValue(cfg, "local_list"));*/
+
 	LaymanAPI *l = laymanAPICreate(cfg, 0, 0);
-	if (!laymanAPIFetchRemoteList(l))
+	/*if (0 == laymanAPIFetchRemoteList(l))
 	{
 		printf("Unable to fetch the remote list.\n");
 		ret = -1;
 		goto finish;
-	}
-
-	StringList *strs = laymanAPIGetAvailable(l);
+	}*/
 
+	StringList *strs = laymanAPIGetAvailable(l, 0);
+	printf("list:\n");
 	stringListPrint(strs);
+	
+	printf("\n");
+
+	unsigned int len = stringListCount(strs);
+	for (unsigned int i = 0; i < len; i++)
+	{
+		OverlayInfo *info = laymanAPIGetInfo(l, stringListGetAt(strs, i));
+		if (!info)
+			continue;
+		printf("%s\n", info->text);
+		free(info->text);
+		free(info);
+	}
+
+	printf("\n");
 
 finish:
 	bareConfigFree(cfg);
 	laymanAPIFree(l);
+	stringListFree(strs);
 
 	interpreterFinalize();
 



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     52b03be4a2adb3b08a39080f7d8f91e3b792f50d
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul 16 14:02:56 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul 16 14:02:56 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=52b03be4

Make functions use the updates in the api
Fix memory management errors, add a construction function for string
list
Fix laymanAPIGetInfo() to use a list of tuples
Fix laymanAPIGetInfo() not to crash
Add a function to the layman API to get information from a list of
overlays
Check all python objects after a call to Python
Use asserts when PyObject_IsTrue returns -1
Add comments where necessary
Implement missing functions : laymanAPIAddRepo, laymanAPIDeleteRepo
Modify the Message class constructor to only take mandatory arguments,
other arguments can be set with the corresponding methods

---
 src/config.c      |   36 +++++++---
 src/dbbase.c      |   41 ----------
 src/dbbase.h      |   12 ---
 src/interpreter.c |   18 +----
 src/laymanapi.c   |  144 +++++++++++++++++++++++++++++-------
 src/laymanapi.h   |    2 +
 src/message.c     |  212 ++++++++++++++++++++++++++++++++++++++++++++---------
 src/message.h     |    2 +-
 src/tester.c      |    2 +-
 9 files changed, 324 insertions(+), 145 deletions(-)

diff --git a/src/config.c b/src/config.c
index 47d4437..12490f7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -16,14 +16,21 @@ PyObject *_bareConfigObject(BareConfig *c)
 		Py_RETURN_NONE;
 }
 
+/*
+ * Creates a bare config object with default values.
+ */
 BareConfig *bareConfigCreate(Message *m, FILE* outFd, FILE* inFd, FILE* errFd)
 {
-	PyObject *pyout = PyFile_FromFile(((!outFd || fileno(outFd) <= 0) ? stdout : outFd),
-				"", "w", 0);
-	PyObject *pyin = PyFile_FromFile(((!inFd || fileno(inFd) <= 0) ? stdin : inFd),
-				"", "r", 0);
-	PyObject *pyerr = PyFile_FromFile(((!errFd || fileno(errFd) <= 0) ? stderr : errFd),
-				"", "w", 0);
+	if (!outFd || fileno(outFd) <= 0)
+		outFd = stdout;
+	if (!inFd || fileno(inFd) <= 0)
+		inFd = stdin;
+	if (!errFd || fileno(errFd) <= 0)
+		errFd = stderr;
+	
+	PyObject *pyout = PyFile_FromFile(outFd, "", "w", 0);
+	PyObject *pyin = PyFile_FromFile(inFd, "", "r", 0);
+	PyObject *pyerr = PyFile_FromFile(errFd, "", "w", 0);
 
 	PyObject *obj = executeFunction("layman.config", "BareConfig", "OOOO", _messageObject(m), pyout, pyin, pyerr);
 	Py_DECREF(pyout);
@@ -50,16 +57,19 @@ void bareConfigFree(BareConfig* cfg)
 		free(cfg);
 }
 
+/*
+ * Returns an option's default value
+ */
 const char* bareConfigGetDefaultValue(BareConfig* cfg, const char* opt)
 {
 	PyObject *obj = PyObject_CallMethod(cfg->object, "get_defaults", NULL);
 	if (!obj)
 		return NULL;
 
-	if (PyDict_Contains(obj, PyBytes_FromString(opt)))
+	if (PyDict_Contains(obj, PyString_FromString(opt)))
 	{
-		PyObject *pyopt = PyBytes_FromString(opt);
-		char *tmp = PyBytes_AsString(PyDict_GetItem(obj, pyopt));
+		PyObject *pyopt = PyString_FromString(opt);
+		char *tmp = PyString_AsString(PyDict_GetItem(obj, pyopt));
 		Py_DECREF(pyopt);
 
 		char *ret = malloc(sizeof(char) * strlen(tmp));
@@ -72,10 +82,13 @@ const char* bareConfigGetDefaultValue(BareConfig* cfg, const char* opt)
 		return "";
 }
 
+/*
+ * Get an option's current value.
+ */
 const char* bareConfigGetOptionValue(BareConfig* cfg, const char* opt)
 {
 	PyObject *obj = PyObject_CallMethod(cfg->object, "get_option", "(z)", opt);
-	char *tmp = PyBytes_AsString(obj);
+	char *tmp = PyString_AsString(obj);
 	char *ret = malloc(sizeof(char) * (strlen(tmp) + 1));
 
 	strcpy(ret, tmp);
@@ -85,6 +98,9 @@ const char* bareConfigGetOptionValue(BareConfig* cfg, const char* opt)
 	return ret;
 }
 
+/*
+ * Modifies an option's value
+ */
 int bareConfigSetOptionValue(BareConfig* cfg, const char* opt, const char* val)
 {
 	PyObject *obj = PyObject_CallMethod(cfg->object, "set_option", "(zz)", opt, val);

diff --git a/src/dbbase.c b/src/dbbase.c
deleted file mode 100644
index fdefac4..0000000
--- a/src/dbbase.c
+++ /dev/null
@@ -1,41 +0,0 @@
-//#include "config.h"
-#include "dbbase.h"
-#include "interpreter.h"
-#include "dict.h"
-#include <Python.h>
-
-struct DbBase
-{
-	PyObject *object;
-};
-
-DbBase* createDbBase(const char *paths[], unsigned int pathCount, Dict *dict, int ignore, int quiet, int ignore_init_read_errors)
-{
-	PyObject *pypaths = PyList_New(pathCount);
-	for (unsigned int i = 0; i < pathCount; i++)
-	{
-		PyObject *path = PyBytes_FromString(paths[i]);
-		PyList_Insert(pypaths, i, path);
-	}
-
-	PyObject *obj = executeFunction("layman.dbbase", "DbBase", "OOIII", pypaths, dictToPyDict(dict), ignore, quiet, ignore_init_read_errors);
-	Py_DECREF(pypaths);
-
-	if (!obj)
-		return NULL;
-
-	DbBase *ret = malloc(sizeof(DbBase));
-	ret->object = obj;
-
-	return ret;
-}
-
-void dbBaseFree(DbBase* db)
-{
-	if (db && db->object)
-	{
-		Py_DECREF(db->object);
-	}
-	if (db)
-		free(db);
-}

diff --git a/src/dbbase.h b/src/dbbase.h
deleted file mode 100644
index bd3786c..0000000
--- a/src/dbbase.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef DB_BASE_H
-#define DB_BASE_H
-
-#include "config.h"
-#include "dict.h"
-
-typedef struct DbBase DbBase;
-
-DbBase* createDbBase(const char *paths[], unsigned int path_count, Dict *c, int ignore, int quiet, int ignore_init_read_errors);
-void dbBaseFree(DbBase*);
-
-#endif

diff --git a/src/interpreter.c b/src/interpreter.c
index 619a157..2430bce 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -89,8 +89,6 @@ struct Interpreter
 	PyObjectList *modules;
 } *in = 0;
 
-//Interpreter *in = 0;
-
 void interpreterInit()
 {
 	if (in)
@@ -145,6 +143,7 @@ PyObject *executeFunction(const char *module, const char *funcName, const char*
 	{
 		mod = moduleNamed(module, in->modules);
 	}
+	// If module is not loaded yet, do it.
 	if (!mod)
 	{
 		mod = PyImport_ImportModule(module);
@@ -153,25 +152,12 @@ PyObject *executeFunction(const char *module, const char *funcName, const char*
 		insert(in->modules, mod);
 	}
 
-	//printf("Using module named %s\n", PyModule_GetName(mod));
-
-	/*printf("mod: %p ", mod);
-	PyObject_Print(mod, stdout, 0);
-	printf("\n");*/
-
 	// Look for the function
 	PyObject *func = PyObject_GetAttrString(mod, funcName);
 	if (!PyCallable_Check(func))
 		return NULL;
 
-	// Call the function
-	/*printf("func: %p\n", func);
-	PyObject_Print(func, stdout, 0);
-	printf("\n");*/
-
-	//PyObject_Print(args, stdout, 0);
-	//printf("\n");
-
+	// Execute it
 	PyObject *val = PyObject_CallObject(func, args);
 
 	if (args != NULL)

diff --git a/src/laymanapi.c b/src/laymanapi.c
index 5de0140..cf4cb1d 100644
--- a/src/laymanapi.c
+++ b/src/laymanapi.c
@@ -2,17 +2,20 @@
 #include "interpreter.h"
 #include "laymanapi.h"
 
-/*
- * FIXME: free memory !!!
- */
-
 struct LaymanAPI
 {
 	PyObject *object;
 };
 
+/*
+ * Creates a LaymanAPI object that must be used in all function in this file.
+ *
+ * The BareConfig argument must not be NULL.
+ */
+
 LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 {
+	assert(NULL != config);
 	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "Oii", _bareConfigObject(config), report_error, output);
 	if (!obj)
 		return NULL;
@@ -23,30 +26,47 @@ LaymanAPI* laymanAPICreate(BareConfig* config, int report_error, int output)
 	return ret;
 }
 
+/*
+ * Returns a list of the available overlays.
+ */
 StringList* laymanAPIGetAvailable(LaymanAPI* l, int reload)
 {
 	if (!l || !l->object)
 		return NULL;
 
 	PyObject *obj = PyObject_CallMethod(l->object, "get_available", "(i)", reload);
+	if (!obj)
+		return NULL;
+
 	StringList *ret = listToCList(obj);
 	Py_DECREF(obj);
 
 	return ret;
 }
 
+/*
+ * Returns a list of the installed overlays.
+ */
 StringList* laymanAPIGetInstalled(LaymanAPI* l, int reload)
 {
 	if (!l || !l->object)
 		return NULL;
 
 	PyObject *obj = PyObject_CallMethod(l->object, "get_installed", "(i)", reload);
+	if (!obj)
+		return NULL;
+
 	StringList* ret = listToCList(obj);
 	Py_DECREF(obj);
 
 	return ret;
 }
 
+/*
+ * Syncs an overlay.
+ * It returns true if it succeeded, false if not.
+ */
+
 int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 {
 	if (!l || !l->object)
@@ -56,46 +76,56 @@ int laymanAPISync(LaymanAPI* l, const char* overlay, int verbose)
 	if (!obj)
 		return 0;
 
-	int ret;
-	if (PyObject_IsTrue(obj))
-		ret = 1;
-	else
-		ret = 0;
+	int ret = PyObject_IsTrue(obj);
+	assert(-1 == ret);
 	
 	Py_DECREF(obj);
 	
-	return ret;
+	return !ret;
 }
 
+/*
+ * Updates the local overlay list.
+ * It returns true if it succeeded, false if not.
+ */
 int laymanAPIFetchRemoteList(LaymanAPI* l)
 {
 	if (!l || !l->object)
 		return 0;
 	
 	PyObject *obj = PyObject_CallMethod(l->object, "fetch_remote_list", NULL);
+	if (!obj)
+		return 0;
 
-	int ret;
-
-	if (!PyObject_IsTrue(obj)) //FIXME : does this work ? It seems to return 1 when false and 0 when true
-		ret = 1;
-	else
-		ret = 0;
+	int ret = PyObject_IsTrue(obj);
+	assert(-1 == ret);
 	
 	Py_DECREF(obj);
 
-	return ret;
+	return !ret;
 }
 
+/*
+ * Gets the information from the overlays given in the StringList overlays.
+ * The results are stored in the results table which must be initialized with N structures,
+ * N being the number of overlays in the overlays StringList.
+ * 
+ * It returns the number of results structures that have been filled.
+ */
 int laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* results)
 {
+	// Check input data.
 	if (!l || !l->object || !overlays || !results)
 		return 0;
 
+	// Convert the StringList to a Python list object.
 	PyObject *list = cListToPyList(overlays);
-	
+
+	// Call the method
 	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
 	Py_DECREF(list);
 
+	// Check if the returned value is a dict as expected.
 	if (!obj || !PyDict_Check(obj))
 	{
 		if (obj)
@@ -110,49 +140,68 @@ int laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* result
 
 	int k = 0;
 
+	// Loop in the dict to get all tuples.
 	while (PyDict_Next(obj, &i, &name, &tuple))
 	{
-		if (!tuple || !PyTuple_Check(tuple))
+		// If it's not a sequence, it's ignored
+		// FIXME:should an assert be used ?
+		if (!tuple || !PySequence_Check(tuple))
 		{
 			Py_DECREF(obj);
 			continue;
 		}
 
-		PyObject *text = PyTuple_GetItem(tuple, 0);
-		PyObject *official = PyTuple_GetItem(tuple, 1);
-		PyObject *supported = PyTuple_GetItem(tuple, 2);
+		PyObject *text = PySequence_GetItem(tuple, 0);
+		PyObject *official = PySequence_GetItem(tuple, 1);
+		PyObject *supported = PySequence_GetItem(tuple, 2);
 
+		// Check if text and name are Strings
 		if (!PyString_Check(text) || !PyString_Check(name))
 			continue;
 
+		// Copy values in the kth structure of the results.
 		char* tmp = PyString_AsString(name);
-		results[k].name = malloc((strlen(tmp) + 1) * sizeof(char));
-		strcpy(results[k].name, tmp);
+		assert(NULL != tmp);
+		results[k].name = strdup(tmp);
 
 		tmp = PyString_AsString(text);
-		results[k].text = malloc((strlen(tmp) + 1) * sizeof(char));
-		strcpy(results[k].text, tmp);
+		assert(NULL != tmp);
+		results[k].text = strdup(tmp);
 
 		results[k].official = PyObject_IsTrue(official);
+		assert(-1 != results[k].official);
 		results[k].supported = PyObject_IsTrue(supported);
+		assert(-1 != results[k].supported);
+
 		k++;
 	}
 
 	Py_DECREF(obj);
+
+	//Return the number of structures that have been filled.
 	return k;
 }
 
+/*
+ * Provided for convenience, this function get the information for only 1 overlay.
+ * Returns NULL if it fails, an OverlayInfo struct if not.
+ */
 OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 {
+	// Check input data.
 	if (!l || !l->object || !overlay)
 		return NULL;
-
+	
+	// Create a list containing the overlay string
 	PyObject *list = PyList_New(1);
 	PyList_SetItem(list, 0, PyString_FromString(overlay));
+	//FIXME:directly call laymanAPIGetInfoList()
 
+	// Call the method
 	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "(O)", list);
 	Py_DECREF(list);
 
+	// Check if the returned value is a dict as expected.
 	if (!obj || !PyDict_Check(obj))
 	{
 		if (obj)
@@ -162,6 +211,7 @@ OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 		return NULL;
 	}
 
+	// Get the tuple corresponding to the overlay and check if it is a tuple.
 	PyObject *tuple = PyDict_GetItemString(obj, overlay);
 
 	if (!tuple || !PyTuple_Check(tuple))
@@ -175,6 +225,7 @@ OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 		return NULL;
 	}
 
+	// Create the structure to return and fill it.
 	PyObject *text = PyTuple_GetItem(tuple, 0);
 	PyObject *official = PyTuple_GetItem(tuple, 1);
 	PyObject *supported = PyTuple_GetItem(tuple, 2);
@@ -182,17 +233,52 @@ OverlayInfo *laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
 	OverlayInfo *oi = malloc(sizeof(OverlayInfo));
 
 	char* tmp = PyString_AsString(text);
-	oi->text = malloc((strlen(tmp) + 1) * sizeof(char));
-	strcpy(oi->text, tmp);
+	assert(NULL != tmp);
+	oi->text = strdup(tmp);
+
+	oi->name = strdup(overlay);
 
 	oi->official = PyObject_IsTrue(official);
+	assert(-1 == oi->official);
 	oi->supported = PyObject_IsTrue(supported);
+	assert(-1 == oi->supported);
 
 	Py_DECREF(obj);
 
 	return oi;
 }
 
+int laymanAPIAddRepo(LaymanAPI* l, StringList *repos)
+{
+	if (!l || !l->object || !repos)
+		return 0;
+
+	PyObject *pyrepos = cListToPyList(repos);
+	PyObject *obj = PyObject_CallMethod(l->object, "add_repo", "(O)", pyrepos);
+	Py_DECREF(pyrepos);
+	if (!obj)
+		return 0;
+
+	return 1;
+}
+
+int laymanAPIDeleteRepo(LaymanAPI* l, StringList *repos)
+{
+	if (!l || !l->object || !repos)
+		return 0;
+
+	PyObject *pyrepos = cListToPyList(repos);
+	PyObject *obj = PyObject_CallMethod(l->object, "delete_repo", "(O)", pyrepos);
+	Py_DECREF(pyrepos);
+	if (!obj)
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Frees a LaymanAPI object from memory
+ */
 void laymanAPIFree(LaymanAPI* l)
 {
 	if (l && l->object)

diff --git a/src/laymanapi.h b/src/laymanapi.h
index 43f99e2..8ef90b3 100644
--- a/src/laymanapi.h
+++ b/src/laymanapi.h
@@ -20,6 +20,8 @@ StringList*	laymanAPIGetInstalled(LaymanAPI*, int reload);
 int		laymanAPISync(LaymanAPI* l, const char* overlay, int verbose);
 int 		laymanAPIFetchRemoteList(LaymanAPI*);
 int		laymanAPIGetInfoList(LaymanAPI* l, StringList* overlays, OverlayInfo* results);
+int		laymanAPIAddRepo(LaymanAPI* l, StringList *repos);
+int		laymanAPIDeleteRepo(LaymanAPI* l, StringList *repos);
 OverlayInfo*	laymanAPIGetInfo(LaymanAPI* l, const char* overlay);
 void		laymanAPIFree(LaymanAPI*);
 

diff --git a/src/message.c b/src/message.c
index 14b211c..181171e 100644
--- a/src/message.c
+++ b/src/message.c
@@ -8,57 +8,37 @@ struct Message
 };
 
 /*
- * TODO: This constructor is too big.
- * 	 Create a little constructor that uses default values
- * 	 and add helper functions to set the values
+ * Creates a Message instance with default values.
+ * To modify those values, use the corresponding functions.
  */
 Message *messageCreate(const char* module,
 			FILE* out,
 			FILE* err,
-			FILE* dbg,
-			int debug_level,
-			int debug_verbosity,
-			int info_level,
-			int warn_level,
-			int col,
-			StringList* mth,
-			StringList* obj,
-			StringList* var)
+			FILE* dbg)
 {
-	PyObject *pyout, *pyerr, *pydbg, *pymth, *pyobj, *pyvar;
+	PyObject *pyout, *pyerr, *pydbg;
 
-	pyout = PyFile_FromFile(((!out || fileno(out) <= 0) ? stdout : out),
-				"", "w", 0);
-	pyerr = PyFile_FromFile(((!err || fileno(err) <= 0) <= 0 ? stderr : err),
-				"", "w", 0);
-	pydbg = PyFile_FromFile(((!dbg || fileno(dbg) <= 0) ? stderr : dbg),
-				"", "w", 0);
+	if (!out || fileno(out) <= 0)
+		out = stdout;
+	if (!err || fileno(err) <= 0)
+		err = stderr;
+	if (!dbg || fileno(dbg) <= 0)
+		dbg = stderr;
 
-	pymth = cListToPyList(mth);
-	pyobj = cListToPyList(obj);
-	pyvar = cListToPyList(var);
+	pyout = PyFile_FromFile(out, "", "w", 0);
+	pyerr = PyFile_FromFile(err, "", "w", 0);
+	pydbg = PyFile_FromFile(dbg, "", "w", 0);
 
 	PyObject *object = executeFunction("layman.debug", "Message",
-					"(sOOOIIIIIOOO)",
+					"(sOOO)",
 					module,
 					pyout,
 					pyerr,
-					pydbg,
-					debug_level,
-					debug_verbosity,
-					info_level,
-					warn_level,
-					col,
-					pymth,
-					pyobj,
-					pyvar);
+					pydbg);
 
 	Py_DECREF(pyout);
 	Py_DECREF(pyerr);
 	Py_DECREF(pydbg);
-	Py_DECREF(pymth);
-	Py_DECREF(pyobj);
-	Py_DECREF(pyvar);
 
 	if (!object)
 		return NULL;
@@ -69,6 +49,168 @@ Message *messageCreate(const char* module,
 	return ret;
 }
 
+int messageSetDebugLevel(Message *m, int debug_level)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_debug_level", "(I)", debug_level);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetDebugVerbosity(Message *m, int debug_verbosity)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_debug_verbosity", "(I)", debug_verbosity);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetInfoLevel(Message *m, int info_level)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_info_level", "(I)", info_level);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetWarnLevel(Message *m, int warn_level)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_warn_level", "(I)", warn_level);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetColorsOn(Message *m)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "color_on", NULL);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetColorsOff(Message *m)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "color_off", NULL);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetDebugMethods(Message *m, const char* mth)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_debug_methods", "(s)", mth);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetDebugClasses(Message *m, const char* cla)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_debug_classes", "(s)", cla);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int messageSetDebugVariables(Message *m, const char* var)
+{
+	if (!m || !m->object)
+		return 0;
+
+	PyObject *obj = PyObject_CallMethod(m->object, "set_debug_variables", "(s)", var);
+	int ret;
+
+	if (obj)
+		ret = 1;
+	else
+		ret = 0;
+
+	Py_DECREF(obj);
+
+	return ret;
+}
+
 void messageFree(Message *m)
 {
 	if (m && m->object)

diff --git a/src/message.h b/src/message.h
index 33399f6..7def442 100644
--- a/src/message.h
+++ b/src/message.h
@@ -9,7 +9,7 @@ typedef struct Message Message;
 /*
  * arguments : module (String), stdout (fd), stderr (fd), stderr (fd), debug_level, debug_verbosity, info_level, warn_level, ?, ?, ?, ?
  */
-Message*	messageCreate(const char*, FILE*, FILE*, FILE*, int, int, int, int, int, StringList*, StringList*, StringList*);
+Message *messageCreate(const char* module, FILE* out, FILE* err, FILE* dbg);
 PyObject*	_messageObject(Message* m);
 void		messageFree(Message *m);
 

diff --git a/src/tester.c b/src/tester.c
index 61497a7..cb9ae4f 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -11,7 +11,7 @@ int main(int argc, char *argv[])
 	int ret = 0;
 	interpreterInit();
 	
-	Message *msg = messageCreate("layman", 0, 0, 0, 4, 2, 4, 4, 1, NULL, NULL, NULL);
+	Message *msg = messageCreate("layman", 0, 0, 0);
 	BareConfig *cfg = bareConfigCreate(msg, 0, 0, 0);
 	/*if (!bareConfigSetOptionValue(cfg, "local_list", "/home/detlev/src/gsoc2010/layman/layman/tests/testfiles/global-overlays.xml"))
 		printf("Error setting config option.\n");



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     69567b830f119ff74706bbdb6f58164201890623
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul  9 10:58:49 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul  9 10:58:49 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=69567b83

Remove the runner
Implement _eq_ and setPriority

---
 src/overlay.c    |   17 +
 src/overlay.h    |   10 +-
 src/pkBackend.py | 1889 ------------------------------------------------------
 src/runner.c     |  132 ----
 src/runner.h     |    6 -
 src/test.py      |   15 -
 6 files changed, 23 insertions(+), 2046 deletions(-)

diff --git a/src/overlay.c b/src/overlay.c
index 74910f9..9b2b2f7 100644
--- a/src/overlay.c
+++ b/src/overlay.c
@@ -142,6 +142,23 @@ const char *overlayToXml(Overlay *o)
 	return PyBytes_AsString(str);
 }
 
+void overlaySetPriority(Overlay *o, int priority)
+{
+	if (!o || !o->object)
+		return;
+
+	PyObject_CallMethod(o->object, "set_priority", "(I)", priority);
+}
+
+int overlaySame(Overlay *o1, Overlay *o2)
+{
+	PyObject *ret = PyObject_RichCompare(o1->object, o2->object, Py_EQ);
+	if (!ret)
+		return 0;
+
+	return PyObject_IsTrue(ret);
+}
+
 void overlayFree(Overlay *o)
 {
 	if (o && o->object)

diff --git a/src/overlay.h b/src/overlay.h
index 2f64bde..d6b96fd 100644
--- a/src/overlay.h
+++ b/src/overlay.h
@@ -1,18 +1,20 @@
 #ifndef OVERLAY_H
 #define OVERLAY_H
 
+//TODO:document me !
+
 typedef struct Overlay Overlay;
 
 Overlay*	createOverlay(const char*, const char*, int, int);
 const char*	overlayName(Overlay*);
 const char*	overlayOwnerEmail(Overlay*);
 const char*	overlayDescription(Overlay*);
-const char*	overlayShortList(Overlay *o);
-const char*	overlayStr(Overlay *o);
-const char*	overlayToXml(Overlay *o);
+const char*	overlayShortList(Overlay*);
+const char*	overlayStr(Overlay*);
+const char*	overlayToXml(Overlay*);
 int 		overlayPriority(Overlay*);
 int 		overlayIsOfficial(Overlay*);
-int		overlayIsSupported(Overlay *o);
+int		overlayIsSupported(Overlay*);
 void		overlayFree(Overlay*);
 
 #endif

diff --git a/src/pkBackend.py b/src/pkBackend.py
deleted file mode 100755
index 3ec1d2d..0000000
--- a/src/pkBackend.py
+++ /dev/null
@@ -1,1889 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# vim:set shiftwidth=4 tabstop=4 expandtab:
-#
-# Copyright (C) 2009 Mounir Lamouri (volkmar) <mounir.lamouri@gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-# packagekit imports
-from packagekit.backend import *
-from packagekit.progress import *
-from packagekit.package import PackagekitPackage
-
-# portage imports
-import portage
-import portage.versions
-import portage.dep
-import _emerge.actions
-import _emerge.stdout_spinner
-import _emerge.create_depgraph_params
-import _emerge.AtomArg
-
-# layman imports
-import layman.db
-import layman.config
-
-# misc imports
-import sys
-import signal
-import re
-from itertools import izip
-
-# NOTES:
-#
-# Package IDs description:
-# CAT/PN;PV;KEYWORD;[REPOSITORY|installed]
-# Last field must be "installed" if installed. Otherwise it's the repo name
-#
-# Naming convention:
-# cpv: category package version, the standard representation of what packagekit
-#   names a package (an ebuild for portage)
-
-# TODO:
-# remove percentage(None) if percentage is used
-# protection against signal when installing/removing
-
-# Map Gentoo categories to the PackageKit group name space
-class PortagePackageGroups(dict):
-    """
-    Portage Package categories group representation
-    """
-    def __init__(self):
-        dict.__init__(self)
-
-        data = {
-            'accessibility': {
-                'name': "Accessibility",
-                'description': "Accessibility applications",
-                'categories': ['app-accessibility'],
-            },
-            'office': {
-                'name': "Office",
-                'description': "Applications used in office environments",
-                'categories': ['app-office', 'app-pda', 'app-mobilephone',
-                    'app-cdr', 'app-antivirus', 'app-laptop', 'mail-',
-                ],
-            },
-            'development': {
-                'name': "Development",
-                'description': "Applications or system libraries",
-                'categories': ['dev-', 'sys-devel'],
-            },
-            'system': {
-                'name': "System",
-                'description': "System applications or libraries",
-                'categories': ['sys-'],
-            },
-            'games': {
-                'name': "Games",
-                'description': "Games, enjoy your spare time",
-                'categories': ['games-'],
-            },
-            'gnome': {
-                'name': "GNOME Desktop",
-                'description': \
-                    "Applications and libraries for the GNOME Desktop",
-                'categories': ['gnome-'],
-            },
-            'kde': {
-                'name': "KDE Desktop",
-                'description': \
-                    "Applications and libraries for the KDE Desktop",
-                'categories': ['kde-'],
-            },
-            'xfce': {
-                'name': "XFCE Desktop",
-                'description': \
-                    "Applications and libraries for the XFCE Desktop",
-                'categories': ['xfce-'],
-            },
-            'lxde': {
-                'name': "LXDE Desktop",
-                'description': \
-                    "Applications and libraries for the LXDE Desktop",
-                'categories': ['lxde-'],
-            },
-            'multimedia': {
-                'name': "Multimedia",
-                'description': \
-                    "Applications and libraries for Multimedia",
-                'categories': ['media-'],
-            },
-            'networking': {
-                'name': "Networking",
-                'description': \
-                    "Applications and libraries for Networking",
-                'categories': ['net-', 'www-'],
-            },
-            'science': {
-                'name': "Science",
-                'description': \
-                    "Scientific applications and libraries",
-                'categories': ['sci-'],
-            },
-            'security': {
-                'name': "Security",
-                'description': \
-                    "Security orientend applications",
-                'categories': ['app-antivirus', 'net-analyzer', 'net-firewall'],
-            },
-            'x11': {
-                'name': "X11",
-                'description': \
-                    "Applications and libraries for X11",
-                'categories': ['x11-'],
-            },
-        }
-
-        self.update(data)
-
-
-class PortageBridge():
-    '''
-    Bridge to portage/emerge settings and variabales to help using them
-    and be sure they are always up-to-date.
-    '''
-
-    def __init__(self):
-        self.settings = None
-        self.trees = None
-        self.mtimedb = None
-        self.vardb = None
-        self.portdb = None
-        self.root_config = None
-
-        self.update()
-
-    def update(self):
-        self.settings, self.trees, self.mtimedb = \
-                _emerge.actions.load_emerge_config()
-        self.vardb = self.trees[self.settings['ROOT']]['vartree'].dbapi
-        self.portdb = self.trees[self.settings['ROOT']]['porttree'].dbapi
-        self.root_config = self.trees[self.settings['ROOT']]['root_config']
-
-        # doing all the changes to settings
-        self.settings.unlock()
-
-        # we don't want interactive ebuilds
-        self.settings["ACCEPT_PROPERTIES"] = "-interactive"
-        self.settings.backup_changes("ACCEPT_PROPERTIES")
-
-        # do not log with mod_echo (cleanly prevent some outputs)
-        def filter_echo(x): return x != 'echo'
-        elogs = self.settings["PORTAGE_ELOG_SYSTEM"].split()
-        elogs = filter(filter_echo, elogs)
-        self.settings["PORTAGE_ELOG_SYSTEM"] = ' '.join(elogs)
-        self.settings.backup_changes("PORTAGE_ELOG_SYSTEM")
-
-        # finally, regenerate settings and lock them again
-        self.settings.regenerate()
-        self.settings.lock()
-
-
-class PackageKitPortageMixin(object):
-
-    def __init__(self):
-        object.__init__(self)
-
-        self.pvar = PortageBridge()
-        # TODO: should be removed when using non-verbose function API
-        # FIXME: avoid using /dev/null, dangerous (ro fs)
-        self._dev_null = open('/dev/null', 'w')
-        # TODO: atm, this stack keep tracks of elog messages
-        self._elog_messages = []
-        self._error_message = ""
-        self._error_phase = ""
-
-    # TODO: should be removed when using non-verbose function API
-    def _block_output(self):
-        sys.stdout = self._dev_null
-        sys.stderr = self._dev_null
-
-    # TODO: should be removed when using non-verbose function API
-    def _unblock_output(self):
-        sys.stdout = sys.__stdout__
-        sys.stderr = sys.__stderr__
-
-    def _is_repo_enabled(self, layman_db, repo_name):
-        if repo_name in layman_db.overlays.keys():
-            return True
-        return False
-
-    def _get_search_list(self, keys_list):
-        '''
-        Get a string composed of keys (separated with spaces).
-        Returns a list of compiled regular expressions.
-        '''
-        search_list = []
-
-        for k in keys_list:
-            # not done entirely by pk-transaction
-            k = re.escape(k)
-            search_list.append(re.compile(k, re.IGNORECASE))
-
-        return search_list
-
-    def _get_portage_categories(self):
-        """
-        Return a list of available Portage categories
-        """
-        return self.pvar.settings.categories
-
-    def _get_portage_category_description(self, category):
-
-        from xml.dom import minidom
-        data = {}
-        portdir = self.pvar.settings['PORTDIR']
-        myfile = os.path.join(portdir, category, "metadata.xml")
-        if os.access(myfile, os.R_OK) and os.path.isfile(myfile):
-            doc = minidom.parse(myfile)
-            longdescs = doc.getElementsByTagName("longdescription")
-            for longdesc in longdescs:
-                data[longdesc.getAttribute("lang").strip()] = \
-                    ' '.join([x.strip() for x in \
-                        longdesc.firstChild.data.strip().split("\n")])
-
-        # Only return in plain English since Portage doesn't support i18n/l10n
-        return data.get('en', "No description")
-
-    def _get_portage_groups(self):
-        """
-        Return an expanded version of PortagePackageGroups
-        """
-        groups = PortagePackageGroups()
-        categories = self._get_portage_categories()
-
-        # expand categories
-        for data in list(groups.values()):
-
-            exp_cats = set()
-            for g_cat in data['categories']:
-                exp_cats.update([x for x in categories if x.startswith(g_cat)])
-            data['categories'] = sorted(exp_cats)
-
-        return groups
-
-    def _get_pk_group(self, cp):
-        """
-        Return PackageKit group belonging to given Portage package.
-        """
-        category = portage.versions.catsplit(cp)[0]
-        group_data = [key for key, data in self._get_portage_groups().items() \
-            if category in data['categories']]
-        try:
-            generic_group_name = group_data.pop(0)
-        except IndexError:
-            return GROUP_UNKNOWN
-
-        return PackageKitPortageBackend.GROUP_MAP[generic_group_name]
-
-    def _get_portage_group(self, pk_group):
-        """
-        Given a PackageKit group identifier, return Portage packages group.
-        """
-        group_map = PackageKitPortageBackend.GROUP_MAP
-        # reverse dict
-        group_map_reverse = dict((y, x) for x, y in group_map.items())
-        return group_map_reverse.get(pk_group, 'unknown')
-
-    def _get_ebuild_settings(self, cpv, metadata):
-        """
-        Return values of given metadata keys for given Portage CPV.
-        """
-        settings = portage.config(clone=self.pvar.settings)
-        settings.setcpv(cpv, mydb=metadata)
-        return settings
-
-    def _is_installed(self, cpv):
-        if self.pvar.vardb.cpv_exists(cpv):
-            return True
-        return False
-
-    def _is_cpv_valid(self, cpv):
-        if self._is_installed(cpv):
-            # actually if is_installed return True that means cpv is in db
-            return True
-        elif self.pvar.portdb.cpv_exists(cpv):
-            return True
-
-        return False
-
-    def _get_real_license_str(self, cpv, metadata):
-        # use conditionals info (w/ USE) in LICENSE and remove ||
-        ebuild_settings = self._get_ebuild_settings(cpv, metadata)
-        license = set(portage.flatten(portage.dep.use_reduce(
-            portage.dep.paren_reduce(metadata["LICENSE"]),
-            uselist=ebuild_settings.get("USE", "").split())))
-        license.discard('||')
-        license = ' '.join(license)
-
-        return license
-
-    def _signal_config_update(self):
-        result = list(portage.util.find_updated_config_files(
-            self.pvar.settings['ROOT'],
-            self.pvar.settings.get('CONFIG_PROTECT', '').split()))
-
-        if result:
-            message = "Some configuration files need updating."
-            message += ";You should use Gentoo's tools to update them (dispatch-conf)"
-            message += ";If you can't do that, ask your system administrator."
-            self.message(MESSAGE_CONFIG_FILES_CHANGED, message)
-
-    def _get_restricted_fetch_files(self, cpv, metadata):
-        '''
-        This function checks files in SRC_URI and look if they are in DESTDIR.
-        Missing files are returned. If there is no issue, None is returned.
-        We don't care about digest but only about existance of files.
-
-        NOTES:
-        - we are assuming the package has RESTRICT='fetch'
-          be sure to call this function only in this case.
-        - we are not using fetch_check because it's not returning missing files
-          so this function is a simplist fetch_check
-        '''
-        missing_files = []
-        ebuild_settings = self._get_ebuild_settings(cpv, metadata)
-
-        files = self.pvar.portdb.getFetchMap(cpv,
-                ebuild_settings['USE'].split())
-
-        for f in files:
-            file_path = os.path.join(ebuild_settings["DISTDIR"], f)
-            if not os.access(file_path, os.F_OK):
-                missing_files.append([file_path, files[f]])
-
-        if len(missing_files) > 0:
-            return missing_files
-
-        return None
-
-    def _check_fetch_restrict(self, packages_list):
-        for p in packages_list:
-            if 'fetch' in p.metadata['RESTRICT']:
-                files = self._get_restricted_fetch_files(p.cpv, p.metadata)
-                if files:
-                    message = "Package %s can't download some files." % p.cpv
-                    message += ";Please, download manually the followonig file(s):"
-                    for x in files:
-                        message += ";- %s then copy it to %s" % (' '.join(x[1]), x[0])
-                    self.error(ERROR_RESTRICTED_DOWNLOAD, message)
-
-    def _elog_listener(self, settings, key, logentries, fulltext):
-        '''
-        This is a listener for elog.
-        It's called each time elog is emitting log messages (at end of process).
-        We are not using settings and fulltext but they are used by other
-        listeners so we have to keep them as arguments.
-        '''
-        message = "Messages for package %s:;" % str(key)
-        error_message = ""
-
-        # building the message
-        for phase in logentries:
-            for entries in logentries[phase]:
-                type = entries[0]
-                messages = entries[1]
-
-                # TODO: portage.elog.filtering is using upper() should we ?
-                if type == 'LOG':
-                    message += ";Information messages:"
-                elif type == 'WARN':
-                    message += ";Warning messages:"
-                elif type == 'QA':
-                    message += ";QA messages:"
-                elif type == 'ERROR':
-                    message += ";Error messages:"
-                    self._error_phase = phase
-                else:
-                    continue
-
-                for msg in messages:
-                    msg = msg.replace('\n', '')
-                    if type == 'ERROR':
-                        error_message += msg + ";"
-                    message += "; " + msg
-
-        # add the message to the stack
-        self._elog_messages.append(message)
-        self._error_message = message
-
-    def _send_merge_error(self, default):
-        # EAPI-2 compliant (at least)
-        # 'other' phase is ignored except this one, every phase should be there
-        if self._error_phase in ("setup", "unpack", "prepare", "configure",
-            "nofetch", "config", "info"):
-            error_type = ERROR_PACKAGE_FAILED_TO_CONFIGURE
-        elif self._error_phase in ("compile", "test"):
-            error_type = ERROR_PACKAGE_FAILED_TO_BUILD
-        elif self._error_phase in ("install", "preinst", "postinst",
-            "package"):
-            error_type = ERROR_PACKAGE_FAILED_TO_INSTALL
-        elif self._error_phase in ("prerm", "postrm"):
-            error_type = ERROR_PACKAGE_FAILED_TO_REMOVE
-        else:
-            error_type = default
-
-        self.error(error_type, self._error_message)
-
-    def _get_file_list(self, cpv):
-        cat, pv = portage.versions.catsplit(cpv)
-        db = portage.dblink(cat, pv, self.pvar.settings['ROOT'],
-                self.pvar.settings, treetype="vartree",
-                vartree=self.pvar.vardb)
-
-        contents = db.getcontents()
-        if not contents:
-            return []
-
-        return db.getcontents().keys()
-
-    def _cmp_cpv(self, cpv1, cpv2):
-        '''
-        returns 1 if cpv1 > cpv2
-        returns 0 if cpv1 = cpv2
-        returns -1 if cpv1 < cpv2
-        '''
-        return portage.versions.pkgcmp(portage.versions.pkgsplit(cpv1),
-            portage.versions.pkgsplit(cpv2))
-
-    def _get_newest_cpv(self, cpv_list, installed):
-        newer = ""
-
-        # get the first cpv following the installed rule
-        for cpv in cpv_list:
-            if self._is_installed(cpv) == installed:
-                newer = cpv
-                break
-
-        if newer == "":
-            return ""
-
-        for cpv in cpv_list:
-            if self._is_installed(cpv) == installed:
-                if self._cmp_cpv(cpv, newer) == 1:
-                    newer = cpv
-
-        return newer
-
-    def _get_metadata(self, cpv, keys, in_dict = False, add_cache_keys = False):
-        '''
-        This function returns required metadata.
-        If in_dict is True, metadata is returned in a dict object.
-        If add_cache_keys is True, cached keys are added to keys in parameter.
-        '''
-        if self._is_installed(cpv):
-            aux_get = self.pvar.vardb.aux_get
-            if add_cache_keys:
-                keys.extend(list(self.pvar.vardb._aux_cache_keys))
-        else:
-            aux_get = self.pvar.portdb.aux_get
-            if add_cache_keys:
-                keys.extend(list(self.pvar.portdb._aux_cache_keys))
-
-        if in_dict:
-            return dict(izip(keys, aux_get(cpv, keys)))
-        else:
-            return aux_get(cpv, keys)
-
-    def _get_size(self, cpv):
-        '''
-        Returns the installed size if the package is installed.
-        Otherwise, the size of files needed to be downloaded.
-        If some required files have been downloaded,
-        only the remaining size will be considered.
-        '''
-        size = 0
-        if self._is_installed(cpv):
-            size = self._get_metadata(cpv, ["SIZE"])[0]
-            if size == '':
-                size = 0
-            else:
-                size = int(size)
-        else:
-            self
-            metadata = self._get_metadata(cpv, ["IUSE", "SLOT"], in_dict=True)
-
-            package = _emerge.Package.Package(
-                    type_name="ebuild",
-                    built=False,
-                    installed=False,
-                    root_config=self.pvar.root_config,
-                    cpv=cpv,
-                    metadata=metadata)
-
-            fetch_file = self.pvar.portdb.getfetchsizes(package[2],
-                    package.use.enabled)
-            for f in fetch_file:
-                size += fetch_file[f]
-
-        return size
-
-    def _get_cpv_slotted(self, cpv_list):
-        cpv_dict = {}
-
-        for cpv in cpv_list:
-            slot = self._get_metadata(cpv, ["SLOT"])[0]
-            if slot not in cpv_dict:
-                cpv_dict[slot] = [cpv]
-            else:
-                cpv_dict[slot].append(cpv)
-
-        return cpv_dict
-
-    def _filter_free(self, cpv_list, fltlist):
-        if not cpv_list:
-            return cpv_list
-
-        def _has_validLicense(cpv):
-            metadata = self._get_metadata(cpv, ["LICENSE", "USE", "SLOT"], True)
-            return not self.pvar.settings._getMissingLicenses(cpv, metadata)
-
-        if FILTER_FREE in fltlist or FILTER_NOT_FREE in fltlist:
-            free_licenses = "@FSF-APPROVED"
-            if FILTER_FREE in fltlist:
-                licenses = "-* " + free_licenses
-            elif FILTER_NOT_FREE in fltlist:
-                licenses = "* -" + free_licenses
-            backup_license = self.pvar.settings["ACCEPT_LICENSE"]
-
-            self.pvar.settings.unlock()
-            self.pvar.settings["ACCEPT_LICENSE"] = licenses
-            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
-            self.pvar.settings.regenerate()
-
-            cpv_list = filter(_has_validLicense, cpv_list)
-
-            self.pvar.settings["ACCEPT_LICENSE"] = backup_license
-            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
-            self.pvar.settings.regenerate()
-            self.pvar.settings.lock()
-
-        return cpv_list
-
-    def _filter_newest(self, cpv_list, fltlist):
-        if len(cpv_list) == 0:
-            return cpv_list
-
-        if FILTER_NEWEST not in fltlist:
-            return cpv_list
-
-        if FILTER_INSTALLED in fltlist:
-            # we have one package per slot, so it's the newest
-            return cpv_list
-
-        cpv_dict = self._get_cpv_slotted(cpv_list)
-
-        # slots are sorted (dict), revert them to have newest slots first
-        slots = cpv_dict.keys()
-        slots.reverse()
-
-        # empty cpv_list, cpv are now in cpv_dict and cpv_list gonna be repop
-        cpv_list = []
-
-        for k in slots:
-            # if not_intalled on, no need to check for newest installed
-            if FILTER_NOT_INSTALLED not in fltlist:
-                newest_installed = self._get_newest_cpv(cpv_dict[k], True)
-                if newest_installed != "":
-                    cpv_list.append(newest_installed)
-            newest_available = self._get_newest_cpv(cpv_dict[k], False)
-            if newest_available != "":
-                cpv_list.append(newest_available)
-
-        return cpv_list
-
-    def _get_all_cp(self, fltlist):
-        # NOTES:
-        # returns a list of cp
-        #
-        # FILTERS:
-        # - installed: ok
-        # - free: ok (should be done with cpv)
-        # - newest: ok (should be finished with cpv)
-        cp_list = []
-
-        if FILTER_INSTALLED in fltlist:
-            cp_list = self.pvar.vardb.cp_all()
-        elif FILTER_NOT_INSTALLED in fltlist:
-            cp_list = self.pvar.portdb.cp_all()
-        else:
-            # need installed packages first
-            cp_list = self.pvar.vardb.cp_all()
-            for cp in self.pvar.portdb.cp_all():
-                if cp not in cp_list:
-                    cp_list.append(cp)
-
-        return cp_list
-
-    def _get_all_cpv(self, cp, fltlist, filter_newest=True):
-        # NOTES:
-        # returns a list of cpv
-        #
-        # FILTERS:
-        # - installed: ok
-        # - free: ok
-        # - newest: ok
-
-        cpv_list = []
-
-        # populate cpv_list taking care of installed filter
-        if FILTER_INSTALLED in fltlist:
-            cpv_list = self.pvar.vardb.match(cp)
-        elif FILTER_NOT_INSTALLED in fltlist:
-            for cpv in self.pvar.portdb.match(cp):
-                if not self._is_installed(cpv):
-                    cpv_list.append(cpv)
-        else:
-            cpv_list = self.pvar.vardb.match(cp)
-            for cpv in self.pvar.portdb.match(cp):
-                if cpv not in cpv_list:
-                    cpv_list.append(cpv)
-
-        # free filter
-        cpv_list = self._filter_free(cpv_list, fltlist)
-
-        # newest filter
-        if filter_newest:
-            cpv_list = self._filter_newest(cpv_list, fltlist)
-
-        return cpv_list
-
-    def _id_to_cpv(self, pkgid):
-        '''
-        Transform the package id (packagekit) to a cpv (portage)
-        '''
-        ret = split_package_id(pkgid)
-
-        if len(ret) < 4:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                    "The package id %s does not contain 4 fields" % pkgid)
-        if '/' not in ret[0]:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                    "The first field of the package id must contain a category")
-
-        # remove slot info from version field
-        version = ret[1].split(':')[0]
-
-        return ret[0] + "-" + version
-
-    def _cpv_to_id(self, cpv):
-        '''
-        Transform the cpv (portage) to a package id (packagekit)
-        '''
-        package, version, rev = portage.versions.pkgsplit(cpv)
-        pkg_keywords, repo, slot = self._get_metadata(cpv,
-                ["KEYWORDS", "repository", "SLOT"])
-
-        pkg_keywords = pkg_keywords.split()
-        sys_keywords = self.pvar.settings["ACCEPT_KEYWORDS"].split()
-        keywords = []
-
-        for x in sys_keywords:
-            if x in pkg_keywords:
-                keywords.append(x)
-
-        # if no keywords, check in package.keywords
-        if not keywords:
-            key_dict = self.pvar.settings.pkeywordsdict.get(
-                    portage.dep.dep_getkey(cpv))
-            if key_dict:
-                for _, keys in key_dict.iteritems():
-                    for x in keys:
-                        keywords.append(x)
-
-        if not keywords:
-            keywords.append("no keywords")
-            self.message(MESSAGE_UNKNOWN,
-                "No keywords have been found for %s" % cpv)
-
-        # don't want to see -r0
-        if rev != "r0":
-            version = version + "-" + rev
-        # add slot info if slot != 0
-        if slot != '0':
-            version = version + ':' + slot
-
-        # if installed, repo should be 'installed', packagekit rule
-        if self._is_installed(cpv):
-            repo = "installed"
-
-        return get_package_id(package, version, ' '.join(keywords), repo)
-
-    def _get_required_packages(self, cpv_input, recursive):
-        '''
-        Get a list of cpv and recursive parameter.
-        Returns the list of packages required for cpv list.
-        '''
-        packages_list = []
-
-        myopts = {}
-        myopts["--selective"] = True
-        myopts["--deep"] = True
-
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "remove")
-        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
-                self.pvar.trees, myopts, myparams, None)
-
-        # TODO: atm, using FILTER_INSTALLED because it's quicker
-        # and we don't want to manage non-installed packages
-        for cp in self._get_all_cp([FILTER_INSTALLED]):
-            for cpv in self._get_all_cpv(cp, [FILTER_INSTALLED]):
-                depgraph._dynamic_config._dep_stack.append(
-                        _emerge.Dependency.Dependency(
-                            atom=portage.dep.Atom('=' + cpv),
-                            root=self.pvar.settings["ROOT"], parent=None))
-
-        if not depgraph._complete_graph():
-            self.error(ERROR_INTERNAL_ERROR, "Error when generating depgraph")
-            return
-
-        def _add_children_to_list(packages_list, node):
-            for n in depgraph._dynamic_config.digraph.parent_nodes(node):
-                if n not in packages_list \
-                        and not isinstance(n, _emerge.SetArg.SetArg):
-                    packages_list.append(n)
-                    _add_children_to_list(packages_list, n)
-
-        for node in depgraph._dynamic_config.digraph.__iter__():
-            if isinstance(node, _emerge.SetArg.SetArg):
-                continue
-            if node.cpv in cpv_input:
-                if recursive:
-                    _add_children_to_list(packages_list, node)
-                else:
-                    for n in \
-                            depgraph._dynamic_config.digraph.parent_nodes(node):
-                        if not isinstance(n, _emerge.SetArg.SetArg):
-                            packages_list.append(n)
-
-        # remove cpv_input that may be added to the list
-        def filter_cpv_input(x): return x.cpv not in cpv_input
-        return filter(filter_cpv_input, packages_list)
-
-
-class PackageKitPortageBackend(PackageKitPortageMixin, PackageKitPortageBase):
-
-    # Portage <-> PackageKit groups map
-    GROUP_MAP = {
-        'accessibility': GROUP_ACCESSIBILITY,
-        'development': GROUP_PROGRAMMING,
-        'games': GROUP_GAMES,
-        'gnome': GROUP_DESKTOP_GNOME,
-        'kde': GROUP_DESKTOP_KDE,
-        'lxde': GROUP_DESKTOP_OTHER,
-        'multimedia': GROUP_MULTIMEDIA,
-        'networking': GROUP_NETWORK,
-        'office': GROUP_OFFICE,
-        'science': GROUP_SCIENCE,
-        'system': GROUP_SYSTEM,
-        'security': GROUP_SECURITY,
-        'x11': GROUP_OTHER,
-        'xfce': GROUP_DESKTOP_XFCE,
-        'unknown': GROUP_UNKNOWN,
-    }
-
-    def __sigquit(self, signum, frame):
-        raise SystemExit(1)
-
-    def __init__(self, args):
-        signal.signal(signal.SIGQUIT, self.__sigquit)
-        PackageKitPortageMixin.__init__(self)
-        PackageKitBaseBackend.__init__(self, args)
-
-    def _package(self, cpv, info=None):
-        desc = self._get_metadata(cpv, ["DESCRIPTION"])[0]
-        if not info:
-            if self._is_installed(cpv):
-                info = INFO_INSTALLED
-            else:
-                info = INFO_AVAILABLE
-        self.package(self._cpv_to_id(cpv), info, desc)
-
-    def get_categories(self):
-
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-
-        categories = self._get_portage_categories()
-        if not categories:
-            self.error(ERROR_GROUP_LIST_INVALID, "no package categories")
-            return
-
-        for name in categories:
-
-            summary = self._get_portage_category_description(name)
-
-            f_name = "/usr/share/pixmaps/portage/%s.png" % (name,)
-            if os.path.isfile(f_name) and os.access(f_name, os.R_OK):
-                icon = name
-            else:
-                icon = "image-missing"
-
-            cat_id = name # same thing
-            self.category("", cat_id, name, summary, icon)
-
-    def get_depends(self, filters, pkgs, recursive):
-        # TODO: use only myparams ?
-        # TODO: improve error management / info
-
-        # FILTERS:
-        # - installed: ok
-        # - free: ok
-        # - newest: ignored because only one version of a package is installed
-
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        fltlist = filters.split(';')
-
-        cpv_input = []
-        cpv_list = []
-
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-            cpv_input.append('=' + cpv)
-
-        myopts = {}
-        myopts["--selective"] = True
-        myopts["--deep"] = True
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        depgraph = _emerge.depgraph.depgraph(
-                self.pvar.settings, self.pvar.trees, myopts, myparams, None)
-        retval, fav = depgraph.select_files(cpv_input)
-
-        if not retval:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Wasn't able to get dependency graph")
-            return
-
-        def _add_children_to_list(cpv_list, node):
-            for n in depgraph._dynamic_config.digraph.child_nodes(node):
-                if n not in cpv_list:
-                    cpv_list.append(n)
-                    _add_children_to_list(cpv_list, n)
-
-        for cpv in cpv_input:
-            for r in depgraph._dynamic_config.digraph.root_nodes():
-                # TODO: remove things with @ as first char
-                # TODO: or refuse SetArgs
-                if not isinstance(r, _emerge.AtomArg.AtomArg):
-                    continue
-                if r.atom == cpv:
-                    if recursive:
-                        _add_children_to_list(cpv_list, r)
-                    else:
-                        for n in \
-                                depgraph._dynamic_config.digraph.child_nodes(r):
-                            for c in \
-                                depgraph._dynamic_config.digraph.child_nodes(n):
-                                cpv_list.append(c)
-
-        def _filter_uninstall(cpv):
-            return cpv[3] != 'uninstall'
-        def _filter_installed(cpv):
-            return cpv[0] == 'installed'
-        def _filter_not_installed(cpv):
-            return cpv[0] != 'installed'
-
-        # removing packages going to be uninstalled
-        cpv_list = filter(_filter_uninstall, cpv_list)
-
-        # install filter
-        if FILTER_INSTALLED in fltlist:
-            cpv_list = filter(_filter_installed, cpv_list)
-        if FILTER_NOT_INSTALLED in fltlist:
-            cpv_list = filter(_filter_not_installed, cpv_list)
-
-        # now we can change cpv_list to a real cpv list
-        tmp_list = cpv_list[:]
-        cpv_list = []
-        for x in tmp_list:
-            cpv_list.append(x[2])
-        del tmp_list
-
-        # free filter
-        cpv_list = self._filter_free(cpv_list, fltlist)
-
-        for cpv in cpv_list:
-            # prevent showing input packages
-            if '=' + cpv not in cpv_input:
-                self._package(cpv)
-
-    def get_details(self, pkgs):
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        nb_pkg = float(len(pkgs))
-        pkg_processed = 0.0
-
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            metadata = self._get_metadata(cpv,
-                    ["DESCRIPTION", "HOMEPAGE", "IUSE", "LICENSE", "SLOT"],
-                    in_dict=True)
-            license = self._get_real_license_str(cpv, metadata)
-
-            self.details(self._cpv_to_id(cpv), license,
-                self._get_pk_group(cpv),
-                metadata["DESCRIPTION"], metadata["HOMEPAGE"],
-                self._get_size(cpv))
-
-            pkg_processed += 100.0
-            self.percentage(int(pkg_processed/nb_pkg))
-
-        self.percentage(100)
-
-    def get_files(self, pkgs):
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        nb_pkg = float(len(pkgs))
-        pkg_processed = 0.0
-
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            if not self._is_installed(cpv):
-                self.error(ERROR_CANNOT_GET_FILELIST,
-                        "get-files is only available for installed packages")
-                continue
-
-            files = self._get_file_list(cpv)
-            files = sorted(files)
-            files = ";".join(files)
-
-            self.files(pkg, files)
-
-            pkg_processed += 100.0
-            self.percentage(int(pkg_processed/nb_pkg))
-
-        self.percentage(100)
-
-    def get_packages(self, filters):
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        fltlist = filters.split(';')
-        cp_list = self._get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
-
-        for cp in self._get_all_cp(fltlist):
-            for cpv in self._get_all_cpv(cp, fltlist):
-                self._package(cpv)
-
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
-
-        self.percentage(100)
-
-    def get_repo_list(self, filters):
-        # NOTES:
-        # use layman API
-        # returns only official and supported repositories
-        # and creates a dummy repo for portage tree
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        fltlist = filters.split(';')
-
-        # get installed and available dbs
-        installed_layman_db = layman.db.DB(layman.config.Config())
-        available_layman_db = layman.db.RemoteDB(layman.config.Config())
-
-        # 'gentoo' is a dummy repo
-        self.repo_detail('gentoo', 'Gentoo Portage tree', True)
-
-        if FILTER_NOT_DEVELOPMENT not in fltlist:
-            for o in available_layman_db.overlays.keys():
-                if available_layman_db.overlays[o].is_official() \
-                        and available_layman_db.overlays[o].is_supported():
-                    self.repo_detail(o, o,
-                            self._is_repo_enabled(installed_layman_db, o))
-
-    def get_requires(self, filters, pkgs, recursive):
-        # TODO: manage non-installed package
-
-        # FILTERS:
-        # - installed: error atm, see previous TODO
-        # - free: ok
-        # - newest: ignored because only one version of a package is installed
-
-        self.status(STATUS_RUNNING)
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        fltlist = filters.split(';')
-
-        cpv_input = []
-        cpv_list = []
-
-        if FILTER_NOT_INSTALLED in fltlist:
-            self.error(ERROR_CANNOT_GET_REQUIRES,
-                    "get-requires returns only installed packages at the moment")
-            return
-
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-            if not self._is_installed(cpv):
-                self.error(ERROR_CANNOT_GET_REQUIRES,
-                        "get-requires is only available for installed packages at the moment")
-                continue
-
-            cpv_input.append(cpv)
-
-        packages_list = self._get_required_packages(cpv_input, recursive)
-
-        # now we can populate cpv_list
-        cpv_list = []
-        for p in packages_list:
-            cpv_list.append(p.cpv)
-        del packages_list
-
-        # free filter
-        cpv_list = self._filter_free(cpv_list, fltlist)
-
-        for cpv in cpv_list:
-            # prevent showing input packages
-            if '=' + cpv not in cpv_input:
-                self._package(cpv)
-
-    def get_update_detail(self, pkgs):
-        # TODO: a lot of informations are missing
-
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        for pkg in pkgs:
-            updates = []
-            obsoletes = ""
-            vendor_url = ""
-            bugzilla_url = ""
-            cve_url = ""
-
-            cpv = self._id_to_cpv(pkg)
-
-            if not self.pvar.portdb.cpv_exists(cpv):
-                self.message(MESSAGE_COULD_NOT_FIND_PACKAGE, "could not find %s" % pkg)
-
-            for cpv in self.pvar.vardb.match(portage.versions.pkgsplit(cpv)[0]):
-                updates.append(cpv)
-            updates = "&".join(updates)
-
-            # temporarily set vendor_url = homepage
-            homepage = self._get_metadata(cpv, ["HOMEPAGE"])[0]
-            vendor_url = homepage
-            issued = ""
-            updated = ""
-
-            self.update_detail(pkg, updates, obsoletes, vendor_url, bugzilla_url,
-                    cve_url, "none", "No update text", "No ChangeLog",
-                    UPDATE_STATE_STABLE, issued, updated)
-
-    def get_updates(self, filters):
-        # NOTES:
-        # because of a lot of things related to Gentoo,
-        # only world and system packages are can be listed as updates
-        # _except_ for security updates
-
-        # UPDATE TYPES:
-        # - blocked: wait for feedbacks
-        # - low: TODO: --newuse
-        # - normal: default
-        # - important: none atm
-        # - security: from @security
-
-        # FILTERS:
-        # - installed: try to update non-installed packages and call me ;)
-        # - free: ok
-        # - newest: ok
-
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        fltlist = filters.split(';')
-
-        update_candidates = []
-        cpv_updates = {}
-        cpv_downgra = {}
-
-        # get system and world packages
-        for s in ["system", "world"]:
-            set = portage.sets.base.InternalPackageSet(
-                    initial_atoms=self.pvar.root_config.setconfig.getSetAtoms(s))
-            for atom in set:
-                update_candidates.append(atom.cp)
-
-        # check if a candidate can be updated
-        for cp in update_candidates:
-            cpv_list_inst = self.pvar.vardb.match(cp)
-            cpv_list_avai = self.pvar.portdb.match(cp)
-
-            cpv_dict_inst = self._get_cpv_slotted(cpv_list_inst)
-            cpv_dict_avai = self._get_cpv_slotted(cpv_list_avai)
-
-            dict_upda = {}
-            dict_down = {}
-
-            # candidate slots are installed slots
-            slots = cpv_dict_inst.keys()
-            slots.reverse()
-
-            for s in slots:
-                cpv_list_updates = []
-                cpv_inst = cpv_dict_inst[s][0] # only one install per slot
-
-                # the slot can be outdated (not in the tree)
-                if s not in cpv_dict_avai:
-                    break
-
-                tmp_list_avai = cpv_dict_avai[s]
-                tmp_list_avai.reverse()
-
-                for cpv in tmp_list_avai:
-                    if self._cmp_cpv(cpv_inst, cpv) == -1:
-                        cpv_list_updates.append(cpv)
-                    else: # because the list is sorted
-                        break
-
-                # no update for this slot
-                if len(cpv_list_updates) == 0:
-                    if [cpv_inst] == self.pvar.portdb.visible([cpv_inst]):
-                        break # really no update
-                    else:
-                        # that's actually a downgrade or even worst
-                        if len(tmp_list_avai) == 0:
-                            break # this package is not known in the tree...
-                        else:
-                            dict_down[s] = [tmp_list_avai.pop()]
-
-                cpv_list_updates = self._filter_free(cpv_list_updates, fltlist)
-
-                if len(cpv_list_updates) == 0:
-                    break
-
-                if FILTER_NEWEST in fltlist:
-                    best_cpv = portage.versions.best(cpv_list_updates)
-                    cpv_list_updates = [best_cpv]
-
-                dict_upda[s] = cpv_list_updates
-
-            if len(dict_upda) != 0:
-                cpv_updates[cp] = dict_upda
-            if len(dict_down) != 0:
-                cpv_downgra[cp] = dict_down
-
-        # get security updates
-        for atom in portage.sets.base.InternalPackageSet(
-                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("security")):
-            # send update message and remove atom from cpv_updates
-            if atom.cp in cpv_updates:
-                slot = self._get_metadata(atom.cpv, ["SLOT"])[0]
-                if slot in cpv_updates[atom.cp]:
-                    tmp_cpv_list = cpv_updates[atom.cp][slot][:]
-                    for cpv in tmp_cpv_list:
-                        if self._cmp_cpv(cpv, atom.cpv) >= 0:
-                            # cpv is a security update and removed from list
-                            cpv_updates[atom.cp][slot].remove(cpv)
-                            self._package(cpv, INFO_SECURITY)
-            else: # update also non-world and non-system packages if security
-                self._package(atom.cpv, INFO_SECURITY)
-
-        # downgrades
-        for cp in cpv_downgra:
-            for slot in cpv_downgra[cp]:
-                for cpv in cpv_downgra[cp][slot]:
-                    self._package(cpv, INFO_IMPORTANT)
-
-        # normal updates
-        for cp in cpv_updates:
-            for slot in cpv_updates[cp]:
-                for cpv in cpv_updates[cp][slot]:
-                    self._package(cpv, INFO_NORMAL)
-
-    def simulate_install_packages(self, pkgs):
-        return self._install_packages(False, pkgs, simulate=True)
-
-    def install_packages(self, only_trusted, pkgs):
-        return self._install_packages(False, pkgs)
-
-    def _install_packages(self, only_trusted, pkgs, simulate=False):
-        # NOTES:
-        # can't install an already installed packages
-        # even if it happens to be needed in Gentoo but probably not this API
-        # TODO: every merged pkg should emit self.package()
-        #       see around _emerge.Scheduler.Scheduler
-
-        self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
-        self.percentage(None)
-
-        cpv_list = []
-
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            if self._is_installed(cpv):
-                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                        "Package %s is already installed" % pkg)
-                continue
-
-            cpv_list.append('=' + cpv)
-
-        # only_trusted isn't supported
-        # but better to show it after important errors
-        if only_trusted:
-            self.error(ERROR_MISSING_GPG_SIGNATURE,
-                    "Portage backend does not support GPG signature")
-            return
-
-        # creating installation depgraph
-        myopts = {}
-        favorites = []
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        self.status(STATUS_DEP_RESOLVE)
-
-        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
-                self.pvar.trees, myopts, myparams, None)
-        retval, favorites = depgraph.select_files(cpv_list)
-        if not retval:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Wasn't able to get dependency graph")
-            return
-
-        # check fetch restrict, can stop the function via error signal
-        self._check_fetch_restrict(depgraph.altlist())
-
-        self.status(STATUS_INSTALL)
-
-        if simulate:
-            return
-
-        # get elog messages
-        portage.elog.add_listener(self._elog_listener)
-
-        try:
-            self._block_output()
-            # compiling/installing
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
-                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
-            rval = mergetask.merge()
-        finally:
-            self._unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self._elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-        self._signal_config_update()
-
-    def refresh_cache(self, force):
-        # NOTES: can't manage progress even if it could be better
-        # TODO: do not wait for exception, check timestamp
-        # TODO: message if overlay repo has changed (layman)
-        self.status(STATUS_REFRESH_CACHE)
-        self.allow_cancel(False)
-        self.percentage(None)
-
-        myopts = {'--quiet': True}
-
-        # get installed and available dbs
-        installed_layman_db = layman.db.DB(layman.config.Config())
-
-        if force:
-            timestamp_path = os.path.join(
-                    self.pvar.settings["PORTDIR"], "metadata", "timestamp.chk")
-            if os.access(timestamp_path, os.F_OK):
-                os.remove(timestamp_path)
-
-        try:
-            self._block_output()
-            for o in installed_layman_db.overlays.keys():
-                installed_layman_db.sync(o, quiet=True)
-            _emerge.actions.action_sync(self.pvar.settings, self.pvar.trees,
-                    self.pvar.mtimedb, myopts, "")
-        except:
-            self.error(ERROR_INTERNAL_ERROR, traceback.format_exc())
-        finally:
-            self._unblock_output()
-
-    def remove_packages(self, allowdep, autoremove, pkgs):
-        return self._remove_packages(allowdep, autoremove, pkgs)
-
-    def simulate_remove_packages(self, pkgs):
-        return self._remove_packages(True, False, pkgs, simulate=True)
-
-    def _remove_packages(self, allowdep, autoremove, pkgs, simulate=False):
-        # TODO: every to-be-removed pkg should emit self.package()
-        #       see around _emerge.Scheduler.Scheduler
-        self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
-        self.percentage(None)
-
-        cpv_list = []
-        packages = []
-        required_packages = []
-        system_packages = []
-
-        # get system packages
-        set = portage.sets.base.InternalPackageSet(
-                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("system"))
-        for atom in set:
-            system_packages.append(atom.cp)
-
-        # create cpv_list
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            if not self._is_installed(cpv):
-                self.error(ERROR_PACKAGE_NOT_INSTALLED,
-                        "Package %s is not installed" % pkg)
-                continue
-
-            # stop removal if a package is in the system set
-            if portage.versions.pkgsplit(cpv)[0] in system_packages:
-                self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
-                        "Package %s is a system package. If you really want to remove it, please use portage" % pkg)
-                continue
-
-            cpv_list.append(cpv)
-
-        # backend do not implement autoremove
-        if autoremove:
-            self.message(MESSAGE_AUTOREMOVE_IGNORED,
-                    "Portage backend do not implement autoremove option")
-
-        # get packages needing candidates for removal
-        required_packages = self._get_required_packages(cpv_list, recursive=True)
-
-        # if there are required packages, allowdep must be on
-        if required_packages and not allowdep:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Could not perform remove operation has packages are needed by other packages")
-            return
-
-        # first, we add required packages
-        for p in required_packages:
-            package = _emerge.Package.Package(
-                    type_name=p.type_name,
-                    built=p.built,
-                    installed=p.installed,
-                    root_config=p.root_config,
-                    cpv=p.cpv,
-                    metadata=p.metadata,
-                    operation='uninstall')
-            packages.append(package)
-
-        # and now, packages we want really to remove
-        for cpv in cpv_list:
-            metadata = self._get_metadata(cpv, [],
-                    in_dict=True, add_cache_keys=True)
-            package = _emerge.Package.Package(
-                    type_name="ebuild",
-                    built=True,
-                    installed=True,
-                    root_config=self.pvar.root_config,
-                    cpv=cpv,
-                    metadata=metadata,
-                    operation="uninstall")
-            packages.append(package)
-
-        if simulate:
-            return
-
-        # need to define favorites to remove packages from world set
-        favorites = []
-        for p in packages:
-            favorites.append('=' + p.cpv)
-
-        # get elog messages
-        portage.elog.add_listener(self._elog_listener)
-
-        # now, we can remove
-        try:
-            self._block_output()
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, mergelist=packages,
-                    myopts={}, spinner=None, favorites=favorites, digraph=None)
-            rval = mergetask.merge()
-        finally:
-            self._unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_REMOVE)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self._elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-    def repo_enable(self, repoid, enable):
-        # NOTES: use layman API >= 1.2.3
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        # special case: trying to work with gentoo repo
-        if repoid == 'gentoo':
-            if not enable:
-                self.error(ERROR_CANNOT_DISABLE_REPOSITORY,
-                        "gentoo repository can't be disabled")
-            return
-
-        # get installed and available dbs
-        installed_layman_db = layman.db.DB(layman.config.Config())
-        available_layman_db = layman.db.RemoteDB(layman.config.Config())
-
-        # check now for repoid so we don't have to do it after
-        if not repoid in available_layman_db.overlays.keys():
-            self.error(ERROR_REPO_NOT_FOUND,
-                    "Repository %s was not found" % repoid)
-            return
-
-        # disabling (removing) a db
-        # if repository already disabled, ignoring
-        if not enable and self._is_repo_enabled(installed_layman_db, repoid):
-            try:
-                installed_layman_db.delete(installed_layman_db.select(repoid))
-            except Exception, e:
-                self.error(ERROR_INTERNAL_ERROR,
-                        "Failed to disable repository "+repoid+" : "+str(e))
-                return
-
-        # enabling (adding) a db
-        # if repository already enabled, ignoring
-        if enable and not self._is_repo_enabled(installed_layman_db, repoid):
-            try:
-                # TODO: clean the trick to prevent outputs from layman
-                self._block_output()
-                installed_layman_db.add(available_layman_db.select(repoid),
-                        quiet=True)
-                self._unblock_output()
-            except Exception, e:
-                self._unblock_output()
-                self.error(ERROR_INTERNAL_ERROR,
-                        "Failed to enable repository "+repoid+" : "+str(e))
-                return
-
-    def resolve(self, filters, pkgs):
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        fltlist = filters.split(';')
-        cp_list = self._get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
-
-        reg_expr = []
-        for pkg in pkgs:
-            reg_expr.append("^" + re.escape(pkg) + "$")
-        reg_expr = "|".join(reg_expr)
-
-        # specifications says "be case sensitive"
-        s = re.compile(reg_expr)
-
-        for cp in cp_list:
-            if s.match(cp):
-                for cpv in self._get_all_cpv(cp, fltlist):
-                    self._package(cpv)
-
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
-
-        self.percentage(100)
-
-    def search_details(self, filters, keys):
-        # NOTES: very bad performance
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        fltlist = filters.split(';')
-        cp_list = self._get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
-        search_list = self._get_search_list(keys)
-
-        for cp in cp_list:
-            # unfortunatelly, everything is related to cpv, not cp
-            # can't filter cp
-            cpv_list = []
-
-            # newest filter can't be executed now
-            # because some cpv are going to be filtered by search conditions
-            # and newest filter could be alterated
-            for cpv in self._get_all_cpv(cp, fltlist, filter_newest=False):
-                match = True
-                metadata =  self._get_metadata(cpv,
-                        ["DESCRIPTION", "HOMEPAGE", "IUSE",
-                            "LICENSE", "repository", "SLOT"],
-                        in_dict=True)
-                # update LICENSE to correspond to system settings
-                metadata["LICENSE"] = self._get_real_license_str(cpv, metadata)
-                for s in search_list:
-                    found = False
-                    for x in metadata:
-                        if s.search(metadata[x]):
-                            found = True
-                            break
-                    if not found:
-                        match = False
-                        break
-                if match:
-                    cpv_list.append(cpv)
-
-            # newest filter
-            cpv_list = self._filter_newest(cpv_list, fltlist)
-
-            for cpv in cpv_list:
-                self._package(cpv)
-
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
-
-        self.percentage(100)
-
-    def search_file(self, filters, key):
-        # FILTERS:
-        # - ~installed is not accepted (error)
-        # - free: ok
-        # - newest: as only installed, by himself
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        fltlist = filters.split(';')
-
-        if FILTER_NOT_INSTALLED in fltlist:
-            self.error(ERROR_CANNOT_GET_FILELIST,
-                    "search-file isn't available with ~installed filter")
-            return
-
-        cpv_list = self.pvar.vardb.cpv_all()
-        nb_cpv = 0.0
-        cpv_processed = 0.0
-        is_full_path = True
-
-        if key[0] != "/":
-            is_full_path = False
-            key = re.escape(key)
-            searchre = re.compile("/" + key + "$", re.IGNORECASE)
-
-        # free filter
-        cpv_list = self._filter_free(cpv_list, fltlist)
-        nb_cpv = float(len(cpv_list))
-
-        for cpv in cpv_list:
-            for f in self._get_file_list(cpv):
-                if (is_full_path and key == f) \
-                or (not is_full_path and searchre.search(f)):
-                    self._package(cpv)
-                    break
-
-            cpv_processed += 100.0
-            self.percentage(int(cpv_processed/nb_cpv))
-
-        self.percentage(100)
-
-    def search_group(self, filters, groups):
-        # TODO: filter unknown groups before searching ? (optimization)
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        fltlist = filters.split(';')
-        cp_list = self._get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
-
-        for cp in cp_list:
-            for group in groups:
-                if self._get_pk_group(cp) == group:
-                    for cpv in self._get_all_cpv(cp, fltlist):
-                        self._package(cpv)
-
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
-
-        self.percentage(100)
-
-    def search_name(self, filters, keys_list):
-        # searching for all keys in package name
-        # also filtering by categories if categery is specified in a key
-        # keys contain more than one category name, no results can be found
-        self.status(STATUS_QUERY)
-        self.allow_cancel(True)
-        self.percentage(0)
-
-        categories = []
-        for k in keys_list[:]:
-            if "/" in k:
-                cat, cp = portage.versions.catsplit(k)
-                categories.append(cat)
-                keys_list[keys_list.index(k)] = cp
-
-        category_filter = None
-        if len(categories) > 1:
-            # nothing will be found because we have two cat/pkg
-            # with a AND operator search
-            return
-        elif len(categories) == 1:
-            category_filter = categories[0]
-
-        # do not use self._get_search_list because of this category feature
-        search_list = []
-        for k in keys_list:
-            # not done entirely by pk-transaction
-            k = re.escape(k)
-            search_list.append(re.compile(k, re.IGNORECASE))
-
-        fltlist = filters.split(';')
-        cp_list = self._get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
-
-        for cp in cp_list:
-            if category_filter:
-                cat, pkg_name = portage.versions.catsplit(cp)
-                if cat != category_filter:
-                    continue
-            else:
-                pkg_name = portage.versions.catsplit(cp)[1]
-            found = True
-
-            # pkg name has to correspond to _every_ keys
-            for s in search_list:
-                if not s.search(pkg_name):
-                    found = False
-                    break
-            if found:
-                for cpv in self._get_all_cpv(cp, fltlist):
-                    self._package(cpv)
-
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
-
-        self.percentage(100)
-
-    def update_packages(self, only_trusted, pkgs):
-        return self._update_packages(only_trusted, pkgs)
-
-    def simulate_update_packages(self, pkgs):
-        return self._update_packages(False, pkgs, simulate=True)
-
-    def _update_packages(self, only_trusted, pkgs, simulate=False):
-        # TODO: manage errors
-        # TODO: manage config file updates
-        # TODO: every updated pkg should emit self.package()
-        #       see around _emerge.Scheduler.Scheduler
-
-        self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
-        self.percentage(None)
-
-        cpv_list = []
-
-        for pkg in pkgs:
-            cpv = self._id_to_cpv(pkg)
-
-            if not self._is_cpv_valid(cpv):
-                self.error(ERROR_UPDATE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            cpv_list.append('=' + cpv)
-
-        # only_trusted isn't supported
-        # but better to show it after important errors
-        if only_trusted:
-            self.error(ERROR_MISSING_GPG_SIGNATURE,
-                    "Portage backend does not support GPG signature")
-            return
-
-        # creating update depgraph
-        myopts = {}
-        favorites = []
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        self.status(STATUS_DEP_RESOLVE)
-
-        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
-                self.pvar.trees, myopts, myparams, None)
-        retval, favorites = depgraph.select_files(cpv_list)
-        if not retval:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Wasn't able to get dependency graph")
-            return
-
-        # check fetch restrict, can stop the function via error signal
-        self._check_fetch_restrict(depgraph.altlist())
-
-        self.status(STATUS_INSTALL)
-
-        if simulate:
-            return
-
-        # get elog messages
-        portage.elog.add_listener(self._elog_listener)
-
-        try:
-            self._block_output()
-            # compiling/installing
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
-                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
-            rval = mergetask.merge()
-        finally:
-            self._unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self._elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-        self._signal_config_update()
-
-    def update_system(self, only_trusted):
-        self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
-        self.percentage(None)
-
-        if only_trusted:
-            self.error(ERROR_MISSING_GPG_SIGNATURE,
-                    "Portage backend does not support GPG signature")
-            return
-
-        myopts = {}
-        myopts["--deep"] = True
-        myopts["--newuse"] = True
-        myopts["--update"] = True
-
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        self.status(STATUS_DEP_RESOLVE)
-
-        # creating list of ebuilds needed for the system update
-        # using backtrack_depgraph to prevent errors
-        retval, depgraph, _ = _emerge.depgraph.backtrack_depgraph(
-                self.pvar.settings, self.pvar.trees, myopts, myparams, "",
-                ["@system", "@world"], None)
-        if not retval:
-            self.error(ERROR_INTERNAL_ERROR,
-                    "Wasn't able to get dependency graph")
-            return
-
-        # check fetch restrict, can stop the function via error signal
-        self._check_fetch_restrict(depgraph.altlist())
-
-        self.status(STATUS_INSTALL)
-
-        # get elog messages
-        portage.elog.add_listener(self._elog_listener)
-
-        try:
-            self._block_output()
-            # compiling/installing
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
-                    depgraph.altlist(), None, depgraph.schedulerGraph())
-            rval = mergetask.merge()
-        finally:
-            self._unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self._elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-        self._signal_config_update()
-
-def main():
-    backend = PackageKitPortageBackend("")
-    backend.dispatcher(sys.argv[1:])
-
-if __name__ == "__main__":
-    main()

diff --git a/src/runner.c b/src/runner.c
deleted file mode 100644
index 61c342a..0000000
--- a/src/runner.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Compile command :
- * gcc -o runner -W -Wall -g --std=c99 runner.c
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include "runner.h"
-
-void stdoutWritten(char*);
-
-struct Runner {
-	void *writeStdout;
-};
-
-int main(int argc, char* argv[])
-{
-	// Tries to compare 2 packages version.
-	/*if (argc < 3)
-	{
-		printf("Please provide 2 packages.\n");
-		return -1;
-	}
-
-	char *str = malloc((strlen(argv[1]) + strlen(argv[2]) + 2) * sizeof(char));
-
-	sprintf(str, "%s %s", argv[1], argv[2]);
-	*/
-	Runner *r = createRunner();
-	r->writeStdout = stdoutWritten;
-	int ret = execute(r, "");
-	
-	if (ret < 0)
-		printf("Execution error\n");
-	
-	freeRunner(r);
-
-	return 0;
-}
-
-void stdoutWritten(char *data)
-{
-	printf("From program : %s\n", data);
-}
-
-Runner *createRunner()
-{
-	Runner *ret = malloc(sizeof(Runner));
-	return ret;
-}
-
-int execute(Runner *r, char *args)
-{
-	r = r;
-	int ret = fork();
-	if (ret > 0)
-	{
-		printf("New PID = %d\n", ret);
-		// Listening socket
-		int fd = socket(AF_INET, SOCK_STREAM, 0);
-		if (fd < 0) 
-			printf("ERROR opening socket\n");
-
-		struct sockaddr_in serv_addr;
-
-		memset(&serv_addr, 0, sizeof(serv_addr));
-	
-		int portno = 5555;
-		serv_addr.sin_family = AF_INET;
-		serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-		serv_addr.sin_port = htons(portno);
-	
-		if ((ret = bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0) 
-		{
-			printf("ERROR on binding : %d, %d (%s)\n", ret, errno, strerror(errno));
-			return ret;
-		}
-	
-		if ((ret = listen(fd, 5)) < 0)
-			printf("ERROR on listening : %d, %d (%s)\n", ret, errno, strerror(errno));
-
-		while(1)
-		{
-			unsigned int clilen = sizeof(serv_addr);
-			int newfd = accept(fd, (struct sockaddr *) &serv_addr, &clilen);
-
-			char buf[256];
-			int n = read(newfd, buf, 255);
-			buf[n] = '\0';
-			printf("received : %s\n", buf);
-		}
-
-		return ret;
-	}
-	
-	int fd = socket(AF_INET, SOCK_STREAM, 0);
-	if (fd < 0) 
-		printf("ERROR opening socket\n");
-	
-	struct sockaddr_in serv_addr;
-
-	memset(&serv_addr, 0, sizeof(serv_addr));
-	
-	int portno = 5555;
-	serv_addr.sin_family = AF_INET;
-	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-	serv_addr.sin_port = htons(portno);
-	
-	if ((ret = connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0) 
-	{
-		printf("ERROR on connecting : %d, %d (%s)\n", ret, errno, strerror(errno));
-		return ret;
-	}
-	
-	dup2(fd, STDOUT_FILENO);
-	ret = execl("./test.py", "test.py", "app-portage/kuroo4-4.2", "app-portage/kuroo4-4.3", NULL);
-	printf("execl: (%d) %s\n", errno, strerror(errno));
-	return ret;
-}
-
-void freeRunner(Runner *r)
-{
-	free(r);
-}

diff --git a/src/runner.h b/src/runner.h
deleted file mode 100644
index c087895..0000000
--- a/src/runner.h
+++ /dev/null
@@ -1,6 +0,0 @@
-
-typedef struct Runner Runner;
-
-Runner *createRunner();
-int execute(Runner*, char*);
-void freeRunner(Runner*);

diff --git a/src/test.py b/src/test.py
deleted file mode 100755
index fadcbdf..0000000
--- a/src/test.py
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python
-# !!!! WARNING !!!!
-# Test file : It's not safe, can break your system and make your life miserable, you've been warned.
-# !!!! WARNING !!!!
-
-from portage import *
-
-ret = pkgcmp(pkgsplit(sys.argv[1]), pkgsplit(sys.argv[2]))
-
-if ret == 0 :
-	print "same"
-elif ret == -1:
-	print "less"
-else:
-	print "more"



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     4e75e7f79601122313e83c4e8d22492492e970e2
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul  9 10:41:42 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul  9 10:41:42 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=4e75e7f7

Add some methods to Overlay, fix some warnings

---
 src/interpreter.c |    4 ++++
 src/overlay.c     |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/overlay.h     |    6 +++++-
 src/tester.c      |    4 ++++
 4 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
index e68f1a2..619a157 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -69,7 +69,9 @@ void freeList(PyObjectList *list, int deref)
 		PyObjectListElem *tmp = node;
 		node = node->next;
 		if (deref)
+		{
 			Py_DECREF(tmp->object);
+		}
 		free(tmp);
 	}
 
@@ -173,7 +175,9 @@ PyObject *executeFunction(const char *module, const char *funcName, const char*
 	PyObject *val = PyObject_CallObject(func, args);
 
 	if (args != NULL)
+	{
 		Py_DECREF(args);
+	}
 
 	return val;
 }

diff --git a/src/overlay.c b/src/overlay.c
index 79fee08..74910f9 100644
--- a/src/overlay.c
+++ b/src/overlay.c
@@ -93,10 +93,61 @@ int overlayIsOfficial(Overlay *o)
 	return (int) PyLong_AsLong(iso);
 }
 
+int overlayIsSupported(Overlay *o)
+{
+	if (!o || !o->object)
+		return -1;
+
+	PyObject *iss = PyObject_CallMethod(o->object, "is_supported", NULL);
+
+	//TODO:Py_DECREF me !
+
+	return (int) PyLong_AsLong(iss);
+}
+
+const char *overlayShortList(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *sl = PyObject_CallMethod(o->object, "short_list", NULL);
+
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(sl);
+}
+
+const char *overlayStr(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *str = PyObject_CallMethod(o->object, "str", NULL);
+
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(str);
+}
+
+const char *overlayToXml(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *element = PyObject_CallMethod(o->object, "to_xml", NULL);
+	PyObject *str = executeFunction("xml.etree.ElementTree", "tostring", "(O)", element);
+
+	Py_DECREF(element);
+
+	return PyBytes_AsString(str);
+}
+
 void overlayFree(Overlay *o)
 {
 	if (o && o->object)
+	{
 		Py_DECREF(o->object);
+	}
 	if (o)
 		free(o);
 }

diff --git a/src/overlay.h b/src/overlay.h
index 9125de0..2f64bde 100644
--- a/src/overlay.h
+++ b/src/overlay.h
@@ -6,9 +6,13 @@ typedef struct Overlay Overlay;
 Overlay*	createOverlay(const char*, const char*, int, int);
 const char*	overlayName(Overlay*);
 const char*	overlayOwnerEmail(Overlay*);
-int 		overlayPriority(Overlay*);
 const char*	overlayDescription(Overlay*);
+const char*	overlayShortList(Overlay *o);
+const char*	overlayStr(Overlay *o);
+const char*	overlayToXml(Overlay *o);
+int 		overlayPriority(Overlay*);
 int 		overlayIsOfficial(Overlay*);
+int		overlayIsSupported(Overlay *o);
 void		overlayFree(Overlay*);
 
 #endif

diff --git a/src/tester.c b/src/tester.c
index 53e4776..40be2ff 100644
--- a/src/tester.c
+++ b/src/tester.c
@@ -3,6 +3,8 @@
 
 int main(int argc, char *argv[])
 {
+	argc = argc;
+	argv = argv;
 	interpreterInit();
 	
 	Overlay *o = createOverlay("<overlay type='svn' src='https://overlays.gentoo.org/svn/dev/wrobel' contact='nobody@gentoo.org' name='wrobel' status='official' priorit='10'><description>Test</description></overlay>", "", 1, 0);
@@ -15,6 +17,8 @@ int main(int argc, char *argv[])
 	
 	printf("Overlay name = %s, owner email : %s, description : %s, priority : %d, it is %sofficial.\n", overlayName(o), overlayOwnerEmail(o), overlayDescription(o), overlayPriority(o), overlayIsOfficial(o) ? "" : "not ");
 
+	printf("xml is %s\n", overlayToXml(o));
+
 	interpreterFinalize();
 
 	return 0;



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     74ee4280886f8adc28b16404c469f63f6aa83e55
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Sat Jul 10 16:09:17 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Sat Jul 10 16:09:17 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=74ee4280

Add LayamnAPI, Message, Config, StringList, update Config.

---
 src/laymanapi.c  |  115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/laymanapi.h  |   47 ++++++++++++++++++++++
 src/message.c    |   71 +++++++++++++++++++++++++++++++++
 src/message.h    |   15 +++++++
 src/stringlist.c |   59 +++++++++++++++++++++++++++
 src/stringlist.h |   12 ++++++
 6 files changed, 319 insertions(+), 0 deletions(-)

diff --git a/src/laymanapi.c b/src/laymanapi.c
new file mode 100644
index 0000000..ae4b2eb
--- /dev/null
+++ b/src/laymanapi.c
@@ -0,0 +1,115 @@
+#include <Python.h>
+#include "interpreter.h"
+#include "laymanapi.h"
+
+struct LaymanAPI
+{
+	PyObject *object;
+};
+
+OverlayInfo strToInfo(const char* str)
+{
+	OverlayInfo ret;
+	return ret;
+}
+
+LaymanAPI* laymanAPICreate(Config* config, int report_error, int output)
+{
+	PyObject *obj = executeFunction("layman.api", "LaymanAPI", "OII", _configObject(config), report_error, output);
+	if (!obj)
+		return NULL;
+
+	LaymanAPI *ret = malloc(sizeof(LaymanAPI));
+	ret->object = obj;
+
+	return ret;
+}
+
+StringList* laymanAPIGetAvailable(LaymanAPI* l)
+{
+	if (!l || !l->object)
+		return NULL;
+
+	PyObject *obj = PyObject_CallMethod(l->object, "get_available", NULL);
+	StringList* ret = listToCList(obj);
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+StringList* laymanAPIGetInstalled(LaymanAPI* l)
+{
+	if (!l || !l->object)
+		return NULL;
+
+	PyObject *obj = PyObject_CallMethod(l->object, "get_installed", NULL);
+	StringList* ret = listToCList(obj);
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+int laymanAPISync(LaymanAPI* l, const char* overlay)
+{
+	if (!l || !l->object)
+		return EXIT_FAILURE;
+
+	PyObject *list = PyList_New(1);
+	PyList_Insert(list, 0, PyBytes_FromString(overlay));
+
+	PyObject *obj = PyObject_CallMethod(l->object, "sync", "O", list);
+	Py_DECREF(list);
+
+	if (!obj)
+		return EXIT_FAILURE;
+
+	PyObject *success = PyList_GetItem(obj, 1);
+	if (success == Py_None)
+		return EXIT_FAILURE;
+	
+	return EXIT_SUCCESS;
+}
+
+int laymanAPIFetchRemoteList(LaymanAPI* l)
+{
+	if (!l || !l->object)
+		return EXIT_FAILURE;
+	
+	PyObject *obj = PyObject_CallMethod(l->object, "fetch_remote_list", NULL);
+
+	int ret;
+
+	if (PyObject_IsTrue(obj))
+		ret = EXIT_SUCCESS;
+	else
+		ret = EXIT_FAILURE;
+	
+	Py_DECREF(obj);
+
+	return ret;
+}
+
+const char* laymanAPIGetInfo(LaymanAPI* l, const char* overlay)
+{
+	if (!l || !l->object)
+		return NULL;
+
+	PyObject *list = PyList_New(1);
+	PyList_Insert(list, 0, PyBytes_FromString(overlay));
+
+	PyObject *obj = PyObject_CallMethod(l->object, "get_info", "O", list);
+	Py_DECREF(list);
+
+	if (!obj)
+		return NULL;
+
+	PyObject *result = PyList_GetItem(obj, 0);
+	char* tmp = PyBytes_AsString(result);
+	char* ret = malloc((strlen(tmp) + 1) * sizeof(char));
+	strcpy(ret, tmp);
+	Py_DECREF(result);
+
+	return ret;
+	//TODO:also return 'official' an 'supported' (see laymanapi.h)
+}
+

diff --git a/src/laymanapi.h b/src/laymanapi.h
new file mode 100644
index 0000000..42c0058
--- /dev/null
+++ b/src/laymanapi.h
@@ -0,0 +1,47 @@
+#ifndef LAYMAN_API_H
+#define LAYMAN_API_H
+
+#include "config.h"
+#include "stringlist.h"
+
+typedef struct LaymanAPI LaymanAPI;
+
+typedef enum OverlayType {Svn = 0, Git, Bzr} OverlayType;
+typedef enum OverlayQuality {Experimental = 0, Stable, Testing} OverlayQuality;
+typedef struct OverlayInfo
+{
+	char *name;
+	char *source;
+	char *contact;
+	OverlayType type;
+	int priority;
+	OverlayQuality quality;
+	char *description;
+	char *link;
+	char *feed;
+	int official;
+	int supported;
+} OverlayInfo;
+
+
+LaymanAPI*	laymanAPICreate(Config*, int, int);
+StringList*	laymanAPIGetAvailable(LaymanAPI*);
+StringList*	laymanAPIGetInstalled(LaymanAPI*);
+
+/*
+ * The Python API returns a list of warnings/sucesses/errors
+ * In here, a boolean value is returned.
+ * Warnings can be retreived with
+ * 	laymanAPIWarnings()
+ * 	laymanAPIErrors()
+ * As there's only one argument here, there's need to have success results.
+ *
+ * The reason it's done this way is that the Python way of doing things is not the same as the Python way.
+ *
+ * FIXME:is it a good idea to have different APIs for different languages ?
+ */
+int 		laymanAPISync(LaymanAPI*, const char*);
+int 		laymanAPIFetchRemoteList(LaymanAPI*);
+const char*	laymanAPIGetInfo(LaymanAPI*, const char*);
+
+#endif

diff --git a/src/message.c b/src/message.c
new file mode 100644
index 0000000..bc0ee56
--- /dev/null
+++ b/src/message.c
@@ -0,0 +1,71 @@
+#include <Python.h>
+#include "message.h"
+#include "interpreter.h"
+
+struct Message
+{
+	PyObject *object;
+};
+
+Message *messageCreate(const char* module,
+			FILE* out,
+			FILE* err,
+			FILE* dbg,
+			int debug_level,
+			int debug_verbosity,
+			int info_level,
+			int warn_level,
+			int col,
+			StringList* mth,
+			StringList* obj,
+			StringList* var)
+{
+	PyObject *pyout, *pyerr, *pydbg, *pymth, *pyobj, *pyvar;
+
+	pyout = PyFile_FromFile((fileno(out) <= 0 ? stdout : out),
+				NULL, "w", 0);
+	pyerr = PyFile_FromFile((fileno(err) <= 0 ? stderr : err),
+				NULL, "w", 0);
+	pydbg = PyFile_FromFile((fileno(dbg) <= 0 ? stderr : dbg),
+				NULL, "w", 0);
+	
+
+	pymth = cListToPyList(mth);
+	pyobj = cListToPyList(obj);
+	pyvar = cListToPyList(var);
+
+	PyObject *object = executeFunction("layman.debug", "Message",
+					"(sOOOIIIIIOOO)",
+					module,
+					pyout,
+					pyerr,
+					pydbg,
+					debug_level,
+					debug_verbosity,
+					info_level,
+					warn_level,
+					col,
+					pymth,
+					pyobj,
+					pyvar);
+
+	Py_DECREF(pyout);
+	Py_DECREF(pyerr);
+	Py_DECREF(pydbg);
+	Py_DECREF(pymth);
+	Py_DECREF(pyobj);
+	Py_DECREF(pyvar);
+
+	if (!object)
+		return NULL;
+
+	Message *ret = malloc(sizeof(Message));
+	ret->object = object;
+
+	return ret;
+}
+
+PyObject *_messageObject(Message* m)
+{
+	return m ? m->object : NULL;
+}

diff --git a/src/message.h b/src/message.h
new file mode 100644
index 0000000..15f3e15
--- /dev/null
+++ b/src/message.h
@@ -0,0 +1,15 @@
+#ifndef MESSAGE_H
+#define MESSAGE_H
+
+#include <Python.h>
+#include "stringlist.h"
+
+typedef struct Message Message;
+
+/*
+ * arguments : module (String), stdout (fd), stderr (fd), stderr (fd), debug_level, debug_verbosity, info_level, warn_level, ?, ?, ?, ?
+ */
+Message *messageCreate(const char*, FILE*, FILE*, FILE*, int, int, int, int, int, StringList*, StringList*, StringList*);
+PyObject *_messageObject(Message* m);
+
+#endif

diff --git a/src/stringlist.c b/src/stringlist.c
new file mode 100644
index 0000000..dc2a45d
--- /dev/null
+++ b/src/stringlist.c
@@ -0,0 +1,59 @@
+#include "stringlist.h"
+
+struct StringList
+{
+	char **list;
+	int count;
+};
+
+StringList* stringListCreate(size_t count)
+{
+	return NULL;
+}
+
+StringList* listToCList(PyObject* list)
+{
+	if (!list || !PyList_Check(list))
+		return NULL;
+
+	int len = PyList_Size(list);
+	StringList *ret = malloc(sizeof(StringList));
+	ret->count = len;
+	ret->list = malloc(sizeof(char*) * len);
+
+	for (int i = 0; i < len; i++)
+	{
+		PyObject *elem = PyList_GetItem(list, i);
+		ret->list[i] = malloc(sizeof(char) * (PyBytes_Size(elem) + 1));
+		strcpy(ret->list[i], PyBytes_AsString(elem));
+	}
+
+	return ret;
+}
+
+PyObject* cListToPyList(StringList* list)
+{
+	if (!list)
+		return NULL;
+
+	PyObject *ret = PyList_New(list->count);
+	for(int i = 0; i < list->count; i++)
+	{
+		PyList_Append(ret, PyBytes_FromString(list->list[i]));
+	}
+
+	return ret;
+}
+
+void stringListFree(StringList* list)
+{
+	if (!list)
+		return;
+
+	for(int i = 0; i < list->count; i++)
+	{
+		free(list->list[i]);
+	}
+
+	free(list);
+}

diff --git a/src/stringlist.h b/src/stringlist.h
new file mode 100644
index 0000000..cf1c33a
--- /dev/null
+++ b/src/stringlist.h
@@ -0,0 +1,12 @@
+#ifndef STRINGLIST_H
+#define STRINGLIST_H
+
+#include <Python.h>
+
+typedef struct StringList StringList;
+
+StringList* stringListCreate(size_t);
+StringList* listToCList(PyObject* list);
+PyObject* cListToPyList(StringList*);
+
+#endif



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     650c79cb75b4b09257ce0e489c5e20707d8758e0
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul  9 13:31:23 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul  9 13:31:23 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=650c79cb

Add a C <-> Python Dict class and fix DbBase to take a Dict fo it's
config argument

---
 src/dbbase.c |   11 +++----
 src/dbbase.h |    3 +-
 src/dict.c   |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/dict.h   |   14 ++++++++++
 4 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/src/dbbase.c b/src/dbbase.c
index c617326..dbff007 100644
--- a/src/dbbase.c
+++ b/src/dbbase.c
@@ -1,6 +1,7 @@
-#include "config.h"
+//#include "config.h"
 #include "dbbase.h"
 #include "interpreter.h"
+#include "dict.h"
 #include <Python.h>
 
 struct DbBase
@@ -8,7 +9,7 @@ struct DbBase
 	PyObject *object;
 };
 
-DbBase* createDbBase(const char *paths[], unsigned int pathCount, Config *c, int ignore, int quiet, int ignore_init_read_errors)
+DbBase* createDbBase(const char *paths[], unsigned int pathCount, Dict *dict, int ignore, int quiet, int ignore_init_read_errors)
 {
 	PyObject *pypaths = PyList_New(pathCount);
 	for (unsigned int i = 0; i < pathCount; i++)
@@ -16,10 +17,8 @@ DbBase* createDbBase(const char *paths[], unsigned int pathCount, Config *c, int
 		PyObject *path = PyBytes_FromString(paths[i]);
 		PyList_Insert(pypaths, i, path);
 	}
-	
-	PyObject *cfg = _object(c);
-	
-	PyObject *obj = executeFunction("layman.dbbase", "DbBase", "OOIII", pypaths, cfg, ignore, quiet, ignore_init_read_errors);
+
+	PyObject *obj = executeFunction("layman.dbbase", "DbBase", "OOIII", pypaths, dictToPyDict(dict), ignore, quiet, ignore_init_read_errors);
 	Py_DECREF(pypaths);
 
 	if (!obj)

diff --git a/src/dbbase.h b/src/dbbase.h
index 12065af..56f9270 100644
--- a/src/dbbase.h
+++ b/src/dbbase.h
@@ -2,9 +2,10 @@
 #define DB_BASE_H
 
 #include "config.h"
+#include "dict.h"
 
 typedef struct DbBase DbBase;
 
-DbBase* createDbBase(const char *paths[], unsigned int path_count, Config *c, int ignore, int quiet, int ignore_init_read_errors);
+DbBase* createDbBase(const char *paths[], unsigned int path_count, Dict *c, int ignore, int quiet, int ignore_init_read_errors);
 
 #endif

diff --git a/src/dict.c b/src/dict.c
new file mode 100644
index 0000000..a818a69
--- /dev/null
+++ b/src/dict.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dict.h"
+
+/*
+ * Dict
+ */
+typedef struct DictElem DictElem;
+struct DictElem
+{
+	const char *key;
+	const char *val;
+	struct DictElem *next;
+};
+
+struct Dict
+{
+	DictElem *root;
+	int count;
+};
+
+Dict *dictCreate()
+{
+	Dict *ret = malloc(sizeof(Dict));
+	ret->count = 0;
+	ret->root = 0;
+	return ret;
+}
+
+void dictInsert(Dict* list, const char* key, const char* value)
+{
+	if (!list)
+		return;
+	DictElem *node = malloc(sizeof(DictElem));
+	node->key = key;
+	node->val = value;
+	node->next = list->root;
+	list->root = node;
+	list->count++;
+}
+
+unsigned int dictCount(Dict *list)
+{
+	return (list ? list->count : 0);
+}
+
+void dictFree(Dict *list, int deref)
+{
+	if (!list)
+		return;
+
+	DictElem *node = list->root;
+	while (node)
+	{
+		DictElem *tmp = node;
+		node = node->next;
+		/*if (deref)
+		{
+			Py_DECREF(tmp->object);
+		}*/
+		free(tmp);
+	}
+
+	free(list);
+}
+
+PyObject *dictToPyDict(Dict *dict)
+{
+	PyObject *pydict = PyDict_New();
+	DictElem *node = dict->root;
+	while (node)
+	{
+		PyDict_SetItem(pydict, PyBytes_FromString(node->key), PyBytes_FromString(node->val));
+		node = node->next;
+	}
+
+	return pydict;
+}

diff --git a/src/dict.h b/src/dict.h
new file mode 100644
index 0000000..844963c
--- /dev/null
+++ b/src/dict.h
@@ -0,0 +1,14 @@
+#ifndef DICT_H
+#define DICT_H
+
+#include <Python.h>
+
+typedef struct Dict Dict;
+
+Dict*		dictCreate();
+//char*		tableFind(Dict *table, char* key);
+void		dictFree(Dict *t, int);
+void		dictInsert(Dict* list, const char* key, const char* value);
+unsigned int	dictCount(Dict *table);
+PyObject*	dictToPyDict(Dict *dict);
+#endif



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     593766766d7d892b469acda29bdb8d848a68dd3b
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul  9 12:45:37 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul  9 12:45:37 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=59376676

Add basic Config and DbBase implemntation (not tested)

---
 src/config.c |   33 +++++++++++++++++++++++++++++++++
 src/config.h |   12 ++++++++++++
 src/dbbase.c |   32 ++++++++++++++++++++++++++++++++
 src/dbbase.h |   10 ++++++++++
 4 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..db632f2
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,33 @@
+#include "config.h"
+#include "interpreter.h"
+#include <Python.h>
+
+struct Config
+{
+	PyObject *object;
+};
+
+PyObject *_object(Config *c)
+{
+	return c ? c->object : NULL;
+}
+
+Config *createConfig(const char *argv[], int argc)
+{
+	PyObject *pyargs = PyList_New(argc);
+	for (int i = 0; i < argc; i++)
+	{
+		PyObject *arg = PyBytes_FromString(argv[i]);
+		PyList_Insert(pyargs, i, arg);
+	}
+
+	PyObject *obj = executeFunction("layman.config", "Config", "O", pyargs);
+	Py_DECREF(pyargs);
+	if (!obj)
+		return NULL;
+
+	Config *ret = malloc(sizeof(Config));
+	ret->object = obj;
+
+	return ret;
+}

diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..e977cdc
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,12 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <Python.h>
+
+typedef struct Config Config;
+
+Config *createConfig(const char *argv[], int argc);
+
+PyObject *_object(Config*);
+
+#endif

diff --git a/src/dbbase.c b/src/dbbase.c
new file mode 100644
index 0000000..c617326
--- /dev/null
+++ b/src/dbbase.c
@@ -0,0 +1,32 @@
+#include "config.h"
+#include "dbbase.h"
+#include "interpreter.h"
+#include <Python.h>
+
+struct DbBase
+{
+	PyObject *object;
+};
+
+DbBase* createDbBase(const char *paths[], unsigned int pathCount, Config *c, int ignore, int quiet, int ignore_init_read_errors)
+{
+	PyObject *pypaths = PyList_New(pathCount);
+	for (unsigned int i = 0; i < pathCount; i++)
+	{
+		PyObject *path = PyBytes_FromString(paths[i]);
+		PyList_Insert(pypaths, i, path);
+	}
+	
+	PyObject *cfg = _object(c);
+	
+	PyObject *obj = executeFunction("layman.dbbase", "DbBase", "OOIII", pypaths, cfg, ignore, quiet, ignore_init_read_errors);
+	Py_DECREF(pypaths);
+
+	if (!obj)
+		return NULL;
+
+	DbBase *ret = malloc(sizeof(DbBase));
+	ret->object = obj;
+
+	return ret;
+}

diff --git a/src/dbbase.h b/src/dbbase.h
new file mode 100644
index 0000000..12065af
--- /dev/null
+++ b/src/dbbase.h
@@ -0,0 +1,10 @@
+#ifndef DB_BASE_H
+#define DB_BASE_H
+
+#include "config.h"
+
+typedef struct DbBase DbBase;
+
+DbBase* createDbBase(const char *paths[], unsigned int path_count, Config *c, int ignore, int quiet, int ignore_init_read_errors);
+
+#endif



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     97d75ee996220405a15f134924ac380262ec46f7
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul  9 10:16:50 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul  9 10:16:50 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=97d75ee9

Restructure classes.

---
 src/interpreter.c |  146 +++++++---------------------------------------------
 src/interpreter.h |   10 ++++
 src/overlay.c     |  102 +++++++++++++++++++++++++++++++++++++
 src/overlay.h     |   14 +++++
 src/tester.c      |   21 ++++++++
 5 files changed, 167 insertions(+), 126 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
index 3653e4f..e68f1a2 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -82,36 +82,41 @@ void freeList(PyObjectList *list, int deref)
  * A Python interpreter object keeps the context like the loaded modules.
  */
 
-typedef struct Interpreter
+struct Interpreter
 {
 	PyObjectList *modules;
-} Interpreter;
+} *in = 0;
 
-Interpreter *createInterpreter()
+//Interpreter *in = 0;
+
+void interpreterInit()
 {
-	Interpreter *ret = malloc(sizeof(Interpreter));
-	ret->modules = createObjectList();
-	return ret;
+	if (in)
+		return;
+
+	if (!Py_IsInitialized())
+		Py_Initialize();
+
+	in = malloc(sizeof(struct Interpreter));
+	in->modules = createObjectList();
 }
 
-void freeInterpreter(Interpreter *inter)
+void interpreterFinalize()
 {
-	if (!inter)
+	if (!in)
 		return;
-	freeList(inter->modules, 1);
-	free(inter);
+	freeList(in->modules, 1);
+	free(in);
 
-	Py_Finalize();
+	if (Py_IsInitialized())
+		Py_Finalize();
 }
 
-Interpreter *in = 0;
-
 /*
  * printf() like function that executes a python function
- * @param interpreter Python interpreter object on which the function should be ran
  * @param module name of the python module in which the function is
  * @param funcName the function name to call
- * @param arg_types printf() like list of arguments. See Python documentation
+ * @param format printf() like list of arguments. See Python documentation
  * @param ... arguments for the function
  */
 
@@ -172,114 +177,3 @@ PyObject *executeFunction(const char *module, const char *funcName, const char*
 
 	return val;
 }
-
-typedef struct Overlay Overlay;
-
-struct Overlay
-{
-	PyObject *object;
-};
-
-/*
- * FIXME: should the xml argument be an expat element ?
- */
-Overlay *createOverlay(const char *xml, const char *config, int ignore, int quiet)
-{
-	//First argument must be a xml.etree.Element
-	//PyObject *elem = executeFunction("layman.overlays.overlay", "testfunc", NULL);
-	PyObject *elem = executeFunction("xml.etree.ElementTree", "fromstring", "(s)", xml);
-	if (!elem)
-		return NULL;
-
-	config = config;
-	PyObject *cfg = PyDict_New();
-	if (!cfg)
-		return NULL;
-
-	PyObject *overlay = executeFunction("layman.overlays.overlay", "Overlay", "(OOIb)", elem, cfg, ignore, quiet);
-	if (!overlay)
-		return NULL;
-	Overlay *ret = malloc(sizeof(Overlay));
-	ret->object = overlay;
-
-	return ret;
-}
-
-const char *overlayName(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *name = PyObject_GetAttrString(o->object, "name");
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(name);
-}
-
-const char *overlayOwnerEmail(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *ret = PyObject_GetAttrString(o->object, "owner_email");
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(ret);
-}
-
-int overlayPriority(Overlay *o)
-{
-	if (!o || !o->object)
-		return -1;
-
-	PyObject *prio = PyObject_GetAttrString(o->object, "priority");
-
-	//TODO:Py_DECREF me !
-
-	return (int) PyLong_AsLong(prio);
-}
-
-const char *overlayDescription(Overlay *o)
-{
-	if (!o || !o->object)
-		return NULL;
-
-	PyObject *desc = PyObject_GetAttrString(o->object, "description");
-
-	//TODO:Py_DECREF me !
-
-	return PyBytes_AsString(desc);
-}
-
-int overlayIsOfficial(Overlay *o)
-{
-	if (!o || !o->object)
-		return -1;
-
-	PyObject *iso = PyObject_CallMethod(o->object, "is_official", NULL);
-
-	//TODO:Py_DECREF me !
-
-	return (int) PyLong_AsLong(iso);
-}
-
-int main(int argc, char *argv[])
-{
-	in = createInterpreter();
-	
-	Overlay *o = createOverlay("<overlay type='svn' src='https://overlays.gentoo.org/svn/dev/wrobel' contact='nobody@gentoo.org' name='wrobel' status='official' priorit='10'><description>Test</description></overlay>", "", 1, 0);
-
-	if (!o)
-	{
-		printf("Error creating overlay.\n");
-		return 0;
-	}
-	
-	printf("Overlay name = %s, owner email : %s, description : %s, priority : %d, it is %sofficial.\n", overlayName(o), overlayOwnerEmail(o), overlayDescription(o), overlayPriority(o), overlayIsOfficial(o) ? "" : "not ");
-
-	freeInterpreter(in);
-
-	return 0;
-}

diff --git a/src/interpreter.h b/src/interpreter.h
new file mode 100644
index 0000000..d21ad44
--- /dev/null
+++ b/src/interpreter.h
@@ -0,0 +1,10 @@
+#ifndef INTERPRETER_H
+#define INTERPRETER_H
+
+#include <Python.h>
+
+void 		interpreterInit();
+void 		interpreterFinalize();
+PyObject*	executeFunction(const char *module, const char *funcName, const char* format, ...);
+
+#endif

diff --git a/src/overlay.c b/src/overlay.c
new file mode 100644
index 0000000..79fee08
--- /dev/null
+++ b/src/overlay.c
@@ -0,0 +1,102 @@
+#include <Python.h>
+
+#include "interpreter.h"
+#include "overlay.h"
+
+struct Overlay
+{
+	PyObject *object;
+};
+
+/*
+ * FIXME: should the xml argument be an expat element ?
+ */
+Overlay *createOverlay(const char *xml, const char *config, int ignore, int quiet)
+{
+	//First argument must be a xml.etree.Element
+	//PyObject *elem = executeFunction("layman.overlays.overlay", "testfunc", NULL);
+	PyObject *elem = executeFunction("xml.etree.ElementTree", "fromstring", "(s)", xml);
+	if (!elem)
+		return NULL;
+
+	config = config;
+	PyObject *cfg = PyDict_New();
+	if (!cfg)
+		return NULL;
+
+	PyObject *overlay = executeFunction("layman.overlays.overlay", "Overlay", "(OOIb)", elem, cfg, ignore, quiet);
+	if (!overlay)
+		return NULL;
+	Overlay *ret = malloc(sizeof(Overlay));
+	ret->object = overlay;
+
+	return ret;
+}
+
+const char *overlayName(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *name = PyObject_GetAttrString(o->object, "name");
+
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(name);
+}
+
+const char *overlayOwnerEmail(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *ret = PyObject_GetAttrString(o->object, "owner_email");
+
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(ret);
+}
+
+int overlayPriority(Overlay *o)
+{
+	if (!o || !o->object)
+		return -1;
+
+	PyObject *prio = PyObject_GetAttrString(o->object, "priority");
+
+	//TODO:Py_DECREF me !
+
+	return (int) PyLong_AsLong(prio);
+}
+
+const char *overlayDescription(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *desc = PyObject_GetAttrString(o->object, "description");
+
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(desc);
+}
+
+int overlayIsOfficial(Overlay *o)
+{
+	if (!o || !o->object)
+		return -1;
+
+	PyObject *iso = PyObject_CallMethod(o->object, "is_official", NULL);
+
+	//TODO:Py_DECREF me !
+
+	return (int) PyLong_AsLong(iso);
+}
+
+void overlayFree(Overlay *o)
+{
+	if (o && o->object)
+		Py_DECREF(o->object);
+	if (o)
+		free(o);
+}

diff --git a/src/overlay.h b/src/overlay.h
new file mode 100644
index 0000000..9125de0
--- /dev/null
+++ b/src/overlay.h
@@ -0,0 +1,14 @@
+#ifndef OVERLAY_H
+#define OVERLAY_H
+
+typedef struct Overlay Overlay;
+
+Overlay*	createOverlay(const char*, const char*, int, int);
+const char*	overlayName(Overlay*);
+const char*	overlayOwnerEmail(Overlay*);
+int 		overlayPriority(Overlay*);
+const char*	overlayDescription(Overlay*);
+int 		overlayIsOfficial(Overlay*);
+void		overlayFree(Overlay*);
+
+#endif

diff --git a/src/tester.c b/src/tester.c
new file mode 100644
index 0000000..53e4776
--- /dev/null
+++ b/src/tester.c
@@ -0,0 +1,21 @@
+#include "overlay.h"
+#include "interpreter.h"
+
+int main(int argc, char *argv[])
+{
+	interpreterInit();
+	
+	Overlay *o = createOverlay("<overlay type='svn' src='https://overlays.gentoo.org/svn/dev/wrobel' contact='nobody@gentoo.org' name='wrobel' status='official' priorit='10'><description>Test</description></overlay>", "", 1, 0);
+
+	if (!o)
+	{
+		printf("Error creating overlay.\n");
+		return 0;
+	}
+	
+	printf("Overlay name = %s, owner email : %s, description : %s, priority : %d, it is %sofficial.\n", overlayName(o), overlayOwnerEmail(o), overlayDescription(o), overlayPriority(o), overlayIsOfficial(o) ? "" : "not ");
+
+	interpreterFinalize();
+
+	return 0;
+}



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     cee0d8244d6b3223c296def49678076edb239445
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Tue Jul  6 09:37:00 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Tue Jul  6 09:37:00 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=cee0d824

Now working execute function (only for functions)

---
 src/interpreter.c |  237 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 204 insertions(+), 33 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
index 6ab2843..2e2f7b9 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -2,57 +2,228 @@
 #include <stdio.h>
 #include <string.h>
 
-int main(int argc, char *argv[])
+/*
+ * PyObjectList
+ */
+typedef struct PyObjectListElem
+{
+	PyObject *object;
+	struct PyObjectListElem *next;
+} PyObjectListElem;
+
+typedef struct PyObjectList
+{
+	PyObjectListElem *root;
+	int count;
+} PyObjectList;
+
+PyObjectList *createObjectList()
+{
+	PyObjectList *ret = malloc(sizeof(PyObjectList));
+	ret->count = 0;
+	ret->root = 0;
+	return ret;
+}
+
+void insert(PyObjectList* list, PyObject *object)
+{
+	if (!list || !object)
+		return;
+	PyObjectListElem *node = malloc(sizeof(PyObjectListElem));
+	node->object = object;
+	node->next = list->root;
+	list->root = node;
+	list->count++;
+}
+
+PyObject *elementAt(PyObjectList* list, int pos)
+{
+	if (!list || list->count < pos)
+		return NULL;
+
+	PyObjectListElem *node = list->root;
+	for (int i = 0; i < pos; i++)
+	{
+		node = node->next;
+	}
+	if (!node)
+		return 0;
+
+	return node->object;
+}
+
+PyObject *moduleNamed(const char *name, PyObjectList *list)
+{
+	PyObjectListElem *node = list->root;
+	while (node)
+	{
+		if (strcmp(PyModule_GetName(node->object), name))
+			return node->object;
+		node = node->next;
+	}
+	
+	return NULL;
+}
+
+PyObject *toTuple(PyObjectList *list)
 {
-	PyObject *pP1, *pP2, *pArgs, *pName, *pModule, *pDict, *pFunc, *pValue;
+	if (!list)
+		return NULL;
 
-	Py_Initialize();
+	PyObject *ret = PyTuple_New(list->count);
+	PyObjectListElem *node = list->root;
+	int i = 0;
+	while (node)
+	{
+		if (node->object)
+			PyTuple_SetItem(ret, i++, node->object);
+		node = node->next;
+	}
 
-	//printf("%s\n", Py_GetVersion());
+	return ret;
+}
 
-	//pName = PyByteArray_FromStringAndSize("portage", strlen("portage"));
-	pModule = PyModule_New("portage");
+int listCount(PyObjectList *list)
+{
+	return (list ? list->count : 0);
+}
 
-	pDict = PyModule_GetDict(pModule);
-	pFunc = PyDict_GetItemString(pDict, "pkgcmp");
+void freeList(PyObjectList *list, int deref)
+{
+	if (!list)
+		return;
 
-	if (PyCallable_Check(pFunc)) 
+	PyObjectListElem *node = list->root;
+	while (node)
 	{
-		pP1 = PyByteArray_FromStringAndSize("app-portage/kuroo4-4.2", strlen("app-portage/kuroo4-4.2"));
-		pP2 = PyByteArray_FromStringAndSize("app-portage/kuroo4-4.3", strlen("app-portage/kuroo4-4.3"));
+		PyObjectListElem *tmp = node;
+		node = node->next;
+		if (deref)
+			Py_DECREF(tmp->object);
+		free(tmp);
+	}
 
-		pArgs = PyTuple_New(2);
+	free(list);
+}
 
-		PyTuple_SetItem(pArgs, 0, pP1);	
-		PyTuple_SetItem(pArgs, 0, pP2);	
+/*
+ * Interpreter
+ */
 
-		pValue = PyObject_CallObject(pFunc, pArgs);
+/*
+ * A Python interpreter object keeps the context like the loaded modules.
+ */
 
-		if (pArgs != NULL)
+typedef struct Interpreter
+{
+	PyObjectList *modules;
+} Interpreter;
+
+Interpreter *createInterpreter()
+{
+	Interpreter *ret = malloc(sizeof(Interpreter));
+	ret->modules = createObjectList();
+	return ret;
+}
+
+void freeInterpreter(Interpreter *inter)
+{
+	if (!inter)
+		return;
+	freeList(inter->modules, 1);
+	free(inter);
+
+	Py_Finalize();
+}
+
+/*
+ * printf() like function that executes a python function
+ * @param interpreter Python interpreter object on which the function should be ran
+ * @param module name of the python module in which the function is
+ * @param funcName the function name to call
+ * @param arg_types printf() like list of arguments TODO:explain more --> See Python documentation
+ * @param ... arguments for the function
+ */
+
+PyObject *executeFunction(Interpreter *interpreter, const char *module, const char *funcName, const char* format, ...)
+{
+	if (!Py_IsInitialized())
+		Py_Initialize();
+
+	// Make arguments
+	// FIXME: use Py_BuildValue.
+	// FIXME: is it possible to pass this function's arguments to another function ?
+	PyObjectList *argList = createObjectList();
+	int i = 0;
+	while (format[i] != '\0')
+	{
+		while(format[i] != '%' && format[i] != '\0')
+			i++;
+		
+		if (format[i] == '\0')
+			break;
+
+		PyObject *arg = NULL;
+		switch(format[++i])
 		{
-			Py_DECREF(pArgs);
+		case 'd': //number
+			break;
+		case 's': //string
+			break;
+		case 'P': //PyObject
+			break;
+		default: //skip or abort ?
+			break;
 		}
+
+		insert(argList, arg);
+		i++;
 	}
-	else 
-		PyErr_Print();
 
-	int ret = PyLong_AsLong(pValue);
-	switch(ret)
+	PyObject *args = toTuple(argList);
+	freeList(argList, 1);
+
+	// Look for the module.
+	PyObject *mod = 0;
+	if (interpreter->modules)
 	{
-	case -1:
-		printf("less");
-		break;
-	case 0:
-		printf("same");
-		break;
-	case 1:
-		printf("more");
-		break;
+		mod = moduleNamed(module, interpreter->modules);
+	}
+	if (!mod)
+	{
+		mod = PyImport_ImportModule(module);
+		insert(interpreter->modules, mod);
 	}
 
-	printf("\n");
+	// Look for the function
+	PyObject *dict = PyModule_GetDict(mod);
+	PyObject *func = PyDict_GetItemString(dict, funcName);
 
-	Py_DECREF(pModule);
+	if (!PyCallable_Check(func))
+		return NULL;
 
-	Py_Finalize();
+	// Call the function
+	PyObject *val = PyObject_CallObject(func, args);
+
+	// Add return value object in a local list so it can be DECREF'ed when the interpreter is deleted.
+	// TODO
+
+	Py_DECREF(args);
+
+	return val;
+}
+
+
+int main(int argc, char *argv[])
+{
+	Interpreter *in = createInterpreter();
+
+	PyObject *ret = executeFunction(in, "portage.data", "portage_group_warning", "");
+
+	if (!ret)
+		printf("failed :-( \n");
+
+	freeInterpreter(in);
+
+	return 0;
 }



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     40928302b905a329555de0fde1d592463049b97c
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Tue Jul  6 15:57:13 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Tue Jul  6 15:57:13 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=40928302

Add examples for method execution from an instance of an object

---
 src/interpreter.c |  135 +++++++++++++++++++++++-----------------------------
 1 files changed, 60 insertions(+), 75 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
index dd0ebd3..5d5bca5 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -40,28 +40,12 @@ void insert(PyObjectList* list, PyObject *object)
 	list->count++;
 }
 
-PyObject *elementAt(PyObjectList* list, int pos)
-{
-	if (!list || list->count < pos)
-		return NULL;
-
-	PyObjectListElem *node = list->root;
-	for (int i = 0; i < pos; i++)
-	{
-		node = node->next;
-	}
-	if (!node)
-		return 0;
-
-	return node->object;
-}
-
 PyObject *moduleNamed(const char *name, PyObjectList *list)
 {
 	PyObjectListElem *node = list->root;
 	while (node)
 	{
-		if (strcmp(PyModule_GetName(node->object), name))
+		if (strcmp(PyModule_GetName(node->object), name) == 0)
 			return node->object;
 		node = node->next;
 	}
@@ -69,24 +53,6 @@ PyObject *moduleNamed(const char *name, PyObjectList *list)
 	return NULL;
 }
 
-PyObject *toTuple(PyObjectList *list)
-{
-	if (!list)
-		return NULL;
-
-	PyObject *ret = PyTuple_New(list->count);
-	PyObjectListElem *node = list->root;
-	int i = 0;
-	while (node)
-	{
-		if (node->object)
-			PyTuple_SetItem(ret, i++, node->object);
-		node = node->next;
-	}
-
-	return ret;
-}
-
 int listCount(PyObjectList *list)
 {
 	return (list ? list->count : 0);
@@ -112,9 +78,7 @@ void freeList(PyObjectList *list, int deref)
 
 /*
  * Interpreter
- */
-
-/*
+ *
  * A Python interpreter object keeps the context like the loaded modules.
  */
 
@@ -145,8 +109,9 @@ void freeInterpreter(Interpreter *inter)
  * @param interpreter Python interpreter object on which the function should be ran
  * @param module name of the python module in which the function is
  * @param funcName the function name to call
- * @param arg_types printf() like list of arguments TODO:explain more --> See Python documentation
+ * @param arg_types printf() like list of arguments. See Python documentation
  * @param ... arguments for the function
+ * FIXME:why are default arguments necessary ?
  */
 
 PyObject *executeFunction(Interpreter *interpreter, const char *module, const char *funcName, const char* format, ...)
@@ -154,38 +119,17 @@ PyObject *executeFunction(Interpreter *interpreter, const char *module, const ch
 	if (!Py_IsInitialized())
 		Py_Initialize();
 
-	// Make arguments
-	// FIXME: use Py_BuildValue.
-	// FIXME: is it possible to pass this function's arguments to another function ?
-	PyObjectList *argList = createObjectList();
-	int i = 0;
-	while (format[i] != '\0')
+	// Make argument list
+	PyObject *args;
+	if (format == NULL)
+		args = Py_None;
+	else
 	{
-		while(format[i] != '%' && format[i] != '\0')
-			i++;
-		
-		if (format[i] == '\0')
-			break;
-
-		PyObject *arg = NULL;
-		switch(format[++i])
-		{
-		case 'd': //number
-			break;
-		case 's': //string
-			break;
-		case 'P': //PyObject
-			break;
-		default: //skip or abort ?
-			break;
-		}
-
-		insert(argList, arg);
-		i++;
-	}
+		va_list listArgs;
+		va_start(listArgs, format);
 
-	PyObject *args = toTuple(argList);
-	freeList(argList, 1);
+		args = Py_VaBuildValue(format, listArgs);
+	}
 
 	// Look for the module.
 	PyObject *mod = 0;
@@ -196,36 +140,77 @@ PyObject *executeFunction(Interpreter *interpreter, const char *module, const ch
 	if (!mod)
 	{
 		mod = PyImport_ImportModule(module);
+		if (!mod)
+			return NULL;
 		insert(interpreter->modules, mod);
 	}
 
-	// Look for the function
-	PyObject *dict = PyModule_GetDict(mod);
-	PyObject *func = PyDict_GetItemString(dict, funcName);
+	/*printf("mod: %p ", mod);
+	PyObject_Print(mod, stdout, 0);
+	printf("\n");*/
 
+	// Look for the function
+	PyObject *func = PyObject_GetAttrString(mod, funcName);
 	if (!PyCallable_Check(func))
 		return NULL;
 
 	// Call the function
-	PyObject *val = PyObject_CallObject(func, args);
+	/*printf("func: %p\n", func);
+	PyObject_Print(func, stdout, 0);
+	printf("\n");*/
+
+	PyObject *val = PyObject_Call(func, args, NULL);
 
 	// Add return value object in a local list so it can be DECREF'ed when the interpreter is deleted.
 	// TODO
-
 	Py_DECREF(args);
 
 	return val;
 }
+/*
+PyObject *executeMethod(PyObject *object, const char *methName, const char* format, ...)
+{
+	if (!Py_IsInitialized())
+		Py_Initialize();
+
+	// Make argument list
+	PyObject *args;
+	if (format == NULL)
+		args = Py_None;
+	else
+	{
+		va_list listArgs;
+		va_start(listArgs, format);
 
+		args = Py_VaBuildValue(format, listArgs);
+	}
+
+	PyObject *ret = PyObject_CallMethod(object, methName, )
+}*/
 
 int main(int argc, char *argv[])
 {
 	Interpreter *in = createInterpreter();
 
-	PyObject *ret = executeFunction(in, "portage.data", "portage_group_warning", "");
+	executeFunction(in, "portage.data", "portage_group_warning", NULL);
+
+	PyObject *arg1 = executeFunction(in, "portage", "pkgsplit", "sI", "app-portage/kuroo4-4.2", 1);
+	PyObject *arg2 = executeFunction(in, "portage", "pkgsplit", "sI", "app-portage/kuroo4-4.1", 1);
+	PyObject *ret = executeFunction(in, "portage", "pkgcmp", "OO", arg1, arg2);
 
 	if (!ret)
 		printf("failed :-( \n");
+	else
+		printf("Return %ld\n", PyLong_AsLong(ret));
+
+	Py_DECREF(ret);
+	Py_DECREF(arg1);
+	Py_DECREF(arg2);
+	
+	PyObject *tbz = executeFunction(in, "portage.output", "ProgressBar", "sIs", "titre", 100, "status");
+	ret = PyObject_CallMethod(tbz, "inc", "I", 25);
+	Py_DECREF(tbz);
+	Py_DECREF(ret);
 
 	freeInterpreter(in);
 



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     c9f9363987db6dd3304d059a86574bb3635ceb14
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Tue Jul  6 12:07:58 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Tue Jul  6 12:07:58 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=c9f93639

Fix runner to run without argument

---
 src/runner.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/runner.c b/src/runner.c
index 628ac9a..61c342a 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -24,7 +24,7 @@ struct Runner {
 int main(int argc, char* argv[])
 {
 	// Tries to compare 2 packages version.
-	if (argc < 3)
+	/*if (argc < 3)
 	{
 		printf("Please provide 2 packages.\n");
 		return -1;
@@ -33,10 +33,10 @@ int main(int argc, char* argv[])
 	char *str = malloc((strlen(argv[1]) + strlen(argv[2]) + 2) * sizeof(char));
 
 	sprintf(str, "%s %s", argv[1], argv[2]);
-
+	*/
 	Runner *r = createRunner();
 	r->writeStdout = stdoutWritten;
-	int ret = execute(r, str);
+	int ret = execute(r, "");
 	
 	if (ret < 0)
 		printf("Execution error\n");



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     2fb39c00d5a75f5bd3462a8b3f7f556367dfc71a
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Tue Jul  6 12:03:43 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Tue Jul  6 12:03:43 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=2fb39c00

Add compile command line

---
 src/interpreter.c |    4 ++++
 src/runner.c      |    6 +++++-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
index 2e2f7b9..dd0ebd3 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -1,3 +1,7 @@
+/*
+ * Compile command :
+ * gcc -o interpreter -W -Wall -g --std=c99 -I/usr/include/python3.1/ -lpython3.1 interpreter.c
+ */
 #include <Python.h>
 #include <stdio.h>
 #include <string.h>

diff --git a/src/runner.c b/src/runner.c
index ddf20d2..628ac9a 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -1,3 +1,7 @@
+/*
+ * Compile command :
+ * gcc -o runner -W -Wall -g --std=c99 runner.c
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -117,7 +121,7 @@ int execute(Runner *r, char *args)
 	}
 	
 	dup2(fd, STDOUT_FILENO);
-	ret = execl("/home/detlev/src/c-portage/src/test.py", "test.py", "app-portage/kuroo4-4.2", "app-portage/kuroo4-4.3", NULL);
+	ret = execl("./test.py", "test.py", "app-portage/kuroo4-4.2", "app-portage/kuroo4-4.3", NULL);
 	printf("execl: (%d) %s\n", errno, strerror(errno));
 	return ret;
 }



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     6459c9b9e7bf16e235b8c5b151f97a224aebb108
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Fri Jul  9 09:18:24 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Fri Jul  9 09:18:24 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=6459c9b9

Tests the layman's overlays API

---
 src/interpreter.c |  153 ++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 110 insertions(+), 43 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
index 5d5bca5..3653e4f 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -104,6 +104,8 @@ void freeInterpreter(Interpreter *inter)
 	Py_Finalize();
 }
 
+Interpreter *in = 0;
+
 /*
  * printf() like function that executes a python function
  * @param interpreter Python interpreter object on which the function should be ran
@@ -111,18 +113,17 @@ void freeInterpreter(Interpreter *inter)
  * @param funcName the function name to call
  * @param arg_types printf() like list of arguments. See Python documentation
  * @param ... arguments for the function
- * FIXME:why are default arguments necessary ?
  */
 
-PyObject *executeFunction(Interpreter *interpreter, const char *module, const char *funcName, const char* format, ...)
+PyObject *executeFunction(const char *module, const char *funcName, const char* format, ...)
 {
 	if (!Py_IsInitialized())
 		Py_Initialize();
 
 	// Make argument list
 	PyObject *args;
-	if (format == NULL)
-		args = Py_None;
+	if (format == NULL || strcmp(format, "") == 0)
+		args = PyTuple_New(0);
 	else
 	{
 		va_list listArgs;
@@ -133,18 +134,20 @@ PyObject *executeFunction(Interpreter *interpreter, const char *module, const ch
 
 	// Look for the module.
 	PyObject *mod = 0;
-	if (interpreter->modules)
+	if (in->modules)
 	{
-		mod = moduleNamed(module, interpreter->modules);
+		mod = moduleNamed(module, in->modules);
 	}
 	if (!mod)
 	{
 		mod = PyImport_ImportModule(module);
 		if (!mod)
 			return NULL;
-		insert(interpreter->modules, mod);
+		insert(in->modules, mod);
 	}
 
+	//printf("Using module named %s\n", PyModule_GetName(mod));
+
 	/*printf("mod: %p ", mod);
 	PyObject_Print(mod, stdout, 0);
 	printf("\n");*/
@@ -159,58 +162,122 @@ PyObject *executeFunction(Interpreter *interpreter, const char *module, const ch
 	PyObject_Print(func, stdout, 0);
 	printf("\n");*/
 
-	PyObject *val = PyObject_Call(func, args, NULL);
+	//PyObject_Print(args, stdout, 0);
+	//printf("\n");
 
-	// Add return value object in a local list so it can be DECREF'ed when the interpreter is deleted.
-	// TODO
-	Py_DECREF(args);
+	PyObject *val = PyObject_CallObject(func, args);
+
+	if (args != NULL)
+		Py_DECREF(args);
 
 	return val;
 }
+
+typedef struct Overlay Overlay;
+
+struct Overlay
+{
+	PyObject *object;
+};
+
 /*
-PyObject *executeMethod(PyObject *object, const char *methName, const char* format, ...)
+ * FIXME: should the xml argument be an expat element ?
+ */
+Overlay *createOverlay(const char *xml, const char *config, int ignore, int quiet)
 {
-	if (!Py_IsInitialized())
-		Py_Initialize();
+	//First argument must be a xml.etree.Element
+	//PyObject *elem = executeFunction("layman.overlays.overlay", "testfunc", NULL);
+	PyObject *elem = executeFunction("xml.etree.ElementTree", "fromstring", "(s)", xml);
+	if (!elem)
+		return NULL;
 
-	// Make argument list
-	PyObject *args;
-	if (format == NULL)
-		args = Py_None;
-	else
-	{
-		va_list listArgs;
-		va_start(listArgs, format);
+	config = config;
+	PyObject *cfg = PyDict_New();
+	if (!cfg)
+		return NULL;
 
-		args = Py_VaBuildValue(format, listArgs);
-	}
+	PyObject *overlay = executeFunction("layman.overlays.overlay", "Overlay", "(OOIb)", elem, cfg, ignore, quiet);
+	if (!overlay)
+		return NULL;
+	Overlay *ret = malloc(sizeof(Overlay));
+	ret->object = overlay;
 
-	PyObject *ret = PyObject_CallMethod(object, methName, )
-}*/
+	return ret;
+}
 
-int main(int argc, char *argv[])
+const char *overlayName(Overlay *o)
 {
-	Interpreter *in = createInterpreter();
+	if (!o || !o->object)
+		return NULL;
 
-	executeFunction(in, "portage.data", "portage_group_warning", NULL);
+	PyObject *name = PyObject_GetAttrString(o->object, "name");
 
-	PyObject *arg1 = executeFunction(in, "portage", "pkgsplit", "sI", "app-portage/kuroo4-4.2", 1);
-	PyObject *arg2 = executeFunction(in, "portage", "pkgsplit", "sI", "app-portage/kuroo4-4.1", 1);
-	PyObject *ret = executeFunction(in, "portage", "pkgcmp", "OO", arg1, arg2);
+	//TODO:Py_DECREF me !
 
-	if (!ret)
-		printf("failed :-( \n");
-	else
-		printf("Return %ld\n", PyLong_AsLong(ret));
+	return PyBytes_AsString(name);
+}
+
+const char *overlayOwnerEmail(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *ret = PyObject_GetAttrString(o->object, "owner_email");
+
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(ret);
+}
+
+int overlayPriority(Overlay *o)
+{
+	if (!o || !o->object)
+		return -1;
+
+	PyObject *prio = PyObject_GetAttrString(o->object, "priority");
+
+	//TODO:Py_DECREF me !
+
+	return (int) PyLong_AsLong(prio);
+}
+
+const char *overlayDescription(Overlay *o)
+{
+	if (!o || !o->object)
+		return NULL;
+
+	PyObject *desc = PyObject_GetAttrString(o->object, "description");
 
-	Py_DECREF(ret);
-	Py_DECREF(arg1);
-	Py_DECREF(arg2);
+	//TODO:Py_DECREF me !
+
+	return PyBytes_AsString(desc);
+}
+
+int overlayIsOfficial(Overlay *o)
+{
+	if (!o || !o->object)
+		return -1;
+
+	PyObject *iso = PyObject_CallMethod(o->object, "is_official", NULL);
+
+	//TODO:Py_DECREF me !
+
+	return (int) PyLong_AsLong(iso);
+}
+
+int main(int argc, char *argv[])
+{
+	in = createInterpreter();
+	
+	Overlay *o = createOverlay("<overlay type='svn' src='https://overlays.gentoo.org/svn/dev/wrobel' contact='nobody@gentoo.org' name='wrobel' status='official' priorit='10'><description>Test</description></overlay>", "", 1, 0);
+
+	if (!o)
+	{
+		printf("Error creating overlay.\n");
+		return 0;
+	}
 	
-	PyObject *tbz = executeFunction(in, "portage.output", "ProgressBar", "sIs", "titre", 100, "status");
-	ret = PyObject_CallMethod(tbz, "inc", "I", 25);
-	Py_DECREF(tbz);
-	Py_DECREF(ret);
+	printf("Overlay name = %s, owner email : %s, description : %s, priority : %d, it is %sofficial.\n", overlayName(o), overlayOwnerEmail(o), overlayDescription(o), overlayPriority(o), overlayIsOfficial(o) ? "" : "not ");
 
 	freeInterpreter(in);
 



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     605ef77a507f23ef3e18072ae40870abb56f3364
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Mon Jul  5 08:39:49 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Jul  5 08:39:49 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=605ef77a

Base runner, not working yet.

---
 src/pkBackend.py | 1889 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/runner.c     |   93 +++
 src/runner.h     |    6 +
 src/test.py      |   15 +
 4 files changed, 2003 insertions(+), 0 deletions(-)

diff --git a/src/pkBackend.py b/src/pkBackend.py
new file mode 100755
index 0000000..3ec1d2d
--- /dev/null
+++ b/src/pkBackend.py
@@ -0,0 +1,1889 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# vim:set shiftwidth=4 tabstop=4 expandtab:
+#
+# Copyright (C) 2009 Mounir Lamouri (volkmar) <mounir.lamouri@gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# packagekit imports
+from packagekit.backend import *
+from packagekit.progress import *
+from packagekit.package import PackagekitPackage
+
+# portage imports
+import portage
+import portage.versions
+import portage.dep
+import _emerge.actions
+import _emerge.stdout_spinner
+import _emerge.create_depgraph_params
+import _emerge.AtomArg
+
+# layman imports
+import layman.db
+import layman.config
+
+# misc imports
+import sys
+import signal
+import re
+from itertools import izip
+
+# NOTES:
+#
+# Package IDs description:
+# CAT/PN;PV;KEYWORD;[REPOSITORY|installed]
+# Last field must be "installed" if installed. Otherwise it's the repo name
+#
+# Naming convention:
+# cpv: category package version, the standard representation of what packagekit
+#   names a package (an ebuild for portage)
+
+# TODO:
+# remove percentage(None) if percentage is used
+# protection against signal when installing/removing
+
+# Map Gentoo categories to the PackageKit group name space
+class PortagePackageGroups(dict):
+    """
+    Portage Package categories group representation
+    """
+    def __init__(self):
+        dict.__init__(self)
+
+        data = {
+            'accessibility': {
+                'name': "Accessibility",
+                'description': "Accessibility applications",
+                'categories': ['app-accessibility'],
+            },
+            'office': {
+                'name': "Office",
+                'description': "Applications used in office environments",
+                'categories': ['app-office', 'app-pda', 'app-mobilephone',
+                    'app-cdr', 'app-antivirus', 'app-laptop', 'mail-',
+                ],
+            },
+            'development': {
+                'name': "Development",
+                'description': "Applications or system libraries",
+                'categories': ['dev-', 'sys-devel'],
+            },
+            'system': {
+                'name': "System",
+                'description': "System applications or libraries",
+                'categories': ['sys-'],
+            },
+            'games': {
+                'name': "Games",
+                'description': "Games, enjoy your spare time",
+                'categories': ['games-'],
+            },
+            'gnome': {
+                'name': "GNOME Desktop",
+                'description': \
+                    "Applications and libraries for the GNOME Desktop",
+                'categories': ['gnome-'],
+            },
+            'kde': {
+                'name': "KDE Desktop",
+                'description': \
+                    "Applications and libraries for the KDE Desktop",
+                'categories': ['kde-'],
+            },
+            'xfce': {
+                'name': "XFCE Desktop",
+                'description': \
+                    "Applications and libraries for the XFCE Desktop",
+                'categories': ['xfce-'],
+            },
+            'lxde': {
+                'name': "LXDE Desktop",
+                'description': \
+                    "Applications and libraries for the LXDE Desktop",
+                'categories': ['lxde-'],
+            },
+            'multimedia': {
+                'name': "Multimedia",
+                'description': \
+                    "Applications and libraries for Multimedia",
+                'categories': ['media-'],
+            },
+            'networking': {
+                'name': "Networking",
+                'description': \
+                    "Applications and libraries for Networking",
+                'categories': ['net-', 'www-'],
+            },
+            'science': {
+                'name': "Science",
+                'description': \
+                    "Scientific applications and libraries",
+                'categories': ['sci-'],
+            },
+            'security': {
+                'name': "Security",
+                'description': \
+                    "Security orientend applications",
+                'categories': ['app-antivirus', 'net-analyzer', 'net-firewall'],
+            },
+            'x11': {
+                'name': "X11",
+                'description': \
+                    "Applications and libraries for X11",
+                'categories': ['x11-'],
+            },
+        }
+
+        self.update(data)
+
+
+class PortageBridge():
+    '''
+    Bridge to portage/emerge settings and variabales to help using them
+    and be sure they are always up-to-date.
+    '''
+
+    def __init__(self):
+        self.settings = None
+        self.trees = None
+        self.mtimedb = None
+        self.vardb = None
+        self.portdb = None
+        self.root_config = None
+
+        self.update()
+
+    def update(self):
+        self.settings, self.trees, self.mtimedb = \
+                _emerge.actions.load_emerge_config()
+        self.vardb = self.trees[self.settings['ROOT']]['vartree'].dbapi
+        self.portdb = self.trees[self.settings['ROOT']]['porttree'].dbapi
+        self.root_config = self.trees[self.settings['ROOT']]['root_config']
+
+        # doing all the changes to settings
+        self.settings.unlock()
+
+        # we don't want interactive ebuilds
+        self.settings["ACCEPT_PROPERTIES"] = "-interactive"
+        self.settings.backup_changes("ACCEPT_PROPERTIES")
+
+        # do not log with mod_echo (cleanly prevent some outputs)
+        def filter_echo(x): return x != 'echo'
+        elogs = self.settings["PORTAGE_ELOG_SYSTEM"].split()
+        elogs = filter(filter_echo, elogs)
+        self.settings["PORTAGE_ELOG_SYSTEM"] = ' '.join(elogs)
+        self.settings.backup_changes("PORTAGE_ELOG_SYSTEM")
+
+        # finally, regenerate settings and lock them again
+        self.settings.regenerate()
+        self.settings.lock()
+
+
+class PackageKitPortageMixin(object):
+
+    def __init__(self):
+        object.__init__(self)
+
+        self.pvar = PortageBridge()
+        # TODO: should be removed when using non-verbose function API
+        # FIXME: avoid using /dev/null, dangerous (ro fs)
+        self._dev_null = open('/dev/null', 'w')
+        # TODO: atm, this stack keep tracks of elog messages
+        self._elog_messages = []
+        self._error_message = ""
+        self._error_phase = ""
+
+    # TODO: should be removed when using non-verbose function API
+    def _block_output(self):
+        sys.stdout = self._dev_null
+        sys.stderr = self._dev_null
+
+    # TODO: should be removed when using non-verbose function API
+    def _unblock_output(self):
+        sys.stdout = sys.__stdout__
+        sys.stderr = sys.__stderr__
+
+    def _is_repo_enabled(self, layman_db, repo_name):
+        if repo_name in layman_db.overlays.keys():
+            return True
+        return False
+
+    def _get_search_list(self, keys_list):
+        '''
+        Get a string composed of keys (separated with spaces).
+        Returns a list of compiled regular expressions.
+        '''
+        search_list = []
+
+        for k in keys_list:
+            # not done entirely by pk-transaction
+            k = re.escape(k)
+            search_list.append(re.compile(k, re.IGNORECASE))
+
+        return search_list
+
+    def _get_portage_categories(self):
+        """
+        Return a list of available Portage categories
+        """
+        return self.pvar.settings.categories
+
+    def _get_portage_category_description(self, category):
+
+        from xml.dom import minidom
+        data = {}
+        portdir = self.pvar.settings['PORTDIR']
+        myfile = os.path.join(portdir, category, "metadata.xml")
+        if os.access(myfile, os.R_OK) and os.path.isfile(myfile):
+            doc = minidom.parse(myfile)
+            longdescs = doc.getElementsByTagName("longdescription")
+            for longdesc in longdescs:
+                data[longdesc.getAttribute("lang").strip()] = \
+                    ' '.join([x.strip() for x in \
+                        longdesc.firstChild.data.strip().split("\n")])
+
+        # Only return in plain English since Portage doesn't support i18n/l10n
+        return data.get('en', "No description")
+
+    def _get_portage_groups(self):
+        """
+        Return an expanded version of PortagePackageGroups
+        """
+        groups = PortagePackageGroups()
+        categories = self._get_portage_categories()
+
+        # expand categories
+        for data in list(groups.values()):
+
+            exp_cats = set()
+            for g_cat in data['categories']:
+                exp_cats.update([x for x in categories if x.startswith(g_cat)])
+            data['categories'] = sorted(exp_cats)
+
+        return groups
+
+    def _get_pk_group(self, cp):
+        """
+        Return PackageKit group belonging to given Portage package.
+        """
+        category = portage.versions.catsplit(cp)[0]
+        group_data = [key for key, data in self._get_portage_groups().items() \
+            if category in data['categories']]
+        try:
+            generic_group_name = group_data.pop(0)
+        except IndexError:
+            return GROUP_UNKNOWN
+
+        return PackageKitPortageBackend.GROUP_MAP[generic_group_name]
+
+    def _get_portage_group(self, pk_group):
+        """
+        Given a PackageKit group identifier, return Portage packages group.
+        """
+        group_map = PackageKitPortageBackend.GROUP_MAP
+        # reverse dict
+        group_map_reverse = dict((y, x) for x, y in group_map.items())
+        return group_map_reverse.get(pk_group, 'unknown')
+
+    def _get_ebuild_settings(self, cpv, metadata):
+        """
+        Return values of given metadata keys for given Portage CPV.
+        """
+        settings = portage.config(clone=self.pvar.settings)
+        settings.setcpv(cpv, mydb=metadata)
+        return settings
+
+    def _is_installed(self, cpv):
+        if self.pvar.vardb.cpv_exists(cpv):
+            return True
+        return False
+
+    def _is_cpv_valid(self, cpv):
+        if self._is_installed(cpv):
+            # actually if is_installed return True that means cpv is in db
+            return True
+        elif self.pvar.portdb.cpv_exists(cpv):
+            return True
+
+        return False
+
+    def _get_real_license_str(self, cpv, metadata):
+        # use conditionals info (w/ USE) in LICENSE and remove ||
+        ebuild_settings = self._get_ebuild_settings(cpv, metadata)
+        license = set(portage.flatten(portage.dep.use_reduce(
+            portage.dep.paren_reduce(metadata["LICENSE"]),
+            uselist=ebuild_settings.get("USE", "").split())))
+        license.discard('||')
+        license = ' '.join(license)
+
+        return license
+
+    def _signal_config_update(self):
+        result = list(portage.util.find_updated_config_files(
+            self.pvar.settings['ROOT'],
+            self.pvar.settings.get('CONFIG_PROTECT', '').split()))
+
+        if result:
+            message = "Some configuration files need updating."
+            message += ";You should use Gentoo's tools to update them (dispatch-conf)"
+            message += ";If you can't do that, ask your system administrator."
+            self.message(MESSAGE_CONFIG_FILES_CHANGED, message)
+
+    def _get_restricted_fetch_files(self, cpv, metadata):
+        '''
+        This function checks files in SRC_URI and look if they are in DESTDIR.
+        Missing files are returned. If there is no issue, None is returned.
+        We don't care about digest but only about existance of files.
+
+        NOTES:
+        - we are assuming the package has RESTRICT='fetch'
+          be sure to call this function only in this case.
+        - we are not using fetch_check because it's not returning missing files
+          so this function is a simplist fetch_check
+        '''
+        missing_files = []
+        ebuild_settings = self._get_ebuild_settings(cpv, metadata)
+
+        files = self.pvar.portdb.getFetchMap(cpv,
+                ebuild_settings['USE'].split())
+
+        for f in files:
+            file_path = os.path.join(ebuild_settings["DISTDIR"], f)
+            if not os.access(file_path, os.F_OK):
+                missing_files.append([file_path, files[f]])
+
+        if len(missing_files) > 0:
+            return missing_files
+
+        return None
+
+    def _check_fetch_restrict(self, packages_list):
+        for p in packages_list:
+            if 'fetch' in p.metadata['RESTRICT']:
+                files = self._get_restricted_fetch_files(p.cpv, p.metadata)
+                if files:
+                    message = "Package %s can't download some files." % p.cpv
+                    message += ";Please, download manually the followonig file(s):"
+                    for x in files:
+                        message += ";- %s then copy it to %s" % (' '.join(x[1]), x[0])
+                    self.error(ERROR_RESTRICTED_DOWNLOAD, message)
+
+    def _elog_listener(self, settings, key, logentries, fulltext):
+        '''
+        This is a listener for elog.
+        It's called each time elog is emitting log messages (at end of process).
+        We are not using settings and fulltext but they are used by other
+        listeners so we have to keep them as arguments.
+        '''
+        message = "Messages for package %s:;" % str(key)
+        error_message = ""
+
+        # building the message
+        for phase in logentries:
+            for entries in logentries[phase]:
+                type = entries[0]
+                messages = entries[1]
+
+                # TODO: portage.elog.filtering is using upper() should we ?
+                if type == 'LOG':
+                    message += ";Information messages:"
+                elif type == 'WARN':
+                    message += ";Warning messages:"
+                elif type == 'QA':
+                    message += ";QA messages:"
+                elif type == 'ERROR':
+                    message += ";Error messages:"
+                    self._error_phase = phase
+                else:
+                    continue
+
+                for msg in messages:
+                    msg = msg.replace('\n', '')
+                    if type == 'ERROR':
+                        error_message += msg + ";"
+                    message += "; " + msg
+
+        # add the message to the stack
+        self._elog_messages.append(message)
+        self._error_message = message
+
+    def _send_merge_error(self, default):
+        # EAPI-2 compliant (at least)
+        # 'other' phase is ignored except this one, every phase should be there
+        if self._error_phase in ("setup", "unpack", "prepare", "configure",
+            "nofetch", "config", "info"):
+            error_type = ERROR_PACKAGE_FAILED_TO_CONFIGURE
+        elif self._error_phase in ("compile", "test"):
+            error_type = ERROR_PACKAGE_FAILED_TO_BUILD
+        elif self._error_phase in ("install", "preinst", "postinst",
+            "package"):
+            error_type = ERROR_PACKAGE_FAILED_TO_INSTALL
+        elif self._error_phase in ("prerm", "postrm"):
+            error_type = ERROR_PACKAGE_FAILED_TO_REMOVE
+        else:
+            error_type = default
+
+        self.error(error_type, self._error_message)
+
+    def _get_file_list(self, cpv):
+        cat, pv = portage.versions.catsplit(cpv)
+        db = portage.dblink(cat, pv, self.pvar.settings['ROOT'],
+                self.pvar.settings, treetype="vartree",
+                vartree=self.pvar.vardb)
+
+        contents = db.getcontents()
+        if not contents:
+            return []
+
+        return db.getcontents().keys()
+
+    def _cmp_cpv(self, cpv1, cpv2):
+        '''
+        returns 1 if cpv1 > cpv2
+        returns 0 if cpv1 = cpv2
+        returns -1 if cpv1 < cpv2
+        '''
+        return portage.versions.pkgcmp(portage.versions.pkgsplit(cpv1),
+            portage.versions.pkgsplit(cpv2))
+
+    def _get_newest_cpv(self, cpv_list, installed):
+        newer = ""
+
+        # get the first cpv following the installed rule
+        for cpv in cpv_list:
+            if self._is_installed(cpv) == installed:
+                newer = cpv
+                break
+
+        if newer == "":
+            return ""
+
+        for cpv in cpv_list:
+            if self._is_installed(cpv) == installed:
+                if self._cmp_cpv(cpv, newer) == 1:
+                    newer = cpv
+
+        return newer
+
+    def _get_metadata(self, cpv, keys, in_dict = False, add_cache_keys = False):
+        '''
+        This function returns required metadata.
+        If in_dict is True, metadata is returned in a dict object.
+        If add_cache_keys is True, cached keys are added to keys in parameter.
+        '''
+        if self._is_installed(cpv):
+            aux_get = self.pvar.vardb.aux_get
+            if add_cache_keys:
+                keys.extend(list(self.pvar.vardb._aux_cache_keys))
+        else:
+            aux_get = self.pvar.portdb.aux_get
+            if add_cache_keys:
+                keys.extend(list(self.pvar.portdb._aux_cache_keys))
+
+        if in_dict:
+            return dict(izip(keys, aux_get(cpv, keys)))
+        else:
+            return aux_get(cpv, keys)
+
+    def _get_size(self, cpv):
+        '''
+        Returns the installed size if the package is installed.
+        Otherwise, the size of files needed to be downloaded.
+        If some required files have been downloaded,
+        only the remaining size will be considered.
+        '''
+        size = 0
+        if self._is_installed(cpv):
+            size = self._get_metadata(cpv, ["SIZE"])[0]
+            if size == '':
+                size = 0
+            else:
+                size = int(size)
+        else:
+            self
+            metadata = self._get_metadata(cpv, ["IUSE", "SLOT"], in_dict=True)
+
+            package = _emerge.Package.Package(
+                    type_name="ebuild",
+                    built=False,
+                    installed=False,
+                    root_config=self.pvar.root_config,
+                    cpv=cpv,
+                    metadata=metadata)
+
+            fetch_file = self.pvar.portdb.getfetchsizes(package[2],
+                    package.use.enabled)
+            for f in fetch_file:
+                size += fetch_file[f]
+
+        return size
+
+    def _get_cpv_slotted(self, cpv_list):
+        cpv_dict = {}
+
+        for cpv in cpv_list:
+            slot = self._get_metadata(cpv, ["SLOT"])[0]
+            if slot not in cpv_dict:
+                cpv_dict[slot] = [cpv]
+            else:
+                cpv_dict[slot].append(cpv)
+
+        return cpv_dict
+
+    def _filter_free(self, cpv_list, fltlist):
+        if not cpv_list:
+            return cpv_list
+
+        def _has_validLicense(cpv):
+            metadata = self._get_metadata(cpv, ["LICENSE", "USE", "SLOT"], True)
+            return not self.pvar.settings._getMissingLicenses(cpv, metadata)
+
+        if FILTER_FREE in fltlist or FILTER_NOT_FREE in fltlist:
+            free_licenses = "@FSF-APPROVED"
+            if FILTER_FREE in fltlist:
+                licenses = "-* " + free_licenses
+            elif FILTER_NOT_FREE in fltlist:
+                licenses = "* -" + free_licenses
+            backup_license = self.pvar.settings["ACCEPT_LICENSE"]
+
+            self.pvar.settings.unlock()
+            self.pvar.settings["ACCEPT_LICENSE"] = licenses
+            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
+            self.pvar.settings.regenerate()
+
+            cpv_list = filter(_has_validLicense, cpv_list)
+
+            self.pvar.settings["ACCEPT_LICENSE"] = backup_license
+            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
+            self.pvar.settings.regenerate()
+            self.pvar.settings.lock()
+
+        return cpv_list
+
+    def _filter_newest(self, cpv_list, fltlist):
+        if len(cpv_list) == 0:
+            return cpv_list
+
+        if FILTER_NEWEST not in fltlist:
+            return cpv_list
+
+        if FILTER_INSTALLED in fltlist:
+            # we have one package per slot, so it's the newest
+            return cpv_list
+
+        cpv_dict = self._get_cpv_slotted(cpv_list)
+
+        # slots are sorted (dict), revert them to have newest slots first
+        slots = cpv_dict.keys()
+        slots.reverse()
+
+        # empty cpv_list, cpv are now in cpv_dict and cpv_list gonna be repop
+        cpv_list = []
+
+        for k in slots:
+            # if not_intalled on, no need to check for newest installed
+            if FILTER_NOT_INSTALLED not in fltlist:
+                newest_installed = self._get_newest_cpv(cpv_dict[k], True)
+                if newest_installed != "":
+                    cpv_list.append(newest_installed)
+            newest_available = self._get_newest_cpv(cpv_dict[k], False)
+            if newest_available != "":
+                cpv_list.append(newest_available)
+
+        return cpv_list
+
+    def _get_all_cp(self, fltlist):
+        # NOTES:
+        # returns a list of cp
+        #
+        # FILTERS:
+        # - installed: ok
+        # - free: ok (should be done with cpv)
+        # - newest: ok (should be finished with cpv)
+        cp_list = []
+
+        if FILTER_INSTALLED in fltlist:
+            cp_list = self.pvar.vardb.cp_all()
+        elif FILTER_NOT_INSTALLED in fltlist:
+            cp_list = self.pvar.portdb.cp_all()
+        else:
+            # need installed packages first
+            cp_list = self.pvar.vardb.cp_all()
+            for cp in self.pvar.portdb.cp_all():
+                if cp not in cp_list:
+                    cp_list.append(cp)
+
+        return cp_list
+
+    def _get_all_cpv(self, cp, fltlist, filter_newest=True):
+        # NOTES:
+        # returns a list of cpv
+        #
+        # FILTERS:
+        # - installed: ok
+        # - free: ok
+        # - newest: ok
+
+        cpv_list = []
+
+        # populate cpv_list taking care of installed filter
+        if FILTER_INSTALLED in fltlist:
+            cpv_list = self.pvar.vardb.match(cp)
+        elif FILTER_NOT_INSTALLED in fltlist:
+            for cpv in self.pvar.portdb.match(cp):
+                if not self._is_installed(cpv):
+                    cpv_list.append(cpv)
+        else:
+            cpv_list = self.pvar.vardb.match(cp)
+            for cpv in self.pvar.portdb.match(cp):
+                if cpv not in cpv_list:
+                    cpv_list.append(cpv)
+
+        # free filter
+        cpv_list = self._filter_free(cpv_list, fltlist)
+
+        # newest filter
+        if filter_newest:
+            cpv_list = self._filter_newest(cpv_list, fltlist)
+
+        return cpv_list
+
+    def _id_to_cpv(self, pkgid):
+        '''
+        Transform the package id (packagekit) to a cpv (portage)
+        '''
+        ret = split_package_id(pkgid)
+
+        if len(ret) < 4:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                    "The package id %s does not contain 4 fields" % pkgid)
+        if '/' not in ret[0]:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                    "The first field of the package id must contain a category")
+
+        # remove slot info from version field
+        version = ret[1].split(':')[0]
+
+        return ret[0] + "-" + version
+
+    def _cpv_to_id(self, cpv):
+        '''
+        Transform the cpv (portage) to a package id (packagekit)
+        '''
+        package, version, rev = portage.versions.pkgsplit(cpv)
+        pkg_keywords, repo, slot = self._get_metadata(cpv,
+                ["KEYWORDS", "repository", "SLOT"])
+
+        pkg_keywords = pkg_keywords.split()
+        sys_keywords = self.pvar.settings["ACCEPT_KEYWORDS"].split()
+        keywords = []
+
+        for x in sys_keywords:
+            if x in pkg_keywords:
+                keywords.append(x)
+
+        # if no keywords, check in package.keywords
+        if not keywords:
+            key_dict = self.pvar.settings.pkeywordsdict.get(
+                    portage.dep.dep_getkey(cpv))
+            if key_dict:
+                for _, keys in key_dict.iteritems():
+                    for x in keys:
+                        keywords.append(x)
+
+        if not keywords:
+            keywords.append("no keywords")
+            self.message(MESSAGE_UNKNOWN,
+                "No keywords have been found for %s" % cpv)
+
+        # don't want to see -r0
+        if rev != "r0":
+            version = version + "-" + rev
+        # add slot info if slot != 0
+        if slot != '0':
+            version = version + ':' + slot
+
+        # if installed, repo should be 'installed', packagekit rule
+        if self._is_installed(cpv):
+            repo = "installed"
+
+        return get_package_id(package, version, ' '.join(keywords), repo)
+
+    def _get_required_packages(self, cpv_input, recursive):
+        '''
+        Get a list of cpv and recursive parameter.
+        Returns the list of packages required for cpv list.
+        '''
+        packages_list = []
+
+        myopts = {}
+        myopts["--selective"] = True
+        myopts["--deep"] = True
+
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "remove")
+        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
+                self.pvar.trees, myopts, myparams, None)
+
+        # TODO: atm, using FILTER_INSTALLED because it's quicker
+        # and we don't want to manage non-installed packages
+        for cp in self._get_all_cp([FILTER_INSTALLED]):
+            for cpv in self._get_all_cpv(cp, [FILTER_INSTALLED]):
+                depgraph._dynamic_config._dep_stack.append(
+                        _emerge.Dependency.Dependency(
+                            atom=portage.dep.Atom('=' + cpv),
+                            root=self.pvar.settings["ROOT"], parent=None))
+
+        if not depgraph._complete_graph():
+            self.error(ERROR_INTERNAL_ERROR, "Error when generating depgraph")
+            return
+
+        def _add_children_to_list(packages_list, node):
+            for n in depgraph._dynamic_config.digraph.parent_nodes(node):
+                if n not in packages_list \
+                        and not isinstance(n, _emerge.SetArg.SetArg):
+                    packages_list.append(n)
+                    _add_children_to_list(packages_list, n)
+
+        for node in depgraph._dynamic_config.digraph.__iter__():
+            if isinstance(node, _emerge.SetArg.SetArg):
+                continue
+            if node.cpv in cpv_input:
+                if recursive:
+                    _add_children_to_list(packages_list, node)
+                else:
+                    for n in \
+                            depgraph._dynamic_config.digraph.parent_nodes(node):
+                        if not isinstance(n, _emerge.SetArg.SetArg):
+                            packages_list.append(n)
+
+        # remove cpv_input that may be added to the list
+        def filter_cpv_input(x): return x.cpv not in cpv_input
+        return filter(filter_cpv_input, packages_list)
+
+
+class PackageKitPortageBackend(PackageKitPortageMixin, PackageKitPortageBase):
+
+    # Portage <-> PackageKit groups map
+    GROUP_MAP = {
+        'accessibility': GROUP_ACCESSIBILITY,
+        'development': GROUP_PROGRAMMING,
+        'games': GROUP_GAMES,
+        'gnome': GROUP_DESKTOP_GNOME,
+        'kde': GROUP_DESKTOP_KDE,
+        'lxde': GROUP_DESKTOP_OTHER,
+        'multimedia': GROUP_MULTIMEDIA,
+        'networking': GROUP_NETWORK,
+        'office': GROUP_OFFICE,
+        'science': GROUP_SCIENCE,
+        'system': GROUP_SYSTEM,
+        'security': GROUP_SECURITY,
+        'x11': GROUP_OTHER,
+        'xfce': GROUP_DESKTOP_XFCE,
+        'unknown': GROUP_UNKNOWN,
+    }
+
+    def __sigquit(self, signum, frame):
+        raise SystemExit(1)
+
+    def __init__(self, args):
+        signal.signal(signal.SIGQUIT, self.__sigquit)
+        PackageKitPortageMixin.__init__(self)
+        PackageKitBaseBackend.__init__(self, args)
+
+    def _package(self, cpv, info=None):
+        desc = self._get_metadata(cpv, ["DESCRIPTION"])[0]
+        if not info:
+            if self._is_installed(cpv):
+                info = INFO_INSTALLED
+            else:
+                info = INFO_AVAILABLE
+        self.package(self._cpv_to_id(cpv), info, desc)
+
+    def get_categories(self):
+
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+
+        categories = self._get_portage_categories()
+        if not categories:
+            self.error(ERROR_GROUP_LIST_INVALID, "no package categories")
+            return
+
+        for name in categories:
+
+            summary = self._get_portage_category_description(name)
+
+            f_name = "/usr/share/pixmaps/portage/%s.png" % (name,)
+            if os.path.isfile(f_name) and os.access(f_name, os.R_OK):
+                icon = name
+            else:
+                icon = "image-missing"
+
+            cat_id = name # same thing
+            self.category("", cat_id, name, summary, icon)
+
+    def get_depends(self, filters, pkgs, recursive):
+        # TODO: use only myparams ?
+        # TODO: improve error management / info
+
+        # FILTERS:
+        # - installed: ok
+        # - free: ok
+        # - newest: ignored because only one version of a package is installed
+
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        cpv_input = []
+        cpv_list = []
+
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+            cpv_input.append('=' + cpv)
+
+        myopts = {}
+        myopts["--selective"] = True
+        myopts["--deep"] = True
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        depgraph = _emerge.depgraph.depgraph(
+                self.pvar.settings, self.pvar.trees, myopts, myparams, None)
+        retval, fav = depgraph.select_files(cpv_input)
+
+        if not retval:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Wasn't able to get dependency graph")
+            return
+
+        def _add_children_to_list(cpv_list, node):
+            for n in depgraph._dynamic_config.digraph.child_nodes(node):
+                if n not in cpv_list:
+                    cpv_list.append(n)
+                    _add_children_to_list(cpv_list, n)
+
+        for cpv in cpv_input:
+            for r in depgraph._dynamic_config.digraph.root_nodes():
+                # TODO: remove things with @ as first char
+                # TODO: or refuse SetArgs
+                if not isinstance(r, _emerge.AtomArg.AtomArg):
+                    continue
+                if r.atom == cpv:
+                    if recursive:
+                        _add_children_to_list(cpv_list, r)
+                    else:
+                        for n in \
+                                depgraph._dynamic_config.digraph.child_nodes(r):
+                            for c in \
+                                depgraph._dynamic_config.digraph.child_nodes(n):
+                                cpv_list.append(c)
+
+        def _filter_uninstall(cpv):
+            return cpv[3] != 'uninstall'
+        def _filter_installed(cpv):
+            return cpv[0] == 'installed'
+        def _filter_not_installed(cpv):
+            return cpv[0] != 'installed'
+
+        # removing packages going to be uninstalled
+        cpv_list = filter(_filter_uninstall, cpv_list)
+
+        # install filter
+        if FILTER_INSTALLED in fltlist:
+            cpv_list = filter(_filter_installed, cpv_list)
+        if FILTER_NOT_INSTALLED in fltlist:
+            cpv_list = filter(_filter_not_installed, cpv_list)
+
+        # now we can change cpv_list to a real cpv list
+        tmp_list = cpv_list[:]
+        cpv_list = []
+        for x in tmp_list:
+            cpv_list.append(x[2])
+        del tmp_list
+
+        # free filter
+        cpv_list = self._filter_free(cpv_list, fltlist)
+
+        for cpv in cpv_list:
+            # prevent showing input packages
+            if '=' + cpv not in cpv_input:
+                self._package(cpv)
+
+    def get_details(self, pkgs):
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        nb_pkg = float(len(pkgs))
+        pkg_processed = 0.0
+
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            metadata = self._get_metadata(cpv,
+                    ["DESCRIPTION", "HOMEPAGE", "IUSE", "LICENSE", "SLOT"],
+                    in_dict=True)
+            license = self._get_real_license_str(cpv, metadata)
+
+            self.details(self._cpv_to_id(cpv), license,
+                self._get_pk_group(cpv),
+                metadata["DESCRIPTION"], metadata["HOMEPAGE"],
+                self._get_size(cpv))
+
+            pkg_processed += 100.0
+            self.percentage(int(pkg_processed/nb_pkg))
+
+        self.percentage(100)
+
+    def get_files(self, pkgs):
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        nb_pkg = float(len(pkgs))
+        pkg_processed = 0.0
+
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            if not self._is_installed(cpv):
+                self.error(ERROR_CANNOT_GET_FILELIST,
+                        "get-files is only available for installed packages")
+                continue
+
+            files = self._get_file_list(cpv)
+            files = sorted(files)
+            files = ";".join(files)
+
+            self.files(pkg, files)
+
+            pkg_processed += 100.0
+            self.percentage(int(pkg_processed/nb_pkg))
+
+        self.percentage(100)
+
+    def get_packages(self, filters):
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self._get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        for cp in self._get_all_cp(fltlist):
+            for cpv in self._get_all_cpv(cp, fltlist):
+                self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def get_repo_list(self, filters):
+        # NOTES:
+        # use layman API
+        # returns only official and supported repositories
+        # and creates a dummy repo for portage tree
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        # get installed and available dbs
+        installed_layman_db = layman.db.DB(layman.config.Config())
+        available_layman_db = layman.db.RemoteDB(layman.config.Config())
+
+        # 'gentoo' is a dummy repo
+        self.repo_detail('gentoo', 'Gentoo Portage tree', True)
+
+        if FILTER_NOT_DEVELOPMENT not in fltlist:
+            for o in available_layman_db.overlays.keys():
+                if available_layman_db.overlays[o].is_official() \
+                        and available_layman_db.overlays[o].is_supported():
+                    self.repo_detail(o, o,
+                            self._is_repo_enabled(installed_layman_db, o))
+
+    def get_requires(self, filters, pkgs, recursive):
+        # TODO: manage non-installed package
+
+        # FILTERS:
+        # - installed: error atm, see previous TODO
+        # - free: ok
+        # - newest: ignored because only one version of a package is installed
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        cpv_input = []
+        cpv_list = []
+
+        if FILTER_NOT_INSTALLED in fltlist:
+            self.error(ERROR_CANNOT_GET_REQUIRES,
+                    "get-requires returns only installed packages at the moment")
+            return
+
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+            if not self._is_installed(cpv):
+                self.error(ERROR_CANNOT_GET_REQUIRES,
+                        "get-requires is only available for installed packages at the moment")
+                continue
+
+            cpv_input.append(cpv)
+
+        packages_list = self._get_required_packages(cpv_input, recursive)
+
+        # now we can populate cpv_list
+        cpv_list = []
+        for p in packages_list:
+            cpv_list.append(p.cpv)
+        del packages_list
+
+        # free filter
+        cpv_list = self._filter_free(cpv_list, fltlist)
+
+        for cpv in cpv_list:
+            # prevent showing input packages
+            if '=' + cpv not in cpv_input:
+                self._package(cpv)
+
+    def get_update_detail(self, pkgs):
+        # TODO: a lot of informations are missing
+
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        for pkg in pkgs:
+            updates = []
+            obsoletes = ""
+            vendor_url = ""
+            bugzilla_url = ""
+            cve_url = ""
+
+            cpv = self._id_to_cpv(pkg)
+
+            if not self.pvar.portdb.cpv_exists(cpv):
+                self.message(MESSAGE_COULD_NOT_FIND_PACKAGE, "could not find %s" % pkg)
+
+            for cpv in self.pvar.vardb.match(portage.versions.pkgsplit(cpv)[0]):
+                updates.append(cpv)
+            updates = "&".join(updates)
+
+            # temporarily set vendor_url = homepage
+            homepage = self._get_metadata(cpv, ["HOMEPAGE"])[0]
+            vendor_url = homepage
+            issued = ""
+            updated = ""
+
+            self.update_detail(pkg, updates, obsoletes, vendor_url, bugzilla_url,
+                    cve_url, "none", "No update text", "No ChangeLog",
+                    UPDATE_STATE_STABLE, issued, updated)
+
+    def get_updates(self, filters):
+        # NOTES:
+        # because of a lot of things related to Gentoo,
+        # only world and system packages are can be listed as updates
+        # _except_ for security updates
+
+        # UPDATE TYPES:
+        # - blocked: wait for feedbacks
+        # - low: TODO: --newuse
+        # - normal: default
+        # - important: none atm
+        # - security: from @security
+
+        # FILTERS:
+        # - installed: try to update non-installed packages and call me ;)
+        # - free: ok
+        # - newest: ok
+
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        update_candidates = []
+        cpv_updates = {}
+        cpv_downgra = {}
+
+        # get system and world packages
+        for s in ["system", "world"]:
+            set = portage.sets.base.InternalPackageSet(
+                    initial_atoms=self.pvar.root_config.setconfig.getSetAtoms(s))
+            for atom in set:
+                update_candidates.append(atom.cp)
+
+        # check if a candidate can be updated
+        for cp in update_candidates:
+            cpv_list_inst = self.pvar.vardb.match(cp)
+            cpv_list_avai = self.pvar.portdb.match(cp)
+
+            cpv_dict_inst = self._get_cpv_slotted(cpv_list_inst)
+            cpv_dict_avai = self._get_cpv_slotted(cpv_list_avai)
+
+            dict_upda = {}
+            dict_down = {}
+
+            # candidate slots are installed slots
+            slots = cpv_dict_inst.keys()
+            slots.reverse()
+
+            for s in slots:
+                cpv_list_updates = []
+                cpv_inst = cpv_dict_inst[s][0] # only one install per slot
+
+                # the slot can be outdated (not in the tree)
+                if s not in cpv_dict_avai:
+                    break
+
+                tmp_list_avai = cpv_dict_avai[s]
+                tmp_list_avai.reverse()
+
+                for cpv in tmp_list_avai:
+                    if self._cmp_cpv(cpv_inst, cpv) == -1:
+                        cpv_list_updates.append(cpv)
+                    else: # because the list is sorted
+                        break
+
+                # no update for this slot
+                if len(cpv_list_updates) == 0:
+                    if [cpv_inst] == self.pvar.portdb.visible([cpv_inst]):
+                        break # really no update
+                    else:
+                        # that's actually a downgrade or even worst
+                        if len(tmp_list_avai) == 0:
+                            break # this package is not known in the tree...
+                        else:
+                            dict_down[s] = [tmp_list_avai.pop()]
+
+                cpv_list_updates = self._filter_free(cpv_list_updates, fltlist)
+
+                if len(cpv_list_updates) == 0:
+                    break
+
+                if FILTER_NEWEST in fltlist:
+                    best_cpv = portage.versions.best(cpv_list_updates)
+                    cpv_list_updates = [best_cpv]
+
+                dict_upda[s] = cpv_list_updates
+
+            if len(dict_upda) != 0:
+                cpv_updates[cp] = dict_upda
+            if len(dict_down) != 0:
+                cpv_downgra[cp] = dict_down
+
+        # get security updates
+        for atom in portage.sets.base.InternalPackageSet(
+                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("security")):
+            # send update message and remove atom from cpv_updates
+            if atom.cp in cpv_updates:
+                slot = self._get_metadata(atom.cpv, ["SLOT"])[0]
+                if slot in cpv_updates[atom.cp]:
+                    tmp_cpv_list = cpv_updates[atom.cp][slot][:]
+                    for cpv in tmp_cpv_list:
+                        if self._cmp_cpv(cpv, atom.cpv) >= 0:
+                            # cpv is a security update and removed from list
+                            cpv_updates[atom.cp][slot].remove(cpv)
+                            self._package(cpv, INFO_SECURITY)
+            else: # update also non-world and non-system packages if security
+                self._package(atom.cpv, INFO_SECURITY)
+
+        # downgrades
+        for cp in cpv_downgra:
+            for slot in cpv_downgra[cp]:
+                for cpv in cpv_downgra[cp][slot]:
+                    self._package(cpv, INFO_IMPORTANT)
+
+        # normal updates
+        for cp in cpv_updates:
+            for slot in cpv_updates[cp]:
+                for cpv in cpv_updates[cp][slot]:
+                    self._package(cpv, INFO_NORMAL)
+
+    def simulate_install_packages(self, pkgs):
+        return self._install_packages(False, pkgs, simulate=True)
+
+    def install_packages(self, only_trusted, pkgs):
+        return self._install_packages(False, pkgs)
+
+    def _install_packages(self, only_trusted, pkgs, simulate=False):
+        # NOTES:
+        # can't install an already installed packages
+        # even if it happens to be needed in Gentoo but probably not this API
+        # TODO: every merged pkg should emit self.package()
+        #       see around _emerge.Scheduler.Scheduler
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        cpv_list = []
+
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            if self._is_installed(cpv):
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
+                        "Package %s is already installed" % pkg)
+                continue
+
+            cpv_list.append('=' + cpv)
+
+        # only_trusted isn't supported
+        # but better to show it after important errors
+        if only_trusted:
+            self.error(ERROR_MISSING_GPG_SIGNATURE,
+                    "Portage backend does not support GPG signature")
+            return
+
+        # creating installation depgraph
+        myopts = {}
+        favorites = []
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        self.status(STATUS_DEP_RESOLVE)
+
+        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
+                self.pvar.trees, myopts, myparams, None)
+        retval, favorites = depgraph.select_files(cpv_list)
+        if not retval:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Wasn't able to get dependency graph")
+            return
+
+        # check fetch restrict, can stop the function via error signal
+        self._check_fetch_restrict(depgraph.altlist())
+
+        self.status(STATUS_INSTALL)
+
+        if simulate:
+            return
+
+        # get elog messages
+        portage.elog.add_listener(self._elog_listener)
+
+        try:
+            self._block_output()
+            # compiling/installing
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
+                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
+            rval = mergetask.merge()
+        finally:
+            self._unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self._elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+        self._signal_config_update()
+
+    def refresh_cache(self, force):
+        # NOTES: can't manage progress even if it could be better
+        # TODO: do not wait for exception, check timestamp
+        # TODO: message if overlay repo has changed (layman)
+        self.status(STATUS_REFRESH_CACHE)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        myopts = {'--quiet': True}
+
+        # get installed and available dbs
+        installed_layman_db = layman.db.DB(layman.config.Config())
+
+        if force:
+            timestamp_path = os.path.join(
+                    self.pvar.settings["PORTDIR"], "metadata", "timestamp.chk")
+            if os.access(timestamp_path, os.F_OK):
+                os.remove(timestamp_path)
+
+        try:
+            self._block_output()
+            for o in installed_layman_db.overlays.keys():
+                installed_layman_db.sync(o, quiet=True)
+            _emerge.actions.action_sync(self.pvar.settings, self.pvar.trees,
+                    self.pvar.mtimedb, myopts, "")
+        except:
+            self.error(ERROR_INTERNAL_ERROR, traceback.format_exc())
+        finally:
+            self._unblock_output()
+
+    def remove_packages(self, allowdep, autoremove, pkgs):
+        return self._remove_packages(allowdep, autoremove, pkgs)
+
+    def simulate_remove_packages(self, pkgs):
+        return self._remove_packages(True, False, pkgs, simulate=True)
+
+    def _remove_packages(self, allowdep, autoremove, pkgs, simulate=False):
+        # TODO: every to-be-removed pkg should emit self.package()
+        #       see around _emerge.Scheduler.Scheduler
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        cpv_list = []
+        packages = []
+        required_packages = []
+        system_packages = []
+
+        # get system packages
+        set = portage.sets.base.InternalPackageSet(
+                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("system"))
+        for atom in set:
+            system_packages.append(atom.cp)
+
+        # create cpv_list
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            if not self._is_installed(cpv):
+                self.error(ERROR_PACKAGE_NOT_INSTALLED,
+                        "Package %s is not installed" % pkg)
+                continue
+
+            # stop removal if a package is in the system set
+            if portage.versions.pkgsplit(cpv)[0] in system_packages:
+                self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
+                        "Package %s is a system package. If you really want to remove it, please use portage" % pkg)
+                continue
+
+            cpv_list.append(cpv)
+
+        # backend do not implement autoremove
+        if autoremove:
+            self.message(MESSAGE_AUTOREMOVE_IGNORED,
+                    "Portage backend do not implement autoremove option")
+
+        # get packages needing candidates for removal
+        required_packages = self._get_required_packages(cpv_list, recursive=True)
+
+        # if there are required packages, allowdep must be on
+        if required_packages and not allowdep:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Could not perform remove operation has packages are needed by other packages")
+            return
+
+        # first, we add required packages
+        for p in required_packages:
+            package = _emerge.Package.Package(
+                    type_name=p.type_name,
+                    built=p.built,
+                    installed=p.installed,
+                    root_config=p.root_config,
+                    cpv=p.cpv,
+                    metadata=p.metadata,
+                    operation='uninstall')
+            packages.append(package)
+
+        # and now, packages we want really to remove
+        for cpv in cpv_list:
+            metadata = self._get_metadata(cpv, [],
+                    in_dict=True, add_cache_keys=True)
+            package = _emerge.Package.Package(
+                    type_name="ebuild",
+                    built=True,
+                    installed=True,
+                    root_config=self.pvar.root_config,
+                    cpv=cpv,
+                    metadata=metadata,
+                    operation="uninstall")
+            packages.append(package)
+
+        if simulate:
+            return
+
+        # need to define favorites to remove packages from world set
+        favorites = []
+        for p in packages:
+            favorites.append('=' + p.cpv)
+
+        # get elog messages
+        portage.elog.add_listener(self._elog_listener)
+
+        # now, we can remove
+        try:
+            self._block_output()
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, mergelist=packages,
+                    myopts={}, spinner=None, favorites=favorites, digraph=None)
+            rval = mergetask.merge()
+        finally:
+            self._unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_REMOVE)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self._elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+    def repo_enable(self, repoid, enable):
+        # NOTES: use layman API >= 1.2.3
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        # special case: trying to work with gentoo repo
+        if repoid == 'gentoo':
+            if not enable:
+                self.error(ERROR_CANNOT_DISABLE_REPOSITORY,
+                        "gentoo repository can't be disabled")
+            return
+
+        # get installed and available dbs
+        installed_layman_db = layman.db.DB(layman.config.Config())
+        available_layman_db = layman.db.RemoteDB(layman.config.Config())
+
+        # check now for repoid so we don't have to do it after
+        if not repoid in available_layman_db.overlays.keys():
+            self.error(ERROR_REPO_NOT_FOUND,
+                    "Repository %s was not found" % repoid)
+            return
+
+        # disabling (removing) a db
+        # if repository already disabled, ignoring
+        if not enable and self._is_repo_enabled(installed_layman_db, repoid):
+            try:
+                installed_layman_db.delete(installed_layman_db.select(repoid))
+            except Exception, e:
+                self.error(ERROR_INTERNAL_ERROR,
+                        "Failed to disable repository "+repoid+" : "+str(e))
+                return
+
+        # enabling (adding) a db
+        # if repository already enabled, ignoring
+        if enable and not self._is_repo_enabled(installed_layman_db, repoid):
+            try:
+                # TODO: clean the trick to prevent outputs from layman
+                self._block_output()
+                installed_layman_db.add(available_layman_db.select(repoid),
+                        quiet=True)
+                self._unblock_output()
+            except Exception, e:
+                self._unblock_output()
+                self.error(ERROR_INTERNAL_ERROR,
+                        "Failed to enable repository "+repoid+" : "+str(e))
+                return
+
+    def resolve(self, filters, pkgs):
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self._get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        reg_expr = []
+        for pkg in pkgs:
+            reg_expr.append("^" + re.escape(pkg) + "$")
+        reg_expr = "|".join(reg_expr)
+
+        # specifications says "be case sensitive"
+        s = re.compile(reg_expr)
+
+        for cp in cp_list:
+            if s.match(cp):
+                for cpv in self._get_all_cpv(cp, fltlist):
+                    self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def search_details(self, filters, keys):
+        # NOTES: very bad performance
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self._get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+        search_list = self._get_search_list(keys)
+
+        for cp in cp_list:
+            # unfortunatelly, everything is related to cpv, not cp
+            # can't filter cp
+            cpv_list = []
+
+            # newest filter can't be executed now
+            # because some cpv are going to be filtered by search conditions
+            # and newest filter could be alterated
+            for cpv in self._get_all_cpv(cp, fltlist, filter_newest=False):
+                match = True
+                metadata =  self._get_metadata(cpv,
+                        ["DESCRIPTION", "HOMEPAGE", "IUSE",
+                            "LICENSE", "repository", "SLOT"],
+                        in_dict=True)
+                # update LICENSE to correspond to system settings
+                metadata["LICENSE"] = self._get_real_license_str(cpv, metadata)
+                for s in search_list:
+                    found = False
+                    for x in metadata:
+                        if s.search(metadata[x]):
+                            found = True
+                            break
+                    if not found:
+                        match = False
+                        break
+                if match:
+                    cpv_list.append(cpv)
+
+            # newest filter
+            cpv_list = self._filter_newest(cpv_list, fltlist)
+
+            for cpv in cpv_list:
+                self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def search_file(self, filters, key):
+        # FILTERS:
+        # - ~installed is not accepted (error)
+        # - free: ok
+        # - newest: as only installed, by himself
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+
+        if FILTER_NOT_INSTALLED in fltlist:
+            self.error(ERROR_CANNOT_GET_FILELIST,
+                    "search-file isn't available with ~installed filter")
+            return
+
+        cpv_list = self.pvar.vardb.cpv_all()
+        nb_cpv = 0.0
+        cpv_processed = 0.0
+        is_full_path = True
+
+        if key[0] != "/":
+            is_full_path = False
+            key = re.escape(key)
+            searchre = re.compile("/" + key + "$", re.IGNORECASE)
+
+        # free filter
+        cpv_list = self._filter_free(cpv_list, fltlist)
+        nb_cpv = float(len(cpv_list))
+
+        for cpv in cpv_list:
+            for f in self._get_file_list(cpv):
+                if (is_full_path and key == f) \
+                or (not is_full_path and searchre.search(f)):
+                    self._package(cpv)
+                    break
+
+            cpv_processed += 100.0
+            self.percentage(int(cpv_processed/nb_cpv))
+
+        self.percentage(100)
+
+    def search_group(self, filters, groups):
+        # TODO: filter unknown groups before searching ? (optimization)
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self._get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        for cp in cp_list:
+            for group in groups:
+                if self._get_pk_group(cp) == group:
+                    for cpv in self._get_all_cpv(cp, fltlist):
+                        self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def search_name(self, filters, keys_list):
+        # searching for all keys in package name
+        # also filtering by categories if categery is specified in a key
+        # keys contain more than one category name, no results can be found
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        categories = []
+        for k in keys_list[:]:
+            if "/" in k:
+                cat, cp = portage.versions.catsplit(k)
+                categories.append(cat)
+                keys_list[keys_list.index(k)] = cp
+
+        category_filter = None
+        if len(categories) > 1:
+            # nothing will be found because we have two cat/pkg
+            # with a AND operator search
+            return
+        elif len(categories) == 1:
+            category_filter = categories[0]
+
+        # do not use self._get_search_list because of this category feature
+        search_list = []
+        for k in keys_list:
+            # not done entirely by pk-transaction
+            k = re.escape(k)
+            search_list.append(re.compile(k, re.IGNORECASE))
+
+        fltlist = filters.split(';')
+        cp_list = self._get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        for cp in cp_list:
+            if category_filter:
+                cat, pkg_name = portage.versions.catsplit(cp)
+                if cat != category_filter:
+                    continue
+            else:
+                pkg_name = portage.versions.catsplit(cp)[1]
+            found = True
+
+            # pkg name has to correspond to _every_ keys
+            for s in search_list:
+                if not s.search(pkg_name):
+                    found = False
+                    break
+            if found:
+                for cpv in self._get_all_cpv(cp, fltlist):
+                    self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def update_packages(self, only_trusted, pkgs):
+        return self._update_packages(only_trusted, pkgs)
+
+    def simulate_update_packages(self, pkgs):
+        return self._update_packages(False, pkgs, simulate=True)
+
+    def _update_packages(self, only_trusted, pkgs, simulate=False):
+        # TODO: manage errors
+        # TODO: manage config file updates
+        # TODO: every updated pkg should emit self.package()
+        #       see around _emerge.Scheduler.Scheduler
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        cpv_list = []
+
+        for pkg in pkgs:
+            cpv = self._id_to_cpv(pkg)
+
+            if not self._is_cpv_valid(cpv):
+                self.error(ERROR_UPDATE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            cpv_list.append('=' + cpv)
+
+        # only_trusted isn't supported
+        # but better to show it after important errors
+        if only_trusted:
+            self.error(ERROR_MISSING_GPG_SIGNATURE,
+                    "Portage backend does not support GPG signature")
+            return
+
+        # creating update depgraph
+        myopts = {}
+        favorites = []
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        self.status(STATUS_DEP_RESOLVE)
+
+        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
+                self.pvar.trees, myopts, myparams, None)
+        retval, favorites = depgraph.select_files(cpv_list)
+        if not retval:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Wasn't able to get dependency graph")
+            return
+
+        # check fetch restrict, can stop the function via error signal
+        self._check_fetch_restrict(depgraph.altlist())
+
+        self.status(STATUS_INSTALL)
+
+        if simulate:
+            return
+
+        # get elog messages
+        portage.elog.add_listener(self._elog_listener)
+
+        try:
+            self._block_output()
+            # compiling/installing
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
+                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
+            rval = mergetask.merge()
+        finally:
+            self._unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self._elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+        self._signal_config_update()
+
+    def update_system(self, only_trusted):
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        if only_trusted:
+            self.error(ERROR_MISSING_GPG_SIGNATURE,
+                    "Portage backend does not support GPG signature")
+            return
+
+        myopts = {}
+        myopts["--deep"] = True
+        myopts["--newuse"] = True
+        myopts["--update"] = True
+
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        self.status(STATUS_DEP_RESOLVE)
+
+        # creating list of ebuilds needed for the system update
+        # using backtrack_depgraph to prevent errors
+        retval, depgraph, _ = _emerge.depgraph.backtrack_depgraph(
+                self.pvar.settings, self.pvar.trees, myopts, myparams, "",
+                ["@system", "@world"], None)
+        if not retval:
+            self.error(ERROR_INTERNAL_ERROR,
+                    "Wasn't able to get dependency graph")
+            return
+
+        # check fetch restrict, can stop the function via error signal
+        self._check_fetch_restrict(depgraph.altlist())
+
+        self.status(STATUS_INSTALL)
+
+        # get elog messages
+        portage.elog.add_listener(self._elog_listener)
+
+        try:
+            self._block_output()
+            # compiling/installing
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
+                    depgraph.altlist(), None, depgraph.schedulerGraph())
+            rval = mergetask.merge()
+        finally:
+            self._unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self._send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self._elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+        self._signal_config_update()
+
+def main():
+    backend = PackageKitPortageBackend("")
+    backend.dispatcher(sys.argv[1:])
+
+if __name__ == "__main__":
+    main()

diff --git a/src/runner.c b/src/runner.c
new file mode 100644
index 0000000..08433a6
--- /dev/null
+++ b/src/runner.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "runner.h"
+
+void stdoutWritten(char*);
+
+struct Runner {
+	void *writeStdout;
+};
+
+int main(int argc, char* argv[])
+{
+	// Tries to compare 2 packages version.
+	if (argc < 3)
+	{
+		printf("Please provide 2 packages.\n");
+		return -1;
+	}
+
+	char *str = malloc((strlen(argv[1]) + strlen(argv[2]) + 2) * sizeof(char));
+
+	sprintf(str, "%s %s", argv[1], argv[2]);
+
+	Runner *r = createRunner();
+	r->writeStdout = stdoutWritten;
+	int ret = execute(r, str);
+	if (ret < 0)
+		printf("Execution error\n");
+	
+	freeRunner(r);
+
+	return 0;
+}
+
+void stdoutWritten(char *data)
+{
+	printf("From program : %s\n", data);
+}
+
+Runner *createRunner()
+{
+	Runner *ret = malloc(sizeof(Runner));
+	return ret;
+}
+
+int execute(Runner *r, char *args)
+{
+	r = r;
+	int ret = fork();
+	if (ret > 0)
+	{
+		printf("New PID = %d\n", ret);
+		return ret;
+	}
+	
+	//printf("args = %s\n", args);
+	//int fd = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+	int fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (fd < 0) 
+		printf("ERROR opening socket\n");
+	
+	struct sockaddr_in serv_addr;
+
+	memset(&serv_addr, 0, sizeof(serv_addr));
+	int portno = 5555;
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_addr.s_addr = INADDR_ANY;
+	serv_addr.sin_port = htons(portno);
+	if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
+		printf("ERROR on connecting\n");
+	
+	//listen(fd, 5);
+
+	dup2(fd, STDOUT_FILENO);
+	ret = execl("/home/detlev/src/c-portage/src/test.py", "test.py", "app-portage/kuroo4-4.2", "app-portage/kuroo4-4.3", NULL);
+	printf("execl: (%d) %s\n", errno, strerror(errno));
+	return ret;
+}
+
+void freeRunner(Runner *r)
+{
+	free(r);
+}

diff --git a/src/runner.h b/src/runner.h
new file mode 100644
index 0000000..c087895
--- /dev/null
+++ b/src/runner.h
@@ -0,0 +1,6 @@
+
+typedef struct Runner Runner;
+
+Runner *createRunner();
+int execute(Runner*, char*);
+void freeRunner(Runner*);

diff --git a/src/test.py b/src/test.py
new file mode 100755
index 0000000..fadcbdf
--- /dev/null
+++ b/src/test.py
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+# !!!! WARNING !!!!
+# Test file : It's not safe, can break your system and make your life miserable, you've been warned.
+# !!!! WARNING !!!!
+
+from portage import *
+
+ret = pkgcmp(pkgsplit(sys.argv[1]), pkgsplit(sys.argv[2]))
+
+if ret == 0 :
+	print "same"
+elif ret == -1:
+	print "less"
+else:
+	print "more"



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     1fa0da3323562b7bfc74501d4b20a12bdfe5d094
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Mon Jul  5 10:19:47 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Jul  5 10:19:47 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=1fa0da33

Add interpreter version : shorter, more reliable

---
 src/interpreter.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/src/interpreter.c b/src/interpreter.c
new file mode 100644
index 0000000..6ab2843
--- /dev/null
+++ b/src/interpreter.c
@@ -0,0 +1,58 @@
+#include <Python.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+	PyObject *pP1, *pP2, *pArgs, *pName, *pModule, *pDict, *pFunc, *pValue;
+
+	Py_Initialize();
+
+	//printf("%s\n", Py_GetVersion());
+
+	//pName = PyByteArray_FromStringAndSize("portage", strlen("portage"));
+	pModule = PyModule_New("portage");
+
+	pDict = PyModule_GetDict(pModule);
+	pFunc = PyDict_GetItemString(pDict, "pkgcmp");
+
+	if (PyCallable_Check(pFunc)) 
+	{
+		pP1 = PyByteArray_FromStringAndSize("app-portage/kuroo4-4.2", strlen("app-portage/kuroo4-4.2"));
+		pP2 = PyByteArray_FromStringAndSize("app-portage/kuroo4-4.3", strlen("app-portage/kuroo4-4.3"));
+
+		pArgs = PyTuple_New(2);
+
+		PyTuple_SetItem(pArgs, 0, pP1);	
+		PyTuple_SetItem(pArgs, 0, pP2);	
+
+		pValue = PyObject_CallObject(pFunc, pArgs);
+
+		if (pArgs != NULL)
+		{
+			Py_DECREF(pArgs);
+		}
+	}
+	else 
+		PyErr_Print();
+
+	int ret = PyLong_AsLong(pValue);
+	switch(ret)
+	{
+	case -1:
+		printf("less");
+		break;
+	case 0:
+		printf("same");
+		break;
+	case 1:
+		printf("more");
+		break;
+	}
+
+	printf("\n");
+
+	Py_DECREF(pModule);
+
+	Py_Finalize();
+}



^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/layman:master commit in: src/
@ 2011-10-05 20:56 Brian Dolbec
  0 siblings, 0 replies; 27+ messages in thread
From: Brian Dolbec @ 2011-10-05 20:56 UTC (permalink / raw
  To: gentoo-commits

commit:     06a8e3c2fa213dfd59088772d24ae62b81000a50
Author:     Detlev Casanova <detlev.casanova <AT> gmail <DOT> com>
AuthorDate: Mon Jul  5 09:23:47 2010 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Jul  5 09:23:47 2010 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/layman.git;a=commit;h=06a8e3c2

Runner working

---
 src/runner.c |   51 +++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/src/runner.c b/src/runner.c
index 08433a6..ddf20d2 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -33,6 +33,7 @@ int main(int argc, char* argv[])
 	Runner *r = createRunner();
 	r->writeStdout = stdoutWritten;
 	int ret = execute(r, str);
+	
 	if (ret < 0)
 		printf("Execution error\n");
 	
@@ -59,12 +60,43 @@ int execute(Runner *r, char *args)
 	if (ret > 0)
 	{
 		printf("New PID = %d\n", ret);
+		// Listening socket
+		int fd = socket(AF_INET, SOCK_STREAM, 0);
+		if (fd < 0) 
+			printf("ERROR opening socket\n");
+
+		struct sockaddr_in serv_addr;
+
+		memset(&serv_addr, 0, sizeof(serv_addr));
+	
+		int portno = 5555;
+		serv_addr.sin_family = AF_INET;
+		serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+		serv_addr.sin_port = htons(portno);
+	
+		if ((ret = bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0) 
+		{
+			printf("ERROR on binding : %d, %d (%s)\n", ret, errno, strerror(errno));
+			return ret;
+		}
+	
+		if ((ret = listen(fd, 5)) < 0)
+			printf("ERROR on listening : %d, %d (%s)\n", ret, errno, strerror(errno));
+
+		while(1)
+		{
+			unsigned int clilen = sizeof(serv_addr);
+			int newfd = accept(fd, (struct sockaddr *) &serv_addr, &clilen);
+
+			char buf[256];
+			int n = read(newfd, buf, 255);
+			buf[n] = '\0';
+			printf("received : %s\n", buf);
+		}
+
 		return ret;
 	}
 	
-	//printf("args = %s\n", args);
-	//int fd = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
 	int fd = socket(AF_INET, SOCK_STREAM, 0);
 	if (fd < 0) 
 		printf("ERROR opening socket\n");
@@ -72,15 +104,18 @@ int execute(Runner *r, char *args)
 	struct sockaddr_in serv_addr;
 
 	memset(&serv_addr, 0, sizeof(serv_addr));
+	
 	int portno = 5555;
 	serv_addr.sin_family = AF_INET;
-	serv_addr.sin_addr.s_addr = INADDR_ANY;
+	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 	serv_addr.sin_port = htons(portno);
-	if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
-		printf("ERROR on connecting\n");
 	
-	//listen(fd, 5);
-
+	if ((ret = connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0) 
+	{
+		printf("ERROR on connecting : %d, %d (%s)\n", ret, errno, strerror(errno));
+		return ret;
+	}
+	
 	dup2(fd, STDOUT_FILENO);
 	ret = execl("/home/detlev/src/c-portage/src/test.py", "test.py", "app-portage/kuroo4-4.2", "app-portage/kuroo4-4.3", NULL);
 	printf("execl: (%d) %s\n", errno, strerror(errno));



^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2011-10-05 20:59 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-05 20:56 [gentoo-commits] proj/layman:master commit in: src/ Brian Dolbec
  -- strict thread matches above, loose matches on Subject: below --
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec
2011-10-05 20:56 Brian Dolbec

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox