* [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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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
* [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: 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
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