[78944] branches/gsoc11-rev-upgrade/base/src/registry2.0

cal at macports.org cal at macports.org
Fri May 27 13:50:58 PDT 2011


Revision: 78944
          http://trac.macports.org/changeset/78944
Author:   cal at macports.org
Date:     2011-05-27 13:50:57 -0700 (Fri, 27 May 2011)
Log Message:
-----------
rev-upgrade: file and fileobj for registry2.0.

Don't use this, it will compile, but very likely leak memory.

Modified Paths:
--------------
    branches/gsoc11-rev-upgrade/base/src/registry2.0/Makefile
    branches/gsoc11-rev-upgrade/base/src/registry2.0/registry.c
    branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c
    branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h

Added Paths:
-----------
    branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c
    branches/gsoc11-rev-upgrade/base/src/registry2.0/file.h
    branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.c
    branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.h

Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/Makefile
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/Makefile	2011-05-27 19:45:32 UTC (rev 78943)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/Makefile	2011-05-27 20:50:57 UTC (rev 78944)
@@ -3,6 +3,7 @@
 SRCS = registry.tcl registry_autoconf.tcl registry_util.tcl receipt_flat.tcl receipt_sqlite.tcl portimage.tcl portuninstall.tcl
 OBJS = registry.o util.o \
 	entry.o entryobj.o \
+	file.o fileobj.o \
 	../cregistry/cregistry.a
 	#graph.o graphobj.o
 

Added: branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c	                        (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/file.c	2011-05-27 20:50:57 UTC (rev 78944)
@@ -0,0 +1,232 @@
+/*
+ * file.c
+ * $Id$
+ *
+ * Copyright (c) 2007 Chris Pickel <sfiera at macports.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sqlite3.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tcl.h>
+
+#include <cregistry/file.h>
+#include <cregistry/util.h>
+
+#include "file.h"
+#include "fileobj.h"
+#include "registry.h"
+#include "util.h"
+
+/**
+ * Converts a command name into a `reg_file`.
+ *
+ * @param [in] interp  Tcl interpreter to check within
+ * @param [in] name    name of file to get
+ * @param [out] errPtr description of error if the file can't be found
+ * @return             a file, or NULL if one couldn't be found
+ * @see get_object
+ */
+/*static reg_file* get_file(Tcl_Interp* interp, char* name, reg_error* errPtr) {
+    return (reg_file*)get_object(interp, name, "file", file_obj_cmd, errPtr);
+}*/
+
+/**
+ * Removes the file from the Tcl interpreter. Doesn't actually delete it since
+ * that's the registry's job. This is written to be used as the
+ * `Tcl_CmdDeleteProc` for an file object command.
+ *
+ * @param [in] clientData address of a reg_file to remove
+ */
+void delete_file(ClientData clientData) {
+    reg_file* file = (reg_file*)clientData;
+    free(file->proc);
+    free(file->path);
+    file->proc = NULL;
+}
+
+typedef struct {
+    char* name;
+    reg_strategy strategy;
+} strategy_type;
+
+static strategy_type strategies[] = {
+    { "-exact",  reg_strategy_exact },
+    { "-glob",   reg_strategy_glob },
+    { "-regexp", reg_strategy_regexp },
+    { "-null",   reg_strategy_null },
+    { "--",      reg_strategy_exact },
+    { NULL, 0 }
+};
+
+/*
+ * registry::file search ?key value ...?
+ *
+ * Searches the registry for files for which each key's value is equal to the
+ * given value. To find all files, call `file search` with no key-value pairs.
+ * For each key, can be given an option of -exact, -glob, -regexp or -null to
+ * specify the matching strategy; defaults to exact.
+ */
+static int file_search(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
+    int i, j;
+    reg_registry* reg = registry_for(interp, reg_attached);
+    if (reg == NULL) {
+        return TCL_ERROR;
+    } else {
+        char** keys;
+        char** vals;
+        int* strats;
+        int key_count = 0;
+        reg_file** files;
+        reg_error error;
+        int file_count;
+        for (i = 2; i < objc;) {
+            int index, strat_index, val_length;
+            if (Tcl_GetIndexFromObj(interp, objv[i], file_props, "search key",
+                        0, &index) != TCL_OK) {
+                return TCL_ERROR;
+            }
+
+            /* we ate the key value */
+            i++;
+
+            /* check whether there's a strategy */
+            if (Tcl_GetString(objv[i])[0] == '-'
+                    && Tcl_GetIndexFromObjStruct(interp, objv[i], strategies,
+                        sizeof(strategy_type), "option", 0, &strat_index)
+                    != TCL_ERROR) {
+                /* this key has a strategy specified, eat the strategy parameter */
+                i++;
+
+                if (strategies[strat_index].strategy != reg_strategy_null) {
+                    /* this key must also have a value */
+                    i++;
+
+                    if (Tcl_GetStringFromObj(objv[i], &val_length) == NULL
+                            || val_length == 0) {
+                        Tcl_WrongNumArgs(interp, 2, objv,
+                                "search ?key ?options? value ...?");
+                        return TCL_ERROR;
+                    }
+                }
+            } else {
+                /* this key must also have a value */
+                i++;
+
+                if (Tcl_GetStringFromObj(objv[i], &val_length) == NULL
+                        || val_length == 0) {
+                    Tcl_WrongNumArgs(interp, 2, objv,
+                            "search ?key ?options? value ...?");
+                    return TCL_ERROR;
+                }
+            }
+
+            key_count++;
+        }
+
+        keys = malloc(key_count * sizeof(char*));
+        vals = malloc(key_count * sizeof(char*));
+        strats = malloc(key_count * sizeof(int));
+        if (!keys || !vals || !strats) {
+            return TCL_ERROR;
+        }
+        for (i = 2, j = 0; i < objc && j < key_count; j++) {
+            int strat_index;
+
+            keys[j] = Tcl_GetString(objv[i++]);
+
+            /* try to get the strategy */
+            if (Tcl_GetString(objv[i])[0] == '-'
+                    && Tcl_GetIndexFromObjStruct(interp, objv[i], strategies,
+                        sizeof(strategy_type), "option", 0, &strat_index)
+                    != TCL_ERROR) {
+                /* this key has a strategy specified */
+                i++;
+
+                strats[j] = strategies[strat_index].strategy;
+            } else {
+                /* use default strategy */
+                strats[j] = reg_strategy_exact;
+            }
+
+            vals[j] = Tcl_GetString(objv[i++]);
+        }
+        file_count = reg_file_search(reg, keys, vals, strats, key_count,
+                &files, &error);
+        free(keys);
+        free(vals);
+        free(strats);
+        if (file_count >= 0) {
+            int retval;
+            Tcl_Obj* resultObj;
+            Tcl_Obj** objs;
+            if (list_file_to_obj(interp, &objs, files, file_count, &error)){
+                resultObj = Tcl_NewListObj(file_count, objs);
+                Tcl_SetObjResult(interp, resultObj);
+                free(objs);
+                retval = TCL_OK;
+            } else {
+                retval = registry_failed(interp, &error);
+            }
+            free(files);
+            return retval;
+        }
+        return registry_failed(interp, &error);
+    }
+}
+
+typedef struct {
+    char* name;
+    int (*function)(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
+} file_cmd_type;
+
+static file_cmd_type file_cmds[] = {
+    /* Global commands */
+    { "search", file_search },
+    { NULL, NULL }
+};
+
+/*
+ * registry::file cmd ?arg ...?
+ *
+ * Commands manipulating file entries in the registry. This can be called `registry::file`
+ */
+int file_cmd(ClientData clientData UNUSED, Tcl_Interp* interp, int objc,
+        Tcl_Obj* CONST objv[]) {
+    int cmd_index;
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
+        return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObjStruct(interp, objv[1], file_cmds,
+                sizeof(file_cmd_type), "cmd", 0, &cmd_index) == TCL_OK) {
+        file_cmd_type* cmd = &file_cmds[cmd_index];
+        return cmd->function(interp, objc, objv);
+    }
+    return TCL_ERROR;
+}

Added: branches/gsoc11-rev-upgrade/base/src/registry2.0/file.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/file.h	                        (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/file.h	2011-05-27 20:50:57 UTC (rev 78944)
@@ -0,0 +1,44 @@
+/*
+ * file.h
+ * vim:tw=80:expandtab
+ * $Id$
+ *
+ * Copyright (c) 2007 Chris Pickel <sfiera at macports.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _FILE_H
+#define _FILE_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <tcl.h>
+
+void delete_file(ClientData clientData);
+
+int file_cmd(ClientData clientData UNUSED, Tcl_Interp* interp, int objc,
+        Tcl_Obj* CONST objv[]);
+
+#endif /* _FILE_H */
+

Added: branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.c	                        (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.c	2011-05-27 20:50:57 UTC (rev 78944)
@@ -0,0 +1,142 @@
+/*
+ * fileobj.c
+ * vim:tw=80:expandtab
+ * $Id: fileobj.c 64533 2010-03-08 11:50:01Z jmr at macports.org $
+ *
+ * Copyright (c) 2007 Chris Pickel <sfiera at macports.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <tcl.h>
+#include <sqlite3.h>
+
+#include "fileobj.h"
+#include "registry.h"
+#include "util.h"
+
+const char* file_props[] = {
+    "path",
+    "actual_path",
+    "active",
+    "mtime",
+    "md5sum",
+    "editable",
+    "binary",
+    NULL
+};
+
+/* ${file} prop ?value? */
+static int file_obj_prop(Tcl_Interp* interp, reg_file* file, int objc,
+        Tcl_Obj* CONST objv[]) {
+    int index;
+    if (objc > 3) {
+        Tcl_WrongNumArgs(interp, 2, objv, "?value?");
+        return TCL_ERROR;
+    }
+    if (objc == 2) {
+        /* ${file} prop; return the current value */
+        reg_registry* reg = registry_for(interp, reg_attached);
+        if (reg == NULL) {
+            return TCL_ERROR;
+        }
+        if (Tcl_GetIndexFromObj(interp, objv[1], file_props, "prop", 0, &index)
+                == TCL_OK) {
+            char* key = Tcl_GetString(objv[1]);
+            char* value;
+            reg_error error;
+            if (reg_file_propget(file, key, &value, &error)) {
+                Tcl_Obj* result = Tcl_NewStringObj(value, -1);
+                Tcl_SetObjResult(interp, result);
+                free(value);
+                return TCL_OK;
+            }
+            return registry_failed(interp, &error);
+        }
+        return TCL_ERROR;
+    } else {
+        /* ${file} prop name value; set a new value */
+        reg_registry* reg = registry_for(interp, reg_attached);
+        if (reg == NULL) {
+            return TCL_ERROR;
+        }
+        if (Tcl_GetIndexFromObj(interp, objv[1], file_props, "prop", 0, &index)
+                == TCL_OK) {
+            char* key = Tcl_GetString(objv[1]);
+            char* value = Tcl_GetString(objv[2]);
+            reg_error error;
+            if (reg_file_propset(file, key, value, &error)) {
+                return TCL_OK;
+            }
+            return registry_failed(interp, &error);
+        }
+        return TCL_ERROR;
+    }
+}
+
+typedef struct {
+    char* name;
+    int (*function)(Tcl_Interp* interp, reg_file* file, int objc,
+            Tcl_Obj* CONST objv[]);
+} file_obj_cmd_type;
+
+static file_obj_cmd_type file_cmds[] = {
+    /* keys */
+    { "path", file_obj_prop },
+    { "actual_path", file_obj_prop },
+    { "active", file_obj_prop },
+    { "mtime", file_obj_prop },
+    { "md5sum", file_obj_prop },
+    { "editable", file_obj_prop },
+    { "binary", file_obj_prop },
+    { NULL, NULL }
+};
+
+/* ${file} cmd ?arg ...? */
+/* This function implements the command that will be called when a file
+ * created by `registry::file` is used as a procedure. Since all data is kept
+ * in a temporary sqlite3 database that is created for the current interpreter,
+ * none of the sqlite3 functions used have any error checking. That should be a
+ * safe assumption, since nothing outside of registry:: should ever have the
+ * chance to touch it.
+ */
+int file_obj_cmd(ClientData clientData, Tcl_Interp* interp, int objc,
+        Tcl_Obj* CONST objv[]) {
+    int cmd_index;
+    if (objc < 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
+        return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObjStruct(interp, objv[1], file_cmds,
+                sizeof(file_obj_cmd_type), "cmd", 0, &cmd_index) == TCL_OK) {
+        file_obj_cmd_type* cmd = &file_cmds[cmd_index];
+        return cmd->function(interp, (reg_file*)clientData, objc, objv);
+    }
+    return TCL_ERROR;
+}
+

Added: branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.h	                        (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/fileobj.h	2011-05-27 20:50:57 UTC (rev 78944)
@@ -0,0 +1,50 @@
+/*
+ * fileobj.h
+ * vim:tw=80:expandtab
+ * $Id: fileobj.h 27967 2007-08-16 20:14:31Z sfiera at macports.org $
+ *
+ * Copyright (c) 2007 Chris Pickel <sfiera at macports.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _FILE_OBJ_CMD_H
+#define _FILE_OBJ_CMD_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <tcl.h>
+#include <sqlite3.h>
+
+typedef struct {
+    sqlite_int64 rowid;
+    char* path;
+    sqlite3* db;
+} file_t;
+
+extern const char* file_props[];
+
+int file_obj_cmd(ClientData clientData, Tcl_Interp* interp, int objc,
+        Tcl_Obj* CONST objv[]);
+
+#endif /* _FILE_OBJ_CMD_H */

Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/registry.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/registry.c	2011-05-27 19:45:32 UTC (rev 78943)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/registry.c	2011-05-27 20:50:57 UTC (rev 78944)
@@ -38,12 +38,14 @@
 
 #include <cregistry/registry.h>
 #include <cregistry/entry.h>
+#include <cregistry/file.h>
 
-#include "registry.h"
+#include "entry.h"
+#include "entryobj.h"
+#include "file.h"
 #include "graph.h"
 #include "item.h"
-#include "entry.h"
-#include "entryobj.h"
+#include "registry.h"
 #include "util.h"
 
 int registry_failed(Tcl_Interp* interp, reg_error* errPtr) {
@@ -319,6 +321,7 @@
     /* Tcl_CreateObjCommand(interp, "registry::graph", GraphCmd, NULL, NULL); */
     /* Tcl_CreateObjCommand(interp, "registry::item", item_cmd, NULL, NULL); */
     Tcl_CreateObjCommand(interp, "registry::entry", entry_cmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "registry::file", file_cmd, NULL, NULL);
     if (Tcl_PkgProvide(interp, "registry2", "2.0") != TCL_OK) {
         return TCL_ERROR;
     }

Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c	2011-05-27 19:45:32 UTC (rev 78943)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/util.c	2011-05-27 20:50:57 UTC (rev 78944)
@@ -175,18 +175,39 @@
         reg_error* errPtr) {
     if (set_object(interp, name, entry, "entry", entry_obj_cmd, NULL,
                 errPtr)) {
-        int size = strlen(name) + 1;
-        entry->proc = malloc(size*sizeof(char));
+        entry->proc = strdup(name);
         if (!entry->proc) {
             return 0;
         }
-        memcpy(entry->proc, name, size);
         return 1;
     }
     return 0;
 }
 
 /**
+ * Sets a given name to be a file object.
+ *
+ * @param [in] interp  Tcl interpreter to create the file within
+ * @param [in] name    name to associate the given file with
+ * @param [in] file    file to associate with the given name
+ * @param [out] errPtr description of error if it couldn't be set
+ * @return             true if success; false if failure
+ * @see set_object
+ */
+int set_file(Tcl_Interp* interp, char* name, reg_file* file,
+        reg_error* errPtr) {
+    if (set_object(interp, name, file, "file", entry_obj_cmd, NULL,
+                errPtr)) {
+        file->proc = strdup(name);
+        if (!file->proc) {
+            return 0;
+        }
+        return 1;
+    }
+    return 0;
+}
+
+/**
  * Reports a sqlite3 error to Tcl.
  *
  * Queries the database for the most recent error message and sets it as the
@@ -293,12 +314,34 @@
     return 1;
 }
 
+int file_to_obj(Tcl_Interp* interp, Tcl_Obj** obj, reg_file* file,
+        reg_error* errPtr) {
+    if (file->proc == NULL) {
+        char* name = unique_name(interp, "::registry::file");
+        if (!name) {
+            return 0;
+        }
+        if (!set_file(interp, name, file, errPtr)) {
+            free(name);
+            return 0;
+        }
+    }
+    *obj = Tcl_NewStringObj(file->proc, -1);
+    return 1;
+}
+
 int list_entry_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
         reg_entry** entries, int entry_count, reg_error* errPtr) {
     return recast(interp, (cast_function*)entry_to_obj, NULL, (void***)objs,
             (void**)entries, entry_count, errPtr);
 }
 
+int list_file_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
+        reg_file** files, int file_count, reg_error* errPtr) {
+    return recast(interp, (cast_function*)file_to_obj, NULL, (void***)objs,
+            (void**)files, file_count, errPtr);
+}
+
 static int obj_to_string(void* userdata UNUSED, char** string, Tcl_Obj* obj,
         reg_error* errPtr UNUSED) {
     *string = Tcl_GetString(obj);

Modified: branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h	2011-05-27 19:45:32 UTC (rev 78943)
+++ branches/gsoc11-rev-upgrade/base/src/registry2.0/util.h	2011-05-27 20:50:57 UTC (rev 78944)
@@ -37,6 +37,7 @@
 
 #include <cregistry/registry.h>
 #include <cregistry/entry.h>
+#include <cregistry/file.h>
 
 typedef struct {
     char* option;
@@ -56,6 +57,8 @@
         Tcl_ObjCmdProc* proc, Tcl_CmdDeleteProc* deleteProc, reg_error* errPtr);
 int set_entry(Tcl_Interp* interp, char* name, reg_entry* entry,
         reg_error* errPtr);
+int set_file(Tcl_Interp* interp, char* name, reg_file* file,
+		reg_error* errPtr);
 
 void set_sqlite_result(Tcl_Interp* interp, sqlite3* db, const char* query);
 
@@ -73,6 +76,10 @@
         reg_error* errPtr);
 int list_entry_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
         reg_entry** entries, int entry_count, reg_error* errPtr);
+int file_to_obj(Tcl_Interp* interp, Tcl_Obj** ibj, reg_file* file,
+		reg_error* errPtr);
+int list_file_to_obj(Tcl_Interp* interp, Tcl_Obj*** objs,
+		reg_file** files, int file_count, reg_error* errPtr);
 
 void free_strings(void* userdata UNUSED, char** strings, int count);
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110527/15f984b8/attachment-0001.html>


More information about the macports-changes mailing list