<pre style='margin:0'>
Clemens Lang (neverpanic) pushed a commit to branch gsoc17-migrate
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/1bb98f2117685378f74bb71421fdddfc176b7ef4">https://github.com/macports/macports-base/commit/1bb98f2117685378f74bb71421fdddfc176b7ef4</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 1bb98f2117685378f74bb71421fdddfc176b7ef4
</span>Author: Umesh Singla <umeshksingla@macports.org>
AuthorDate: Mon Aug 14 22:41:33 2017 +0530

<span style='display:block; white-space:pre;color:#404040;'>    create snapshotobj module with basic registry::snapshot commands
</span>---
 src/cregistry/Makefile.in     |   2 +-
 src/cregistry/registry.c      |   1 +
 src/cregistry/snapshot.h      |   2 +-
 src/pextlib1.0/tracelib.c     |   1 +
 src/registry2.0/Makefile.in   |   3 +-
 src/registry2.0/entry.c       |  54 ---------------
 src/registry2.0/registry.c    |   2 +
 src/registry2.0/registry.h    |   1 +
 src/registry2.0/snapshot.c    | 154 ++++++++++++++++++++++++++++++++++++++++++
 src/registry2.0/snapshotobj.c | 132 ++++++++++++++++++++++++++++++++++++
 src/registry2.0/util.c        |   1 +
 src/registry2.0/util.h        |   1 +
 12 files changed, 297 insertions(+), 57 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/Makefile.in b/src/cregistry/Makefile.in
</span><span style='display:block; white-space:pre;color:#808080;'>index 64aa570..b604609 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2,7 +2,7 @@
</span> srcdir = @srcdir@
 VPATH  = @srcdir@
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-OBJS = registry.o entry.o sql.o vercomp.o util.o file.o portgroup.o
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+OBJS = registry.o entry.o sql.o vercomp.o util.o file.o portgroup.o snapshot.o
</span> STLIB_NAME = cregistry.a
 RANLIB = ranlib
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/registry.c b/src/cregistry/registry.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 8a8b5b3..1fc73f5 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/registry.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/registry.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -33,6 +33,7 @@
</span> 
 #include "portgroup.h"
 #include "entry.h"
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "snapshot.h"
</span> #include "file.h"
 #include "sql.h"
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/snapshot.h b/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;color:#808080;'>index e74824a..30fe8ec 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -42,7 +42,7 @@ typedef struct {
</span> } variant;
 
 typedef struct {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    char* name;g
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    char* name;
</span>     int requested;
     char* state;
     variant* variants;
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/tracelib.c b/src/pextlib1.0/tracelib.c
</span><span style='display:block; white-space:pre;color:#808080;'>index c4390ae..95c427f 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/tracelib.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/tracelib.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -56,6 +56,7 @@
</span> #include <sys/un.h>
 #include <unistd.h>
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <cregistry/snapshot.h>
</span> #include <cregistry/portgroup.h>
 #include <cregistry/entry.h>
 #include <registry2.0/registry.h>
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/Makefile.in b/src/registry2.0/Makefile.in
</span><span style='display:block; white-space:pre;color:#808080;'>index b492755..e78e8e4 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/Makefile.in
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -9,7 +9,8 @@ SRCS = registry.tcl registry_util.tcl receipt_flat.tcl receipt_sqlite.tcl portim
</span> OBJS = registry.o util.o \
        entry.o entryobj.o \
        file.o fileobj.o \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        portgroup.o portgroupobj.o
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   portgroup.o portgroupobj.o \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   snapshot.o snapshotobj.o
</span>   #graph.o graphobj.o
 
 SHLIB_NAME= registry${SHLIB_SUFFIX}
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/entry.c b/src/registry2.0/entry.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 2700945..0647816 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/entry.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/entry.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -477,58 +477,6 @@ static int entry_owner(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span>     }
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-static int create_snapshot(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    printf("inside 2.0 entry\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        Tcl_WrongNumArgs(interp, 2, objv, "create_snapshot ?note?");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        char* note = Tcl_GetString(objv[2]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        reg_error error;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        /* may be a new datatype for snapshot */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        reg_entry* new_snaphot = reg_snapshot_create(reg, note, &error);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if (new_snaphot != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            Tcl_Obj* result;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if (entry_to_obj(interp, &result, new_snaphot, NULL, &error)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                Tcl_SetObjResult(interp, result);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return TCL_OK;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-static int get_snapshot(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    printf("getting snapshot\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        Tcl_WrongNumArgs(interp, 2, objv, "get_snapshot ?snapshot_id?");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        char* id = Tcl_GetString(objv[2]);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        reg_error error;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        reg_snapshot* snapshot;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        int port_count = reg_snapshot_get(reg, id, &snapshot, &error);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if (snapshot != NULL && port_count >= 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            Tcl_Obj* resultObj;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if (entry_to_obj(interp, &resultObj, snapshot, NULL, &error)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                Tcl_SetObjResult(interp, resultObj);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return TCL_OK;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> typedef struct {
     char* name;
     int (*function)(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -545,8 +493,6 @@ static entry_cmd_type entry_cmds[] = {
</span>     { "imaged", entry_imaged },
     { "installed", entry_installed },
     { "owner", entry_owner },
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    { "create_snapshot", create_snapshot},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    { "get_snapshot", get_snapshot},
</span>     { NULL, NULL }
 };
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/registry.c b/src/registry2.0/registry.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 24140e9..a350396 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/registry.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/registry.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -39,6 +39,7 @@
</span> #include <cregistry/registry.h>
 #include <cregistry/portgroup.h>
 #include <cregistry/entry.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <cregistry/snapshot.h>
</span> #include <cregistry/file.h>
 
 #include "entry.h"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -46,6 +47,7 @@
</span> #include "file.h"
 #include "graph.h"
 #include "item.h"
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "snapshot.h"
</span> #include "portgroup.h"
 #include "registry.h"
 #include "util.h"
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/registry.h b/src/registry2.0/registry.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 366cf5b..2dda9d1 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/registry.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/registry.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -35,6 +35,7 @@
</span> #include <sqlite3.h>
 #include <cregistry/portgroup.h>
 #include <cregistry/entry.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <cregistry/snapshot.h>
</span> 
 typedef struct _entry_list {
     reg_entry* entry;
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/snapshot.c b/src/registry2.0/snapshot.c
</span><span style='display:block; white-space:pre;color:#808080;'>index e69de29..e316327 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,154 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * snapshot.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2017 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * are met:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if HAVE_CONFIG_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <config.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <tcl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sqlite3.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <cregistry/util.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "snapshot.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "snapshotobj.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "registry.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "util.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Converts a command name into a `reg_snapshot`.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] interp  Tcl interpreter to check within
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] name    name of snapshot to get
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [out] errPtr description of error if the snapshot can't be found
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @return             an snapshot, or NULL if one couldn't be found
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @see get_object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static reg_snapshot* get_snapshot(Tcl_Interp* interp, char* name, reg_error* errPtr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return (reg_snapshot*)get_object(interp, name, "snapshot", snapshot_obj_cmd, errPtr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Removes the snapshot from the Tcl interpreter. Doesn't actually delete it since
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * that's the registry's job. This is written to be used as the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * `Tcl_CmdDeleteProc` for an snapshot object command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] clientData address of a reg_snapshot to remove
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void delete_snapshot(ClientData clientData) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reg_snapshot* snapshot = (reg_snapshot*)clientData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    free(snapshot->proc);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    snapshot->proc = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int create_snapshot(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("inside 2.0 snapshot\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 2, objv, "create_snapshot ?note?");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        char* note = Tcl_GetString(objv[2]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_error error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        /* may be a new datatype for snapshot */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_entry* new_snaphot = reg_snapshot_create(reg, note, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (new_snaphot != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            Tcl_Obj* result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (entry_to_obj(interp, &result, new_snaphot, NULL, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                Tcl_SetObjResult(interp, result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int get_snapshot(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("getting snapshot\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 2, objv, "get_snapshot ?snapshot_id?");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        char* id = Tcl_GetString(objv[2]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_error error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_snapshot* snapshot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        int port_count = reg_snapshot_get(reg, id, &snapshot, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (snapshot != NULL && port_count >= 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            Tcl_Obj* resultObj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (entry_to_obj(interp, &resultObj, snapshot, NULL, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                Tcl_SetObjResult(interp, resultObj);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    char* name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int (*function)(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} snapshot_cmd_type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static snapshot_cmd_type snapshot_cmds[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Global commands */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { "create", create_snapshot},
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { "get", get_snapshot},
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { NULL, NULL }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * registry::snapshot cmd ?arg ...?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Commands manipulating snapshots in the registry. This could be called
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * `registry::port`, but that could be misleading, because `registry::item`
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * represents ports too, but not those in the registry.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int snapshot_cmd(ClientData clientData UNUSED, Tcl_Interp* interp, int objc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int cmd_index;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc < 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (Tcl_GetIndexFromObjStruct(interp, objv[1], snapshot_cmds,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                sizeof(snapshot_cmd_type), "cmd", 0, &cmd_index) == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        snapshot_cmd_type* cmd = &snapshot_cmds[cmd_index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return cmd->function(interp, objc, objv);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span>\ No newline at end of file
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/snapshotobj.c b/src/registry2.0/snapshotobj.c
</span><span style='display:block; white-space:pre;color:#808080;'>index e69de29..1280dcd 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/snapshotobj.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/snapshotobj.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,132 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * snapshotobj.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2017 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * are met:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if HAVE_CONFIG_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <config.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <tcl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sqlite3.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "snapshotobj.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "registry.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "util.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+const char* snapshot_props[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    "note",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    "ports",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    "created_at",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* ${snapshot} prop ?value? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int snapshot_obj_prop(Tcl_Interp* interp, reg_snapshot* snapshot, int objc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int index;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 2, objv, "?value?");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc == 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        /* ${snapshot} prop; return the current value */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (Tcl_GetIndexFromObj(interp, objv[1], snapshot_props, "prop", 0, &index)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char* key = Tcl_GetString(objv[1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char* value;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            reg_error error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (reg_snapshot_propget(snapshot, key, &value, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                Tcl_Obj* result = Tcl_NewStringObj(value, -1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                Tcl_SetObjResult(interp, result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                free(value);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        /* ${snapshot} prop name value; set a new value */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (Tcl_GetIndexFromObj(interp, objv[1], snapshot_props, "prop", 0, &index)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char* key = Tcl_GetString(objv[1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char* value = Tcl_GetString(objv[2]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            reg_error error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (reg_snapshot_propset(snapshot, key, value, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    char* name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int (*function)(Tcl_Interp* interp, reg_snapshot* snapshot, int objc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            Tcl_Obj* CONST objv[]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} snapshot_obj_cmd_type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static snapshot_obj_cmd_type snapshot_cmds[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* keys */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { "note", snapshot_obj_prop },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { "created_at", snapshot_obj_prop },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* ports */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { "ports", snapshot_obj_ports },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { NULL, NULL }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* ${snapshot} cmd ?arg ...? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* This function implements the command that will be called when a snapshot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * created by `registry::snapshot` is used as a procedure. Since all data is kept
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * in a temporary sqlite3 database that is created for the current interpreter,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * none of the sqlite3 functions used have any error checking. That should be a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * safe assumption, since nothing outside of registry:: should ever have the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * chance to touch it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int snapshot_obj_cmd(ClientData clientData, Tcl_Interp* interp, int objc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int cmd_index;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc < 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (Tcl_GetIndexFromObjStruct(interp, objv[1], snapshot_cmds,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                sizeof(snapshot_obj_cmd_type), "cmd", 0, &cmd_index) == TCL_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        snapshot_obj_cmd_type* cmd = &snapshot_cmds[cmd_index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return cmd->function(interp, (reg_snapshot*)clientData, objc, objv);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span>\ No newline at end of file
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/util.c b/src/registry2.0/util.c
</span><span style='display:block; white-space:pre;color:#808080;'>index c77e285..ba618d8 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/util.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/util.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -36,6 +36,7 @@
</span> 
 #include "util.h"
 #include "entryobj.h"
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "snapshotobj.h"
</span> #include "fileobj.h"
 #include "portgroupobj.h"
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/util.h b/src/registry2.0/util.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 2b07d39..e5f6e60 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/util.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/util.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -37,6 +37,7 @@
</span> 
 #include <cregistry/registry.h>
 #include <cregistry/portgroup.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <cregistry/snapshot.h>
</span> #include <cregistry/entry.h>
 #include <cregistry/file.h>
 
</pre><pre style='margin:0'>

</pre>