[51556] users/toby
toby at macports.org
toby at macports.org
Wed May 27 14:19:42 PDT 2009
Revision: 51556
http://trac.macports.org/changeset/51556
Author: toby at macports.org
Date: 2009-05-27 14:19:42 -0700 (Wed, 27 May 2009)
Log Message:
-----------
sqlite portindex prototype
Added Paths:
-----------
users/toby/sqlite_portindex/
users/toby/sqlite_portindex/portindex.c
Added: users/toby/sqlite_portindex/portindex.c
===================================================================
--- users/toby/sqlite_portindex/portindex.c (rev 0)
+++ users/toby/sqlite_portindex/portindex.c 2009-05-27 21:19:42 UTC (rev 51556)
@@ -0,0 +1,318 @@
+#include <sys/param.h>
+#include <assert.h>
+#include <dirent.h>
+#include <err.h>
+#include <getopt.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sqlite3.h>
+#include <tcl.h>
+
+typedef void (*mport_traverse_callback)(const char *, void *);
+
+void mport_traverse(char *, void *, mport_traverse_callback);
+
+struct index_context {
+ char *directory;
+ Tcl_Interp *interp;
+ sqlite3 *db;
+ sqlite3_stmt *stmt;
+#ifdef LEGACY_PORTINDEX
+ int fd;
+#endif /* LEGACY_PORTINDEX */
+};
+
+static struct index_context *index_context_init(char *directory);
+static void index_context_cleanup(struct index_context *ictx);
+static void usage(void);
+
+static void
+warndb(sqlite3 *db, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ fprintf(stderr, ": %s\n", sqlite3_errmsg(db));
+}
+
+void
+mport_traverse(char *root, void *context, mport_traverse_callback callback)
+{
+ DIR *dir1, *dir2;
+ struct dirent *entry1, *entry2;
+ char *catpath, *portdir;
+
+ dir1 = opendir(root);
+ while ((entry1 = readdir(dir1)) != NULL) {
+ if (!(entry1->d_type & DT_DIR) || entry1->d_name[0] == '.' || entry1->d_name[0] == '_') {
+ continue;
+ }
+ asprintf(&catpath, "%s/%s", root, entry1->d_name);
+ dir2 = opendir(catpath);
+ free(catpath);
+ while ((entry2 = readdir(dir2)) != NULL) {
+ if (!(entry2->d_type & DT_DIR) || entry2->d_name[0] == '.') {
+ continue;
+ }
+ asprintf(&portdir, "%s/%s", entry1->d_name, entry2->d_name);
+ callback(portdir, context);
+ free(portdir);
+ }
+ closedir(dir2);
+ }
+ closedir(dir1);
+}
+
+static void
+insert_info(Tcl_Obj *info, struct index_context *ictx)
+{
+ int status, i, objc;
+ Tcl_Obj **objv;
+ char *col, *val;
+ int bind_index;
+
+ sqlite3_reset(ictx->stmt);
+
+ // xxx: put into db blah
+ status = Tcl_ListObjGetElements(ictx->interp, info, &objc, &objv);
+ assert(status == TCL_OK);
+ assert((objc % 2) == 0);
+
+ for (i = 0; i < objc; i += 2) {
+ asprintf(&col, "@%s", Tcl_GetString(objv[i]));
+ bind_index = sqlite3_bind_parameter_index(ictx->stmt, col);
+ if (bind_index > 0) {
+ val = Tcl_GetString(objv[i + 1]);
+ status = sqlite3_bind_text(ictx->stmt, bind_index, val, -1, SQLITE_TRANSIENT);
+ if (status != SQLITE_OK) {
+ warndb(ictx->db, "sqlite3_bind_text");
+ }
+ }
+ free(col);
+ }
+
+ status = sqlite3_step(ictx->stmt);
+ assert(status == SQLITE_DONE);
+
+#ifdef LEGACY_PORTINDEX
+ // write to file
+#endif /* LEGACY_PORTINDEX */
+}
+
+static void
+pindex(const char *portdir, void *ctx)
+{
+ struct index_context *ictx = (struct index_context *)ctx;
+ char *url;
+ Tcl_Obj *eobjv[2];
+ Tcl_Obj *port;
+ Tcl_Obj *info;
+
+ // set port [mportopen $url]
+ eobjv[0] = Tcl_NewStringObj("mportopen", -1);
+ asprintf(&url, "file://%s/%s", ictx->directory, portdir);
+ eobjv[1] = Tcl_NewStringObj(url, -1);
+ free(url);
+ Tcl_EvalObjv(ictx->interp, 2, eobjv, 0);
+ port = Tcl_GetObjResult(ictx->interp);
+
+ // set info [mportinfo $port]
+ eobjv[0] = Tcl_NewStringObj("mportinfo", -1);
+ eobjv[1] = port;
+ Tcl_EvalObjv(ictx->interp, 2, eobjv, 0);
+ info = Tcl_GetObjResult(ictx->interp);
+
+ insert_info(info, ictx);
+
+ // mportclose $port
+ eobjv[0] = Tcl_NewStringObj("mportclose", -1);
+ eobjv[1] = port;
+ Tcl_EvalObjv(ictx->interp, 2, eobjv, 0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ char directory[MAXPATHLEN];
+ struct index_context *ictx;
+
+ while ((ch = getopt(argc, argv, "")) != -1) {
+ switch (ch) {
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ switch (argc) {
+ case 1:
+ strlcpy(directory, argv[0], sizeof(directory));
+ break;
+ case 0:
+ if (getcwd(directory, sizeof(directory)) == NULL) {
+ err(1, "getcwd");
+ }
+ break;
+ default:
+ usage();
+ }
+
+ ictx = index_context_init(directory);
+ if (ictx == NULL) {
+ exit(1);
+ }
+
+ /* Traverse the directory tree, indexing each port. */
+ mport_traverse(directory, ictx, pindex);
+
+ index_context_cleanup(ictx);
+
+ return 0;
+}
+
+static int
+callback_select(void *ctx __unused, int count, char **values, char **keys)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ printf("%s : %s\n", keys[i], values[i]);
+ }
+
+ return 0;
+}
+
+static void
+create_table(sqlite3 *db)
+{
+ int rc;
+
+ rc = sqlite3_exec(db, "CREATE TABLE portindex ("
+ "categories,"
+ "depends_build,"
+ "depends_lib,"
+ "depends_run,"
+ "description,"
+ "epoch,"
+ "homepage,"
+ "long_description,"
+ "maintainers,"
+ "name,"
+ "platforms,"
+ "portdir,"
+ "revision,"
+ "variants,"
+ "version"
+ ")", NULL, NULL, NULL);
+ if (rc != SQLITE_OK) {
+ warndb(db, "sqlite3_exec");
+ }
+}
+
+static void
+create_stmt(struct index_context *ictx)
+{
+ int status;
+
+ status = sqlite3_prepare_v2(ictx->db, "INSERT INTO portindex VALUES ("
+ "@categories,"
+ "@depends_build,"
+ "@depends_lib,"
+ "@depends_run,"
+ "@description,"
+ "@epoch,"
+ "@homepage,"
+ "@long_description,"
+ "@maintainers,"
+ "@name,"
+ "@platforms,"
+ "@portdir,"
+ "@revision,"
+ "@variants,"
+ "@version"
+ ")", -1, &ictx->stmt, NULL);
+ if (status != SQLITE_OK) {
+ warndb(ictx->db, "sqlite3_prepare_v2");
+ }
+}
+
+static struct index_context *
+index_context_init(char *directory)
+{
+ struct index_context *ictx;
+ int status;
+
+ ictx = calloc(1, sizeof(struct index_context));
+
+ ictx->directory = strdup(directory);
+
+ // XXX: generate temp file...
+ status = sqlite3_open("PortIndex.db", &ictx->db);
+ if (status != SQLITE_OK) {
+ warndb(ictx->db, "sqlite3_open");
+ }
+
+ create_table(ictx->db);
+ create_stmt(ictx);
+
+#ifdef LEGACY_PORTINDEX
+ // open portindex
+#endif /* LEGACY_PORTINDEX */
+
+ ictx->interp = Tcl_CreateInterp();
+ Tcl_Init(ictx->interp);
+ Tcl_EvalFile(ictx->interp, "/Library/Tcl/macports1.0/macports_fastload.tcl");
+ Tcl_PkgRequire(ictx->interp, "macports", "1.0", 0);
+ Tcl_Eval(ictx->interp, "mportinit");
+
+ return ictx;
+}
+
+static void
+index_context_cleanup(struct index_context *ictx)
+{
+ int status;
+
+ Tcl_DeleteInterp(ictx->interp);
+ ictx->interp = NULL;
+
+#ifdef LEGACY_PORTINDEX
+ // close portindex
+#endif /* LEGACY_PORTINDEX */
+
+ // XXX: debugging
+ status = sqlite3_exec(ictx->db, "SELECT * FROM portindex", callback_select, NULL, NULL);
+ if (status != SQLITE_OK) {
+ warndb(ictx->db, "sqlite3_exec");
+ }
+
+ status = sqlite3_finalize(ictx->stmt);
+ if (status != SQLITE_OK) {
+ warndb(ictx->db, "sqlite3_finalize");
+ }
+
+ status = sqlite3_close(ictx->db);
+ if (status != SQLITE_OK) {
+ warndb(ictx->db, "sqlite3_close");
+ }
+
+ free(ictx->directory);
+ ictx->directory = NULL;
+
+ free(ictx);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: portindex [directory]\n");
+ exit(1);
+}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20090527/458eda55/attachment.html>
More information about the macports-changes
mailing list