[darwinbuild-changes] [16] trunk/darwinxref

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 4 01:37:04 PDT 2006


Revision: 16
          http://trac.macosforge.org/projects/darwinbuild/changeset/16
Author:   kevin
Date:     2006-10-04 01:37:04 -0700 (Wed, 04 Oct 2006)

Log Message:
-----------
- moved DBPlugin structure to private API
- removed session arguments from plugin API
- added support for Tcl plugins

Modified Paths:
--------------
    trunk/darwinxref/DBDataStore.c
    trunk/darwinxref/DBPlugin.c
    trunk/darwinxref/DBPlugin.h

Added Paths:
-----------
    trunk/darwinxref/DBPluginPriv.h
    trunk/darwinxref/DBTclPlugin.c

Modified: trunk/darwinxref/DBDataStore.c
===================================================================
--- trunk/darwinxref/DBDataStore.c	2005-06-17 23:50:10 UTC (rev 15)
+++ trunk/darwinxref/DBDataStore.c	2006-10-04 08:37:04 UTC (rev 16)
@@ -31,26 +31,32 @@
  */
 
 #include "DBPlugin.h"
+#include "DBPluginPriv.h"
 #include "cfutils.h"
 #include "sqlite3.h"
 
-extern const void*  DBGetPluginWithName(CFStringRef);
+//////
+// NOT THREAD SAFE
+// We currently operate under the assumption that there is only
+// one thread, with no plugin re-entrancy.
+//////
+void* __DBDataStore;
+void* _DBPluginGetDataStorePtr() {
+	return __DBDataStore;
+}
 
-int DBBeginTransaction(void* session);
-int DBRollbackTransaction(void* session);
-int DBCommitTransaction(void* session);
 
-
 //////
 //
 // sqlite3 utility functions
 //
 //////
 
-#define __SQL(db, callback, context, fmt) \
+#define __SQL(callback, context, fmt) \
 	va_list args; \
 	char* errmsg; \
 	va_start(args, fmt); \
+	sqlite3* db = _DBPluginGetDataStorePtr(); \
 	char *query = sqlite3_vmprintf(fmt, args); \
 	res = sqlite3_exec(db, query, callback, context, &errmsg); \
 	if (res != SQLITE_OK) { \
@@ -58,15 +64,15 @@
 	} \
 	sqlite3_free(query);
 
-int SQL(sqlite3* db, const char* fmt, ...) {
+int SQL(const char* fmt, ...) {
 	int res;
-	__SQL(db, NULL, NULL, fmt);
+	__SQL(NULL, NULL, fmt);
 	return res;
 }
 
-int SQL_CALLBACK(sqlite3* db, sqlite3_callback callback, void* context, const char* fmt, ...) {
+int SQL_CALLBACK(sqlite3_callback callback, void* context, const char* fmt, ...) {
 	int res;
-	__SQL(db, callback, context, fmt);
+	__SQL(callback, context, fmt);
 	return res;
 }
 
@@ -75,10 +81,10 @@
 	return 0;
 }
 
-int SQL_BOOLEAN(sqlite3* db, const char* fmt, ...) {
+int SQL_BOOLEAN(const char* fmt, ...) {
 	int res;
 	int val = 0;
-	__SQL(db, isTrue, &val, fmt);
+	__SQL(isTrue, &val, fmt);
 	return val;
 }
 
@@ -89,18 +95,18 @@
 	return 0;
 }
 
-char* SQL_STRING(sqlite3* db, const char* fmt, ...) {
+char* SQL_STRING(const char* fmt, ...) {
 	int res;
 	char* str = 0;
-	__SQL(db, getString, &str, fmt);
+	__SQL(getString, &str, fmt);
 	return str;
 }
 
-CFStringRef SQL_CFSTRING(sqlite3* db, const char* fmt, ...) {
+CFStringRef SQL_CFSTRING(const char* fmt, ...) {
 	int res;
 	CFStringRef str = NULL;
 	char* cstr = NULL;
-	__SQL(db, getString, &cstr, fmt);
+	__SQL(getString, &cstr, fmt);
 	str = cfstr(cstr);
 	if (cstr) free(cstr);
 	return str;
@@ -116,10 +122,10 @@
 	return 0;
 }
 
-CFArrayRef SQL_CFARRAY(sqlite3* db, const char* fmt, ...) {
+CFArrayRef SQL_CFARRAY(const char* fmt, ...) {
 	int res;
 	CFMutableArrayRef array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-	__SQL(db, sqlAddStringToArray, array, fmt);
+	__SQL(sqlAddStringToArray, array, fmt);
 	return array;
 }
 
@@ -147,15 +153,16 @@
 	return 0;
 }
 
-CFDictionaryRef SQL_CFDICTIONARY(sqlite3* db, const char* fmt, ...) {
+CFDictionaryRef SQL_CFDICTIONARY(const char* fmt, ...) {
 	int res;
 	CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-	__SQL(db, sqlAddValueToDictionary, dict, fmt);
+	__SQL(sqlAddValueToDictionary, dict, fmt);
 	return dict;
 }
 
-void SQL_NOERR(sqlite3* db, char* sql) {
+void SQL_NOERR(char* sql) {
 	char* errmsg;
+	sqlite3* db = _DBPluginGetDataStorePtr();
 	int res = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
 	if (res != SQLITE_OK && res != SQLITE_ERROR) {
 		fprintf(stderr, "Error: %s (%d)\n", errmsg, res);
@@ -164,20 +171,19 @@
 	}
 }
 
-void* DBDataStoreInitialize(const char* datafile) {
-	sqlite3* db;
-	sqlite3_open(datafile, &db);
-	if (db == NULL) return NULL;
+int DBDataStoreInitialize(const char* datafile) {
+	sqlite3_open(datafile, (sqlite3**)&__DBDataStore);
+	if (__DBDataStore == NULL) return -1;
 
 	char* table = "CREATE TABLE properties (build TEXT, project TEXT, property TEXT, key TEXT, value TEXT)";
 	char* index = "CREATE INDEX properties_index ON properties (build, project, property, key, value)";
-	SQL_NOERR(db, table);
-	SQL_NOERR(db, index);
-
-	return db; 
+	SQL_NOERR(table);
+	SQL_NOERR(index);
+	
+	return 0;
 }
 
-CFArrayRef DBCopyPropNames(void* session, CFStringRef build, CFStringRef project) {
+CFArrayRef DBCopyPropNames(CFStringRef build, CFStringRef project) {
 	char* cbuild = strdup_cfstr(build);
 	char* cproj = strdup_cfstr(project);
 	char* sql;
@@ -186,44 +192,44 @@
 	} else {
 		sql = "SELECT DISTINCT property FROM properties WHERE build=%Q AND project IS NULL ORDER BY property";
 	}
-	CFArrayRef res = SQL_CFARRAY(session, sql, cbuild, cproj);
+	CFArrayRef res = SQL_CFARRAY(sql, cbuild, cproj);
 	free(cbuild);
 	free(cproj);
 	return res;
 }
 
-CFArrayRef DBCopyProjectNames(void* session, CFStringRef build) {
+CFArrayRef DBCopyProjectNames(CFStringRef build) {
 	char* cbuild = strdup_cfstr(build);
-	CFArrayRef res = SQL_CFARRAY(session, "SELECT DISTINCT project FROM properties WHERE build=%Q ORDER BY project", cbuild);
+	CFArrayRef res = SQL_CFARRAY("SELECT DISTINCT project FROM properties WHERE build=%Q ORDER BY project", cbuild);
 	free(cbuild);
 	return res;
 }
 
-CFTypeID  DBCopyPropType(void* session, CFStringRef property) {
+CFTypeID  DBCopyPropType(CFStringRef property) {
 	CFTypeID type = -1;
-	const DBPropertyPlugin* plugin = DBGetPluginWithName(property);
-	if (plugin && plugin->base.type == kDBPluginPropertyType) {
+	const DBPlugin* plugin = DBGetPluginWithName(property);
+	if (plugin && plugin->type == kDBPluginPropertyType) {
 		type = plugin->datatype;
 	}
 	return type;
 }
 
-CFTypeRef DBCopyProp(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
+CFTypeRef DBCopyProp(CFStringRef build, CFStringRef project, CFStringRef property) {
 	CFTypeRef res = NULL;
-	CFTypeID type = DBCopyPropType(session, property);
+	CFTypeID type = DBCopyPropType(property);
 	if (type == -1) return NULL;
 
 	if (type == CFStringGetTypeID()) {
-		res = DBCopyPropString(session, build, project, property);
+		res = DBCopyPropString(build, project, property);
 	} else if (type == CFArrayGetTypeID()) {
-		res = DBCopyPropArray(session, build, project, property);
+		res = DBCopyPropArray(build, project, property);
 	} else if (type == CFDictionaryGetTypeID()) {
-		res = DBCopyPropDictionary(session, build, project, property);
+		res = DBCopyPropDictionary(build, project, property);
 	}
 	return res;
 }
 
-CFStringRef _DBCopyPropString(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
+CFStringRef _DBCopyPropString(CFStringRef build, CFStringRef project, CFStringRef property) {
 	char* cbuild = strdup_cfstr(build);
 	char* cproj = strdup_cfstr(project);
 	char* cprop = strdup_cfstr(property);
@@ -232,14 +238,14 @@
 		sql = "SELECT value FROM properties WHERE property=%Q AND build=%Q AND project=%Q";
 	else
 		sql = "SELECT value FROM properties WHERE property=%Q AND build=%Q AND project IS NULL";
-	CFStringRef res = SQL_CFSTRING(session, sql, cprop, cbuild, cproj);
+	CFStringRef res = SQL_CFSTRING(sql, cprop, cbuild, cproj);
 	free(cproj);
 	free(cprop);
 	free(cbuild);
 	return res;
 }
 
-CFArrayRef _DBCopyPropArray(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
+CFArrayRef _DBCopyPropArray(CFStringRef build, CFStringRef project, CFStringRef property) {
 	char* cbuild = strdup_cfstr(build);
 	char* cproj = strdup_cfstr(project);
 	char* cprop = strdup_cfstr(property);
@@ -248,14 +254,14 @@
 		sql = "SELECT value FROM properties WHERE property=%Q AND build=%Q AND project=%Q ORDER BY key";
 	else
 		sql = "SELECT value FROM properties WHERE property=%Q AND build=%Q AND project IS NULL ORDER BY key";
-	CFArrayRef res = SQL_CFARRAY(session, sql, cprop, cbuild, cproj);
+	CFArrayRef res = SQL_CFARRAY(sql, cprop, cbuild, cproj);
 	free(cproj);
 	free(cprop);
 	free(cbuild);
 	return res;
 }
 
-CFDictionaryRef _DBCopyPropDictionary(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
+CFDictionaryRef _DBCopyPropDictionary(CFStringRef build, CFStringRef project, CFStringRef property) {
 	char* cbuild = strdup_cfstr(build);
 	char* cproj = strdup_cfstr(project);
 	char* cprop = strdup_cfstr(property);
@@ -264,7 +270,7 @@
 		sql = "SELECT DISTINCT key,value FROM properties WHERE property=%Q AND build=%Q AND project=%Q ORDER BY key";
 	else
 		sql = "SELECT DISTINCT key,value FROM properties WHERE property=%Q AND build=%Q AND project IS NULL ORDER BY key";
-	CFDictionaryRef res = SQL_CFDICTIONARY(session, sql, cprop, cbuild, cproj);
+	CFDictionaryRef res = SQL_CFDICTIONARY(sql, cprop, cbuild, cproj);
 	free(cbuild);
 	free(cproj);
 	free(cprop);
@@ -274,8 +280,8 @@
 //
 // Kluge to globally support build aliases ("original") and inheritance ("inherits") properties.
 //
-CFTypeRef _DBCopyPropWithInheritance(void* session, CFStringRef build, CFStringRef project, CFStringRef property,
-	CFTypeRef (*func)(void*, CFStringRef, CFStringRef, CFStringRef)) {
+CFTypeRef _DBCopyPropWithInheritance(CFStringRef build, CFStringRef project, CFStringRef property,
+	CFTypeRef (*func)(CFStringRef, CFStringRef, CFStringRef)) {
 
 	CFTypeRef res = NULL;
 
@@ -288,13 +294,13 @@
 	// if a build alias ("original") is found, break out of the search path
 	// and restart using the original name instead.
 	do {
-		res = func(session, build, project, property);
+		res = func(build, project, property);
 		if (res) break;
 		
-		original = _DBCopyPropString(session, build, project, CFSTR("original"));
+		original = _DBCopyPropString(build, project, CFSTR("original"));
 		if (original) break;
 
-		CFStringRef inherits = _DBCopyPropString(session, build, NULL, CFSTR("inherits"));
+		CFStringRef inherits = _DBCopyPropString(build, NULL, CFSTR("inherits"));
 		if (inherits) CFArrayAppendValue(builds, inherits);
 		build = inherits;
 	} while (build != NULL);
@@ -303,7 +309,7 @@
 		CFIndex i, count = CFArrayGetCount(builds);
 		for (i = 0; i < count; ++i) {
 			build = CFArrayGetValueAtIndex(builds, i);
-			res = func(session, build, original, property);
+			res = func(build, original, property);
 			if (res) break;
 		}
 	}
@@ -313,22 +319,22 @@
 }
 
 
-CFStringRef DBCopyPropString(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
-	return (CFStringRef)_DBCopyPropWithInheritance(session, build, project, property, (void*)_DBCopyPropString);
+CFStringRef DBCopyPropString(CFStringRef build, CFStringRef project, CFStringRef property) {
+	return (CFStringRef)_DBCopyPropWithInheritance(build, project, property, (void*)_DBCopyPropString);
 }
 
-CFArrayRef DBCopyPropArray(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
-	return (CFArrayRef)_DBCopyPropWithInheritance(session, build, project, property, (void*)_DBCopyPropArray);
+CFArrayRef DBCopyPropArray(CFStringRef build, CFStringRef project, CFStringRef property) {
+	return (CFArrayRef)_DBCopyPropWithInheritance(build, project, property, (void*)_DBCopyPropArray);
 }
 
-CFDictionaryRef DBCopyPropDictionary(void* session, CFStringRef build, CFStringRef project, CFStringRef property) {
-	return (CFDictionaryRef)_DBCopyPropWithInheritance(session, build, project, property, (void*)_DBCopyPropDictionary);
+CFDictionaryRef DBCopyPropDictionary(CFStringRef build, CFStringRef project, CFStringRef property) {
+	return (CFDictionaryRef)_DBCopyPropWithInheritance(build, project, property, (void*)_DBCopyPropDictionary);
 }
 
 
-int DBSetProp(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFTypeRef value) {
+int DBSetProp(CFStringRef build, CFStringRef project, CFStringRef property, CFTypeRef value) {
 	int res = 0;
-	CFTypeID type = DBCopyPropType(session, property);
+	CFTypeID type = DBCopyPropType(property);
 	if (type == -1) {
 		cfprintf(stderr, "Error: unknown property in project \"%@\": %@\n", project, property);
 		return -1;
@@ -343,26 +349,26 @@
 	}
 
 	if (type == CFStringGetTypeID()) {
-		res = DBSetPropString(session, build, project, property, value);
+		res = DBSetPropString(build, project, property, value);
 	} else if (type == CFArrayGetTypeID()) {
-		res = DBSetPropArray(session, build, project, property, value);
+		res = DBSetPropArray(build, project, property, value);
 	} else if (type == CFDictionaryGetTypeID()) {
-		res = DBSetPropDictionary(session, build, project, property, value);
+		res = DBSetPropDictionary(build, project, property, value);
 	}
 	return res;
 }
 
-int DBSetPropString(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFStringRef value) {
+int DBSetPropString(CFStringRef build, CFStringRef project, CFStringRef property, CFStringRef value) {
         char* cbuild = strdup_cfstr(build);
         char* cproj = strdup_cfstr(project);
         char* cprop = strdup_cfstr(property);
         char* cvalu = strdup_cfstr(value);
 	if (project) {
-		SQL(session, "DELETE FROM properties WHERE build=%Q AND project=%Q AND property=%Q", cbuild, cproj, cprop);
-		SQL(session, "INSERT INTO properties (build,project,property,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cproj, cprop, cvalu);
+		SQL("DELETE FROM properties WHERE build=%Q AND project=%Q AND property=%Q", cbuild, cproj, cprop);
+		SQL("INSERT INTO properties (build,project,property,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cproj, cprop, cvalu);
 	} else {
-		SQL(session, "DELETE FROM properties WHERE build=%Q AND project IS NULL AND property=%Q", cbuild, cprop);
-		SQL(session, "INSERT INTO properties (build,property,value) VALUES (%Q, %Q, %Q)", cbuild, cprop, cvalu);
+		SQL("DELETE FROM properties WHERE build=%Q AND project IS NULL AND property=%Q", cbuild, cprop);
+		SQL("INSERT INTO properties (build,property,value) VALUES (%Q, %Q, %Q)", cbuild, cprop, cvalu);
 	}
 	free(cbuild);
         free(cproj);
@@ -371,22 +377,22 @@
 	return 0;
 }
 
-int DBSetPropArray(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFArrayRef value) {
+int DBSetPropArray(CFStringRef build, CFStringRef project, CFStringRef property, CFArrayRef value) {
 	char* cbuild = strdup_cfstr(build);
 	char* cproj = strdup_cfstr(project);
 	char* cprop = strdup_cfstr(property);
 	if (project) {
-		SQL(session, "DELETE FROM properties WHERE build=%Q AND project=%Q AND property=%Q", cbuild, cproj, cprop);
+		SQL("DELETE FROM properties WHERE build=%Q AND project=%Q AND property=%Q", cbuild, cproj, cprop);
 	} else {
-		SQL(session, "DELETE FROM properties WHERE build=%Q AND project IS NULL AND property=%Q", cbuild, cprop);
+		SQL("DELETE FROM properties WHERE build=%Q AND project IS NULL AND property=%Q", cbuild, cprop);
 	}
 	CFIndex i, count = CFArrayGetCount(value);
 	for (i = 0; i < count; ++i) {
 		char* cvalu = strdup_cfstr(CFArrayGetValueAtIndex(value, i));
 		if (project) {
-			SQL(session, "INSERT INTO properties (build,project,property,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cproj, cprop, cvalu);
+			SQL("INSERT INTO properties (build,project,property,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cproj, cprop, cvalu);
 		} else {
-			SQL(session, "INSERT INTO properties (build,property,value) VALUES (%Q, %Q, %Q)", cbuild, cprop, cvalu);
+			SQL("INSERT INTO properties (build,property,value) VALUES (%Q, %Q, %Q)", cbuild, cprop, cvalu);
 		}
 		free(cvalu);
 	}
@@ -396,7 +402,7 @@
 	return 0;
 }
 
-int DBSetPropDictionary(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFDictionaryRef value) {
+int DBSetPropDictionary(CFStringRef build, CFStringRef project, CFStringRef property, CFDictionaryRef value) {
 	char* cbuild = strdup_cfstr(build);
 	char* cproj = strdup_cfstr(project);
 	char* cprop = strdup_cfstr(property);
@@ -410,9 +416,9 @@
 		if (CFGetTypeID(cf) == CFStringGetTypeID()) {
 			char* cvalu = strdup_cfstr(cf);
 			if (project) {
-				SQL(session, "INSERT INTO properties (build,project,property,key,value) VALUES (%Q, %Q, %Q, %Q, %Q)", cbuild, cproj, cprop, ckey, cvalu);
+				SQL("INSERT INTO properties (build,project,property,key,value) VALUES (%Q, %Q, %Q, %Q, %Q)", cbuild, cproj, cprop, ckey, cvalu);
 			} else {
-				SQL(session, "INSERT INTO properties (build,property,key,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cprop, ckey, cvalu);
+				SQL("INSERT INTO properties (build,property,key,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cprop, ckey, cvalu);
 			}
 			free(cvalu);
 		} else if (CFGetTypeID(cf) == CFArrayGetTypeID()) {
@@ -420,9 +426,9 @@
 			for (j = 0; j < count; ++j) {
 				char* cvalu = strdup_cfstr(CFArrayGetValueAtIndex(cf, j));
 				if (project) {
-					SQL(session, "INSERT INTO properties (build,project,property,key,value) VALUES (%Q, %Q, %Q, %Q, %Q)", cbuild, cproj, cprop, ckey, cvalu);
+					SQL("INSERT INTO properties (build,project,property,key,value) VALUES (%Q, %Q, %Q, %Q, %Q)", cbuild, cproj, cprop, ckey, cvalu);
 				} else {
-					SQL(session, "INSERT INTO properties (build,property,key,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cprop, ckey, cvalu);
+					SQL("INSERT INTO properties (build,property,key,value) VALUES (%Q, %Q, %Q, %Q)", cbuild, cprop, ckey, cvalu);
 				}
 				free(cvalu);
 			}
@@ -437,13 +443,13 @@
 }
 
 
-CFDictionaryRef DBCopyProjectPlist(void* session, CFStringRef build, CFStringRef project) {
+CFDictionaryRef DBCopyProjectPlist(CFStringRef build, CFStringRef project) {
 	CFMutableDictionaryRef res = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-	CFArrayRef props = DBCopyPropNames(session, build, project);
+	CFArrayRef props = DBCopyPropNames(build, project);
 	CFIndex i, count = CFArrayGetCount(props);
 	for (i = 0; i < count; ++i) {
 		CFStringRef prop = CFArrayGetValueAtIndex(props, i);
-		CFTypeRef value = DBCopyProp(session, build, project, prop);
+		CFTypeRef value = DBCopyProp(build, project, prop);
 		if (value) {
 			CFDictionaryAddValue(res, prop, value);
 			CFRelease(value);
@@ -453,14 +459,14 @@
 }
 
 
-CFDictionaryRef DBCopyBuildPlist(void* session, CFStringRef build) {
-	CFMutableDictionaryRef plist = (CFMutableDictionaryRef)DBCopyProjectPlist(session, build, NULL);
+CFDictionaryRef DBCopyBuildPlist(CFStringRef build) {
+	CFMutableDictionaryRef plist = (CFMutableDictionaryRef)DBCopyProjectPlist(build, NULL);
 	CFMutableDictionaryRef projects = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-	CFArrayRef names = DBCopyProjectNames(session, build);
+	CFArrayRef names = DBCopyProjectNames(build);
 	CFIndex i, count = CFArrayGetCount(names);
 	for (i = 0; i < count; ++i) {
 		CFStringRef name = CFArrayGetValueAtIndex(names, i);
-		CFDictionaryRef proj = DBCopyProjectPlist(session, build, name);
+		CFDictionaryRef proj = DBCopyProjectPlist(build, name);
 		CFDictionaryAddValue(projects, name, proj);
 		CFRelease(proj);
 	}
@@ -470,7 +476,7 @@
 }
 
 
-int _DBSetPlist(void* session, CFStringRef buildParam, CFStringRef projectParam, CFPropertyListRef plist) {
+int _DBSetPlist(CFStringRef buildParam, CFStringRef projectParam, CFPropertyListRef plist) {
 	int res = 0;
 	CFIndex i, count;
 	
@@ -493,7 +499,7 @@
 	//
 	// Delete any properties which may have been removed
 	//
-	CFArrayRef existingProps = DBCopyPropNames(session, build, project);
+	CFArrayRef existingProps = DBCopyPropNames(build, project);
 	count = CFArrayGetCount(props);
 	CFRange range = CFRangeMake(0, count);
 	CFIndex existingCount = CFArrayGetCount(existingProps);
@@ -505,10 +511,10 @@
 			char* cprop = strdup_cfstr(prop);
 			if (project) {
 				char* cproj = strdup_cfstr(project);
-				SQL(session, "DELETE FROM properties WHERE build=%Q AND project=%Q AND property=%Q", cbuild, cproj, cprop);
+				SQL("DELETE FROM properties WHERE build=%Q AND project=%Q AND property=%Q", cbuild, cproj, cprop);
 				free(cproj);
 			} else {
-				SQL(session, "DELETE FROM properties WHERE build=%Q AND project IS NULL AND property=%Q", cbuild, cprop);
+				SQL("DELETE FROM properties WHERE build=%Q AND project IS NULL AND property=%Q", cbuild, cprop);
 			}
 			free(cbuild);
 			free(cprop);
@@ -524,7 +530,7 @@
 		if (CFEqual(prop, CFSTR("build")) || CFEqual(prop, CFSTR("projects"))) continue;
 		
 		CFTypeRef value = CFDictionaryGetValue(plist, prop);
-		res = DBSetProp(session, build, project, prop, value);
+		res = DBSetProp(build, project, prop, value);
 		if (res != 0) break;
 	}
 	
@@ -534,7 +540,7 @@
 		for (i = 0; i < count; ++i ) {
 			CFStringRef project = CFArrayGetValueAtIndex(projectNames, i);
 			CFDictionaryRef subplist = CFDictionaryGetValue(projects, project);
-			res = _DBSetPlist(session, build, project, subplist);
+			res = _DBSetPlist(build, project, subplist);
 			if (res != 0) break;
 		}
 		CFRelease(projectNames);
@@ -543,28 +549,28 @@
 	return res;
 }
 
-int DBSetPlist(void* session, CFStringRef buildParam, CFPropertyListRef plist) {
+int DBSetPlist(CFStringRef buildParam, CFPropertyListRef plist) {
 	int res;
-	res = DBBeginTransaction(session);
+	res = DBBeginTransaction();
 	if (res != 0) return res;
-	res = _DBSetPlist(session, buildParam, NULL, plist);
+	res = _DBSetPlist(buildParam, NULL, plist);
 	if (res != 0) {
-		DBRollbackTransaction(session);
+		DBRollbackTransaction();
 		return res;
 	}
-	DBCommitTransaction(session);
+	DBCommitTransaction();
 	return res;
 }
 
 
-int DBBeginTransaction(void* session) {
-	return SQL(session, "BEGIN");
+int DBBeginTransaction() {
+	return SQL("BEGIN");
 }
-int DBRollbackTransaction(void* session) {
-	return SQL(session, "ROLLBACK");
+int DBRollbackTransaction() {
+	return SQL("ROLLBACK");
 }
-int DBCommitTransaction(void* session) {
-	return SQL(session, "COMMIT");
+int DBCommitTransaction() {
+	return SQL("COMMIT");
 }
 
 

Modified: trunk/darwinxref/DBPlugin.c
===================================================================
--- trunk/darwinxref/DBPlugin.c	2005-06-17 23:50:10 UTC (rev 15)
+++ trunk/darwinxref/DBPlugin.c	2006-10-04 08:37:04 UTC (rev 16)
@@ -39,15 +39,78 @@
 
 #include "cfutils.h"
 #include "DBPlugin.h"
+#include "DBPluginPriv.h"
 
-const void* DBGetPluginWithName(CFStringRef name);
+//////
+// Public interfaces for plugins
+// For more implementation, also see DBDataStore.c
+//////
+void DBPluginSetType(UInt32 type) {
+	DBPlugin* plugin = _DBPluginGetCurrentPlugin();
+	switch (type) {
+		case kDBPluginBasicType:
+		case kDBPluginPropertyType:
+			plugin->type = type;
+			break;
+		default:
+			// XXX: error
+			break;
+	}
+}
 
+void DBPluginSetName(CFStringRef name) {
+	DBPlugin* plugin = _DBPluginGetCurrentPlugin();
+	plugin->name = CFStringCreateCopy(NULL, name);
+}
+
+void DBPluginSetRunFunc(DBPluginRunFunc func) {
+	DBPlugin* plugin = _DBPluginGetCurrentPlugin();
+	plugin->run = func;
+}
+
+void DBPluginSetUsageFunc(DBPluginUsageFunc func) {
+	DBPlugin* plugin = _DBPluginGetCurrentPlugin();
+	plugin->usage = func;
+}
+
+void DBPluginSetDataType(CFTypeID type) {
+	DBPlugin* plugin = _DBPluginGetCurrentPlugin();
+	plugin->datatype = type;
+}
+
+
+
+//////
+// Private interfaces to DBPlugin for use by darwinxref internals
+//////
+
+//////
+// NOT THREAD SAFE
+// We currently operate under the assumption that there is only
+// one thread, with no plugin re-entrancy.
+//////
+const DBPlugin* __DBPluginCurrentPlugin;
+void _DBPluginSetCurrentPlugin(const DBPlugin* plugin) {
+	__DBPluginCurrentPlugin = plugin;
+}
+DBPlugin* _DBPluginGetCurrentPlugin() {
+	return (DBPlugin*)__DBPluginCurrentPlugin;
+}
+
 CFDictionaryValueCallBacks cfDictionaryPluginValueCallBacks = {
 	0, NULL, NULL, NULL, NULL
 };
 
 static CFMutableDictionaryRef plugins;
 
+DBPlugin* _DBPluginInitialize() {
+	DBPlugin* plugin = malloc(sizeof(DBPlugin));
+	assert(plugin != NULL);
+	memset(plugin, 0, sizeof(DBPlugin));
+	plugin->type = kDBPluginNullType;
+	return plugin;
+}
+
 int load_plugins(const char* plugin_path) {
 	if (plugins == NULL) {
 		plugins = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &cfDictionaryPluginValueCallBacks);
@@ -62,6 +125,7 @@
 	(void)fts_read(dir);
 	FTSENT* ent = fts_children (dir, FTS_NAMEONLY);
 	while (ent != NULL) {
+		DBPlugin* plugin = NULL;
 		if (strstr(ent->fts_name, ".so")) {
 			char* filename;
 			asprintf(&filename, "%s/%s", fullpath, ent->fts_name);
@@ -69,22 +133,31 @@
 			void* handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
 			if (handle) {
 				DBPluginInitializeFunc func = dlsym(handle, "initialize");
-				DBPlugin* plugin = (*func)(kDBPluginCurrentVersion);
-				if (plugin) {
-					if (plugin->version == kDBPluginCurrentVersion &&
-						(plugin->type == kDBPluginPropertyType || plugin->type == kDBPluginType)) {
-						CFDictionarySetValue(plugins, plugin->name, plugin);
-					} else {
-						fprintf(stderr, "Unrecognized plugin version and type: %x, %x: %s\n", plugin->version, plugin->type, ent->fts_name);
-					}
-				} else {
-						fprintf(stderr, "Plugin initialize returned null: %s\n", ent->fts_name);
-				}
-				//dlclose(handle);
+				plugin = _DBPluginInitialize();
+				_DBPluginSetCurrentPlugin(plugin);
+				(*func)(kDBPluginCurrentVersion);	// Call out to C plugin
+				// XXX: check for error?
 			} else {
 				fprintf(stderr, "Could not dlopen plugin: %s\n", ent->fts_name);
 			}
+#if HAVE_TCL_PLUGINS
+		} else if (strstr(ent->fts_name, ".tcl")) {
+			char* filename;
+			asprintf(&filename, "%s/%s", fullpath, ent->fts_name);
+			plugin = _DBPluginInitialize();
+			_DBPluginSetCurrentPlugin(plugin);
+			load_tcl_plugin(plugin, filename);	// Calls out to Tcl plugin
+#endif
 		}
+		if (plugin) {
+			if (plugin->name == NULL) {
+				fprintf(stderr, "warning: plugin has no name (skipping): %s\n", ent->fts_name);
+			} else if (plugin->type == kDBPluginNullType) {
+				fprintf(stderr, "warning: plugin has no type (skipping): %s\n", ent->fts_name);
+			} else {
+				CFDictionarySetValue(plugins, plugin->name, plugin);
+			}
+		}
 		ent = ent->fts_link;
 	}
 	fts_close(dir);
@@ -98,7 +171,17 @@
 		CFStringRef name = cfstr(argv[0]);
 		const DBPlugin* plugin = DBGetPluginWithName(name);
 		if (plugin) {
-			CFStringRef usage = plugin->usage(NULL);
+			_DBPluginSetCurrentPlugin(plugin);
+#if HAVE_TCL_PLUGINS
+			CFStringRef usage = NULL;
+			if ((plugin->type & kDBPluginTclType) != 0) {
+				usage = call_tcl_usage((DBPlugin*)plugin);
+			} else {
+				usage = plugin->usage();
+			}
+#else
+			CFStringRef usage = plugin->usage();
+#endif
 			cfprintf(stderr, "usage: %s [-f db] [-b build] %@ %@\n", progname, name, usage);
 			CFRelease(usage);
 			return;
@@ -110,15 +193,25 @@
 	for (i = 0; i < count; ++i) {
 		CFStringRef name = CFArrayGetValueAtIndex(pluginNames, i);
 		const DBPlugin* plugin = DBGetPluginWithName(name);
-		CFStringRef usage = plugin->usage(NULL);
+		_DBPluginSetCurrentPlugin(plugin);
+#if HAVE_TCL_PLUGINS
+		CFStringRef usage = NULL;
+		if ((plugin->type & kDBPluginTclType) != 0) {
+			usage = call_tcl_usage((DBPlugin*)plugin);
+		} else {
+			usage = plugin->usage();
+		}
+#else
+		CFStringRef usage = plugin->usage();
+#endif
 		cfprintf(stderr, "usage: %s [-f db] [-b build] %@ %@\n", progname, name, usage);
 		CFRelease(usage);
 	}
 }
 
-const void* DBGetPluginWithName(CFStringRef name) {
+const DBPlugin* DBGetPluginWithName(CFStringRef name) {
 	const void* plugin = CFDictionaryGetValue(plugins, name);
-	return plugin;
+	return (DBPlugin*)plugin;
 }
 
 int run_plugin(void* session, int argc, char* argv[]) {
@@ -131,7 +224,16 @@
 	}
 	const DBPlugin* plugin = DBGetPluginWithName(name);
 	if (plugin) {
-		res = plugin->run(session, args);
+		_DBPluginSetCurrentPlugin(plugin);
+#if HAVE_TCL_PLUGINS
+		if ((plugin->type & kDBPluginTclType) != 0) {
+			res = call_tcl_run((DBPlugin*)plugin, args);
+		} else {
+			res = plugin->run(args);
+		}
+#else
+		res = plugin->run(args);
+#endif
 	} else {
 		print_usage("darwinxref", argc, argv);
 	}
@@ -142,12 +244,12 @@
 extern CFDictionaryRef _CFCopySystemVersionDictionary();
 static CFStringRef currentBuild = NULL;
 
-void DBSetCurrentBuild(void* session, char* build) {
+void DBSetCurrentBuild(char* build) {
 	if (currentBuild) CFRelease(currentBuild);
 	currentBuild = cfstr(build);
 }
 
-CFStringRef DBGetCurrentBuild(void* session) {
+CFStringRef DBGetCurrentBuild() {
 	if (currentBuild) return currentBuild;
 
 	// The following is Private API.

Modified: trunk/darwinxref/DBPlugin.h
===================================================================
--- trunk/darwinxref/DBPlugin.h	2005-06-17 23:50:10 UTC (rev 15)
+++ trunk/darwinxref/DBPlugin.h	2006-10-04 08:37:04 UTC (rev 16)
@@ -42,10 +42,9 @@
 	Initialization function present in every plugin.
 	@param version The latest plugin version that darwinxref is aware of
 	(kDBPluginCurrentVersion).
-	@result A pointer to an initialized DBPlugin structure describing this
-	plugin.  The structure should be allocated with malloc(3).
+	@result 0 for success, -1 for error.
 */
-typedef DBPlugin* (*DBPluginInitializeFunc)(int version);
+typedef int (*DBPluginInitializeFunc)(int version);
 
 /*!
 	@typedef DBPluginRunFunc
@@ -55,7 +54,7 @@
 	@param argv The command line arguments.
 	@result Returns an exit status for darwinxref.
 */
-typedef int (*DBPluginRunFunc)(void* session, CFArrayRef argv);
+typedef int (*DBPluginRunFunc)(CFArrayRef argv);
 
 /*!
 	@typedef DBPluginUsageFunc
@@ -64,7 +63,7 @@
 	any callbacks from the plugin.
 	@result The command line usage string.
 */
-typedef CFStringRef (*DBPluginUsageFunc)(void* session);
+typedef CFStringRef (*DBPluginUsageFunc)();
 
 
 /*!
@@ -83,66 +82,72 @@
 	Plugin which adds a build or project property to the plist file.
 */
 enum {
-	kDBPluginType = FOUR_CHAR_CODE('plug'),
-	kDBPluginPropertyType = FOUR_CHAR_CODE('prop'),
+	kDBPluginNullType = 0,
+	kDBPluginBasicType = 1,
+	kDBPluginPropertyType = 2,
+#if HAVE_TCL_PLUGINS
+	kDBPluginTclType = 0x8000000,
+#endif
 };
 
-
 /*!
-	@typedef DBPlugin
-	Basic plugin data structure returned by plugin's initialize function.
-	@field version kDBPluginCurrentVersion (this structure is version 0).
-	@field type kDBPluginType, or kDBPluginPropertyType.
-	@field name The name of the plugin (visible from the command line).
-	@field run The function to call when the plugin is invoked from the
-	command line.
-	@field usage The function that returns the command line usage string
-	for this plugin.
+	@typedef DBPropPluginGetFunc
+	Accessor for returning the property implemented by this plugin.
+	This gives the plugin the opportunity to perform integrity checks
+	on the data other than the basic type checking performed by darwinxref.
+	@param session An opaque session pointer that should be passed to
+	any callbacks from the plugin.
+	@param project The project whose property should be returned, or NULL to get
+	a build property.
+	@result The value of the property.
 */
-struct DBPlugin {
-	UInt32		version;
-	UInt32		type;
-	CFStringRef	name;
-	DBPluginRunFunc		run;
-	DBPluginUsageFunc	usage;
-};
+//typedef CFPropertyListRef (*DBPluginGetPropFunc)(void* session, CFStringRef project);
 
-
 /*!
-	@typedef DBPropertyPlugin
-	Extended plugin data structure for the kDBPluginPropertyType.
-	@field base The basic plugin structure
-	@field datatype The datatype of this property
-	(i.e. one of CFStringGetTypeID(), CFArrayGetTypeID(), CFDictionaryGetTypeID())
+	@typedef DBPropPluginSetFunc
+	Accessor for setting the property implemented by this plugin.
+	This gives the plugin the opportunity to perform integrity checks
+	on the data other than the basic type checking performed by darwinxref.
+	@param session An opaque session pointer that should be passed to
+	any callbacks from the plugin.
+	@param project The project whose property should be set, or NULL to set
+	a build property.
+	@param value The new value of the property.
+	@result The status, 0 for success.
 */
-typedef struct {
-	DBPlugin	base;
-	CFTypeID	datatype;
-} DBPropertyPlugin;
+//typedef int (*DBPluginSetPropFunc)(void* session, CFStringRef project, CFPropertyListRef value);
 
 // plugin API
 
-CFStringRef DBGetCurrentBuild(void* session);
+// initialization routines, only call during initialize.
+void DBPluginSetType(UInt32 type);
+void DBPluginSetName(CFStringRef name);
+void DBPluginSetRunFunc(DBPluginRunFunc func);
+void DBPluginSetUsageFunc(DBPluginUsageFunc func);
+void DBPluginSetDataType(CFTypeID type);
 
-CFArrayRef DBCopyPropNames(void* session, CFStringRef build, CFStringRef project);
-CFArrayRef DBCopyProjectNames(void* session, CFStringRef build);
+// generally available routines
 
-CFTypeRef DBCopyProp(void* session, CFStringRef build, CFStringRef project, CFStringRef property);
-CFStringRef DBCopyPropString(void* session, CFStringRef build, CFStringRef project, CFStringRef property);
-CFArrayRef DBCopyPropArray(void* session, CFStringRef build, CFStringRef project, CFStringRef property);
-CFDictionaryRef DBCopyPropDictionary(void* session, CFStringRef build, CFStringRef project, CFStringRef property);
+CFStringRef DBGetCurrentBuild();
 
-int DBSetProp(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFTypeRef value);
-int DBSetPropString(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFStringRef value);
-int DBSetPropArray(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFArrayRef value);
-int DBSetPropDictionary(void* session, CFStringRef build, CFStringRef project, CFStringRef property, CFDictionaryRef value);
+CFArrayRef DBCopyPropNames(CFStringRef build, CFStringRef project);
+CFArrayRef DBCopyProjectNames(CFStringRef build);
 
-CFDictionaryRef DBCopyProjectPlist(void* session, CFStringRef build, CFStringRef project);
-CFDictionaryRef DBCopyBuildPlist(void* session, CFStringRef build);
+CFTypeRef DBCopyProp(CFStringRef build, CFStringRef project, CFStringRef property);
+CFStringRef DBCopyPropString(CFStringRef build, CFStringRef project, CFStringRef property);
+CFArrayRef DBCopyPropArray(CFStringRef build, CFStringRef project, CFStringRef property);
+CFDictionaryRef DBCopyPropDictionary(CFStringRef build, CFStringRef project, CFStringRef property);
 
-int DBSetPlist(void* session, CFStringRef build, CFPropertyListRef plist);
+int DBSetProp(CFStringRef build, CFStringRef project, CFStringRef property, CFTypeRef value);
+int DBSetPropString(CFStringRef build, CFStringRef project, CFStringRef property, CFStringRef value);
+int DBSetPropArray(CFStringRef build, CFStringRef project, CFStringRef property, CFArrayRef value);
+int DBSetPropDictionary(CFStringRef build, CFStringRef project, CFStringRef property, CFDictionaryRef value);
 
+CFDictionaryRef DBCopyProjectPlist(CFStringRef build, CFStringRef project);
+CFDictionaryRef DBCopyBuildPlist(CFStringRef build);
 
+int DBSetPlist(CFStringRef build, CFPropertyListRef plist);
+
 #include "cfutils.h"
 
 #endif

Added: trunk/darwinxref/DBPluginPriv.h
===================================================================
--- trunk/darwinxref/DBPluginPriv.h	                        (rev 0)
+++ trunk/darwinxref/DBPluginPriv.h	2006-10-04 08:37:04 UTC (rev 16)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_BSD_LICENSE_HEADER_START@
+ * 
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ * 
+ * @APPLE_BSD_LICENSE_HEADER_END@
+ */
+
+#include "DBPlugin.h"
+
+/*!
+	@typedef DBPlugin
+	Basic plugin data structure returned by plugin's initialize function.
+	@field version kDBPluginCurrentVersion (this structure is version 0).
+	@field type kDBPluginType, or kDBPluginPropertyType.
+	@field name The name of the plugin (visible from the command line).
+	@field run The function to call when the plugin is invoked from the
+	command line.
+	@field usage The function that returns the command line usage string
+	for this plugin.
+	@field datatype The datatype of this property
+	(i.e. one of CFStringGetTypeID(), CFArrayGetTypeID(), CFDictionaryGetTypeID())
+	@field getprop The property get accessor, NULL for default behavior
+	@field setprop The property set accessor, NULL for default behavior
+*/
+struct DBPlugin {
+	// for all plugins
+	UInt32		type;
+	CFStringRef	name;
+	// for compiled plugins
+	DBPluginRunFunc		run;
+	DBPluginUsageFunc	usage;
+#if HAVE_TCL_PLUGINS
+	// for tcl plugins
+	void*		interp;
+#endif
+	// for property plugins
+	CFTypeID	datatype;
+//	DBPluginGetPropFunc getprop;
+//	DBPluginSetPropFunc setprop;
+};
+
+void* _DBPluginGetDataStorePtr();
+DBPlugin* _DBPluginGetCurrentPlugin();
+
+const DBPlugin* DBGetPluginWithName(CFStringRef name);
+
+int DBBeginTransaction();
+int DBRollbackTransaction();
+int DBCommitTransaction();
+
+#if HAVE_TCL_PLUGINS
+int load_tcl_plugin(DBPlugin* plugin, const char* filename);
+CFStringRef call_tcl_usage(DBPlugin* plugin);
+int call_tcl_run(DBPlugin* plugin, CFArrayRef args);
+#endif
\ No newline at end of file


Property changes on: trunk/darwinxref/DBPluginPriv.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/darwinxref/DBTclPlugin.c
===================================================================
--- trunk/darwinxref/DBTclPlugin.c	                        (rev 0)
+++ trunk/darwinxref/DBTclPlugin.c	2006-10-04 08:37:04 UTC (rev 16)
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Portions copyright (c) 2003 Kevin Van Vechten <kevin at opendarwin.org>
+ *
+ * @APPLE_BSD_LICENSE_HEADER_START@
+ * 
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ * 
+ * @APPLE_BSD_LICENSE_HEADER_END@
+ */
+
+
+#if HAVE_TCL_PLUGINS
+
+#include "DBPluginPriv.h"
+
+#include <tcl.h>
+
+CFStringRef cfstr_tcl(Tcl_Obj* obj) {
+	CFStringRef result = NULL;
+	int length;
+	char* buf = Tcl_GetStringFromObj(obj, &length);
+	if (buf) {
+		result = CFStringCreateWithBytes(NULL, buf, length, kCFStringEncodingUTF8, 0);
+	}
+	return result;
+}
+
+Tcl_Obj* tcl_cfstr(CFStringRef cf) {
+	Tcl_Obj* tcl_result = NULL;
+	if (cf) {
+		CFIndex length = CFStringGetLength(cf);
+		CFIndex size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUnicode);
+		UniChar* buffer = (UniChar*)Tcl_Alloc(size);
+		if (buffer) {
+			CFStringGetCharacters(cf, CFRangeMake(0, length), buffer);
+			tcl_result = Tcl_NewUnicodeObj(buffer, length);
+			Tcl_Free((char*)buffer);
+		}
+	}
+	return tcl_result;
+}
+
+
+int DBPluginSetNameCmd(ClientData data, Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
+	if (objc != 2) {
+		Tcl_WrongNumArgs(interp, 1, objv, "name");
+		return TCL_ERROR;
+	}
+
+	CFStringRef str = cfstr_tcl(objv[1]);
+	DBPlugin* plugin = (DBPlugin*)data;
+	plugin->name = str;
+	return TCL_OK;
+}
+
+int DBPluginSetTypeCmd(ClientData data, Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
+	if (objc != 2) {
+		Tcl_WrongNumArgs(interp, 1, objv, "type");
+		return TCL_ERROR;
+	}
+	int length;
+	char* type = Tcl_GetStringFromObj(objv[1], &length);
+	DBPlugin* plugin = (DBPlugin*)data;
+	if (strcmp(type, "basic") == 0) {
+		plugin->type = kDBPluginBasicType | kDBPluginTclType;
+	} else if (strcmp(type, "property") == 0) {
+		plugin->type = kDBPluginPropertyType | kDBPluginTclType;
+	} else {
+			Tcl_AppendResult(interp, "Unknown type: ", type, NULL);
+			return TCL_ERROR;
+	}
+	return TCL_OK;
+}
+
+
+int load_tcl_plugin(DBPlugin* plugin, const char* filename) {
+	// Create a plugin object
+	Tcl_Interp* interp = Tcl_CreateInterp();
+
+	plugin->interp = (DBPluginRunFunc)interp;
+
+	// Register our plugin callback
+	Tcl_CreateObjCommand(interp, "DBPluginSetName", DBPluginSetNameCmd, (ClientData)plugin, (Tcl_CmdDeleteProc *)NULL);
+	Tcl_CreateObjCommand(interp, "DBPluginSetType", DBPluginSetTypeCmd, (ClientData)plugin, (Tcl_CmdDeleteProc *)NULL);
+
+	// Source the plugin file
+	Tcl_EvalFile(interp, filename);
+
+	return 0;
+}
+
+CFStringRef call_tcl_usage(DBPlugin* plugin) {
+	Tcl_Eval(plugin->interp, "usage");
+	Tcl_Obj* res = Tcl_GetObjResult(plugin->interp);
+	return cfstr_tcl(res);
+}
+
+int call_tcl_run(DBPlugin* plugin, CFArrayRef args) {
+	// XXX: need to pass args
+	Tcl_Eval(plugin->interp, "run");
+	Tcl_Obj* res = Tcl_GetObjResult(plugin->interp);
+	return 0;
+}
+
+#endif /* HAVE_TCL_PLUGINS */
\ No newline at end of file


Property changes on: trunk/darwinxref/DBTclPlugin.c
___________________________________________________________________
Name: svn:eol-style
   + native

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20061004/563d5fc6/attachment-0001.html


More information about the darwinbuild-changes mailing list