[23857] users/rhwood/Pallet/CFLib.c

source_changes at macosforge.org source_changes at macosforge.org
Wed Apr 11 02:57:45 PDT 2007


Revision: 23857
          http://trac.macosforge.org/projects/macports/changeset/23857
Author:   rhwood at macports.org
Date:     2007-04-11 02:57:45 -0700 (Wed, 11 Apr 2007)

Log Message:
-----------
Add CFLib.c from the MacPorts base code, but don't use it yet.

Added Paths:
-----------
    users/rhwood/Pallet/CFLib.c

Added: users/rhwood/Pallet/CFLib.c
===================================================================
--- users/rhwood/Pallet/CFLib.c	                        (rev 0)
+++ users/rhwood/Pallet/CFLib.c	2007-04-11 09:57:45 UTC (rev 23857)
@@ -0,0 +1,1378 @@
+/*
+ * CFLib.c
+ * CFLib.dylib
+ * $Id: CFLib.c 19376 2006-09-02 03:19:06Z yeled at macports.org $
+ *
+ * Copyright (c) 2003 Kevin Van Vechten <kevin at opendarwin.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.
+ * 3. Neither the name of the copyright owner nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER OR 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.
+ */
+
+#include <tcl.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+/*
+	Wildebeest
+	TCL bindings for CoreFoundation
+	
+	Currently CFString, CFData, CFURL, CFArray, and CFDictionary are
+	toll free bridged.
+	
+	Most of CFArray, CFDictionary, CFBundle, and CFPropertyList
+	have been implemented.
+	
+	TODO:
+		Toll free bridges for CFNumber, CFDate, CFBoolean.
+ */
+
+/* CFBase.h */
+
+/* CFType ObjType */
+static int tclObjToCFString(Tcl_Interp*, Tcl_Obj*, CFTypeRef*);
+static int tclObjToCFType(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	*outPtr = NULL;
+	if (obj->typePtr == Tcl_GetObjType("CFString") ||
+		obj->typePtr == Tcl_GetObjType("CFData") ||
+		obj->typePtr == Tcl_GetObjType("CFURL") ||
+		obj->typePtr == Tcl_GetObjType("CFNumber") ||
+		obj->typePtr == Tcl_GetObjType("CFArray") ||
+		obj->typePtr == Tcl_GetObjType("CFDictionary") ||
+		obj->typePtr == Tcl_GetObjType("CFBundle") ||
+		obj->typePtr == Tcl_GetObjType("CFType")) {
+		*outPtr = CFRetain(obj->internalRep.otherValuePtr);
+	} else {
+		return tclObjToCFString(interp, obj, outPtr);
+	}
+	return TCL_OK;
+}
+
+static void cfTypeDupInternalRepProc(Tcl_Obj* srcPtr, Tcl_Obj* dupPtr) {
+	dupPtr->typePtr = srcPtr->typePtr;
+	CFTypeRef cf = srcPtr->internalRep.otherValuePtr;
+	dupPtr->internalRep.otherValuePtr = cf ? (void*)CFRetain(cf) : NULL;
+}
+
+static void cfTypeFreeInternalRepProc(Tcl_Obj* objPtr) {
+	objPtr->typePtr = NULL;
+	CFTypeRef cf = objPtr->internalRep.otherValuePtr;
+	if (cf) CFRelease(cf);
+}
+
+static void cfTypeUpdateStringProc2(Tcl_Obj* objPtr, CFStringRef str) {
+	if (str) {
+		CFIndex length = CFStringGetLength(str);
+		CFIndex size = CFStringGetMaximumSizeForEncoding(length + 1, kCFStringEncodingUTF8);
+		objPtr->bytes = Tcl_Alloc(size);
+		if (objPtr->bytes) {
+			CFIndex bytesUsed;
+			CFStringGetBytes(str, CFRangeMake(0, length), kCFStringEncodingUTF8, '?', 0, objPtr->bytes, size, &bytesUsed);
+			objPtr->length = bytesUsed;
+			objPtr->bytes[bytesUsed] = 0;	// terminating NUL as per TCL spec.
+		}
+	}
+}
+
+static void cfTypeUpdateStringProc(Tcl_Obj* objPtr) {
+	CFTypeRef cf = objPtr->internalRep.otherValuePtr;
+	if (cf) {
+		CFStringRef str = CFCopyDescription(cf);
+		if (str) {
+			cfTypeUpdateStringProc2(objPtr, str);
+			CFRelease(str);
+		}
+	}
+}
+
+static int cfTypeSetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	Tcl_Obj* tcl_result = Tcl_NewStringObj("CFTypes must be created with CF constructors", -1);
+	Tcl_SetObjResult(interp, tcl_result);
+	return TCL_ERROR;
+}
+
+static void cfTypeRegister() {
+	static Tcl_ObjType cfTypeType;
+	cfTypeType.name = "CFType";
+	cfTypeType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfTypeType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfTypeType.updateStringProc = cfTypeUpdateStringProc;
+	cfTypeType.setFromAnyProc = cfTypeSetFromAnyProc;
+	Tcl_RegisterObjType(&cfTypeType);
+}
+
+
+
+
+/* CFString.h */
+
+// tcl string -> CFString implicit conversion
+static int tclObjToCFString(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outString) {
+	*outString = NULL;
+	if (obj->typePtr != Tcl_GetObjType("CFString")) {
+		int length;
+		char* buf = Tcl_GetStringFromObj(obj, &length);
+		if (buf) {
+			*outString = CFStringCreateWithBytes(NULL, buf, length, kCFStringEncodingUTF8, 0);
+		} else {
+			return TCL_ERROR;
+		}
+	} else {
+		*outString = CFRetain(obj->internalRep.otherValuePtr);
+	}
+	return TCL_OK;
+}
+
+// CFString -> tcl string implicit conversion
+static Tcl_Obj* cfStringToTCLString(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;
+}
+
+
+/* CFString ObjType */
+
+static int cfStringSetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	if (objPtr->bytes) {
+		objPtr->internalRep.otherValuePtr = (void*)CFStringCreateWithBytes(NULL, 
+												objPtr->bytes,
+												objPtr->length,
+												kCFStringEncodingUTF8,
+												0);
+		return TCL_OK;
+	} else {
+		return TCL_ERROR;
+	}
+}
+
+static void cfStringUpdateStringProc(Tcl_Obj* objPtr) {
+	cfTypeUpdateStringProc2(objPtr, objPtr->internalRep.otherValuePtr);
+}
+
+static void cfStringRegister() {
+	static Tcl_ObjType cfStringType;
+	cfStringType.name = "CFString";
+	cfStringType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfStringType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfStringType.updateStringProc = cfStringUpdateStringProc;
+	cfStringType.setFromAnyProc = cfStringSetFromAnyProc;
+	Tcl_RegisterObjType(&cfStringType);
+}
+
+/* CFData.h */
+/* CFData ObjType */
+
+// tcl string -> CFData implicit conversion
+static int tclObjToCFData(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outData) {
+	*outData = NULL;
+	if (obj->typePtr != Tcl_GetObjType("CFData")) {
+		int length;
+		char* buf = Tcl_GetStringFromObj(obj, &length);
+		if (buf) {
+			*outData = CFDataCreate(NULL, buf, length);
+		} else {
+			return TCL_ERROR;
+		}
+	} else {
+		*outData = CFRetain(obj->internalRep.otherValuePtr);
+	}
+	return TCL_OK;
+}
+
+static int cfDataSetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	if (objPtr->bytes) {
+		objPtr->internalRep.otherValuePtr = (void*)CFDataCreate(NULL, 
+												objPtr->bytes,
+												objPtr->length);
+		return TCL_OK;
+	} else {
+		return TCL_ERROR;
+	}
+}
+
+static void cfDataUpdateStringProc(Tcl_Obj* objPtr) {
+	CFDataRef data = objPtr->internalRep.otherValuePtr;
+	if (data) {
+		CFIndex length = CFDataGetLength(data);
+		objPtr->bytes = Tcl_Alloc(length);
+		if (objPtr->bytes) {
+			CFDataGetBytes(data, CFRangeMake(0, length), objPtr->bytes);
+			objPtr->length = length;
+		}
+	}
+}
+
+static void cfDataRegister() {
+	static Tcl_ObjType cfDataType;
+	cfDataType.name = "CFData";
+	cfDataType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfDataType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfDataType.updateStringProc = cfDataUpdateStringProc;
+	cfDataType.setFromAnyProc = cfDataSetFromAnyProc;
+	Tcl_RegisterObjType(&cfDataType);
+}
+
+
+/* CFArray.h */
+/* CFArray ObjType */
+
+// tcl list -> CFArray implicit conversion
+static int tclObjToCFArray(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	int result = TCL_OK;
+	*outPtr = NULL;
+	if (obj->typePtr != Tcl_GetObjType("CFArray")) {
+		int objc;
+		Tcl_Obj** objv;
+		result = Tcl_ListObjGetElements(interp, obj, &objc, &objv);
+		if (result == TCL_OK) {
+			const void** argv = (const void**)Tcl_Alloc(sizeof(void*) * objc);
+			int i;
+			for (i = 0; i < objc; ++i) {
+				result = tclObjToCFType(interp, objv[i], (CFTypeRef*)&argv[i]);
+				if (result != TCL_OK) break;
+			}
+			if (result == TCL_OK) {
+				*outPtr = CFArrayCreate(NULL, argv, objc, &kCFTypeArrayCallBacks);
+			}
+			Tcl_Free((char*)argv);
+		}
+	} else {
+		*outPtr = CFRetain(obj->internalRep.otherValuePtr);
+	}
+	return result;
+}
+
+static int cfArraySetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	Tcl_Obj* tcl_result = Tcl_NewStringObj("CFArrays must be created with CFArrayCreate", -1);
+	Tcl_SetObjResult(interp, tcl_result);
+	return TCL_ERROR;
+}
+
+static void cfArrayRegister() {
+	static Tcl_ObjType cfArrayType;
+	cfArrayType.name = "CFArray";
+	cfArrayType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfArrayType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfArrayType.updateStringProc = cfTypeUpdateStringProc;
+	cfArrayType.setFromAnyProc = cfArraySetFromAnyProc;
+	Tcl_RegisterObjType(&cfArrayType);
+}
+
+
+/* CFDictionary.h */
+/* CFDictionary ObjType */
+// tcl list -> CFDictionary implicit conversion
+static int tclObjToCFDictionary(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	int result = TCL_OK;
+	*outPtr = NULL;
+	if (obj->typePtr != Tcl_GetObjType("CFDictionary")) {
+		int objc;
+		Tcl_Obj** objv;
+		result = Tcl_ListObjGetElements(interp, obj, &objc, &objv);
+		if (result == TCL_OK) {			
+			if (objc & 1) {
+				Tcl_Obj* tcl_result = Tcl_NewStringObj("list must have an even number of elements", -1);
+				Tcl_SetObjResult(interp, tcl_result);
+				result = TCL_ERROR;
+			} else {
+				const void** keys = (const void**)Tcl_Alloc(sizeof(void*) * objc / 2);
+				const void** vals = (const void**)Tcl_Alloc(sizeof(void*) * objc / 2);
+				int i, j;
+				for (i = 0, j = 0; i < objc; i += 2, ++j) {
+					result = tclObjToCFType(interp, objv[i], (CFTypeRef*)&keys[j]);
+					if (result != TCL_OK) break;
+					result = tclObjToCFType(interp, objv[i+1], (CFTypeRef*)&vals[j]);
+					if (result != TCL_OK) break;
+				}
+				if (result == TCL_OK) {
+					*outPtr = CFDictionaryCreate(NULL, keys, vals, objc / 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+				}
+				Tcl_Free((char*)keys);
+				Tcl_Free((char*)vals);
+			}
+		}
+	} else {
+		*outPtr = CFRetain(obj->internalRep.otherValuePtr);
+	}
+	return result;
+}
+
+static int cfDictionarySetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	Tcl_Obj* tcl_result = Tcl_NewStringObj("CFDictionaries must be created with CFDictionaryCreate", -1);
+	Tcl_SetObjResult(interp, tcl_result);
+	return TCL_ERROR;
+}
+
+static void cfDictionaryRegister() {
+	static Tcl_ObjType cfDictionaryType;
+	cfDictionaryType.name = "CFDictionary";
+	cfDictionaryType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfDictionaryType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfDictionaryType.updateStringProc = cfTypeUpdateStringProc;
+	cfDictionaryType.setFromAnyProc = cfDictionarySetFromAnyProc;
+	Tcl_RegisterObjType(&cfDictionaryType);
+}
+
+/* CFNumber.h */
+/* CFNumber ObjType */
+
+static int cfNumberSetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	Tcl_Obj* tcl_result = Tcl_NewStringObj("CFNumbers must be created with CFNumberCreate", -1);
+	Tcl_SetObjResult(interp, tcl_result);
+	return TCL_ERROR;
+}
+
+// XXX: consolidate with cfStringUpdateStringProc
+static void cfNumberUpdateStringProc(Tcl_Obj* objPtr) {
+	CFNumberRef number = objPtr->internalRep.otherValuePtr;
+	CFStringRef str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), number);
+	if (str) {
+		cfTypeUpdateStringProc2(objPtr, str);
+		CFRelease(str);
+	}
+}
+
+static void cfNumberRegister() {
+	static Tcl_ObjType cfNumberType;
+	cfNumberType.name = "CFNumber";
+	cfNumberType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfNumberType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfNumberType.updateStringProc = cfNumberUpdateStringProc;
+	cfNumberType.setFromAnyProc = cfNumberSetFromAnyProc;
+	Tcl_RegisterObjType(&cfNumberType);
+}
+
+//CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+int tclCFNumberCreate(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
+	CFStringRef string;
+	int			result = TCL_OK;
+	Tcl_Obj*	tcl_result;
+	char*		theType;
+	if (objc != 3) {
+		Tcl_WrongNumArgs(interp, 1, objv, "theType value");
+		return TCL_ERROR;
+	}
+	theType = Tcl_GetStringFromObj(objv[1], NULL);
+	
+	tcl_result = Tcl_NewObj();
+	tcl_result->typePtr = Tcl_GetObjType("CFNumber");
+	tcl_result->bytes = NULL;
+	tcl_result->length = 0;
+	
+	// This may be cutting corners, but since property lists only
+	// distinguish between real and integer, we'll only make that
+	// distinction here too.
+	if (strcmp(theType, "kCFNumberSInt8Type") == 0 ||
+		strcmp(theType, "kCFNumberSInt16Type") == 0 ||
+		strcmp(theType, "kCFNumberSInt32Type") == 0 ||
+		strcmp(theType, "kCFNumberSInt64Type") == 0 ||
+		strcmp(theType, "kCFNumberCharType") == 0 ||
+		strcmp(theType, "kCFNumberShortType") == 0 ||
+		strcmp(theType, "kCFNumberIntType") == 0 ||
+		strcmp(theType, "kCFNumberLongType") == 0 ||
+		strcmp(theType, "kCFNumberLongLongType") == 0 ||
+		strcmp(theType, "kCFNumberCFIndexType") == 0) {
+			long val;
+			result = Tcl_GetLongFromObj(interp, objv[2], &val);
+			if (result == TCL_ERROR) return result;
+			tcl_result->internalRep.otherValuePtr = (void*)CFNumberCreate(NULL, kCFNumberLongType, &val);
+	} else if (strcmp(theType, "kCFNumberFloatType") == 0 ||
+		strcmp(theType, "kCFNumberDoubleType") == 0 ||
+		strcmp(theType, "kCFNumberFloat32Type") == 0 ||
+		strcmp(theType, "kCFNumberFloat64Type") == 0) {
+			double val;
+			result = Tcl_GetDoubleFromObj(interp, objv[2], &val);
+			if (result == TCL_ERROR) return result;
+			tcl_result->internalRep.otherValuePtr = (void*)CFNumberCreate(NULL, kCFNumberDoubleType, &val);		
+	} else {
+		Tcl_Obj* tcl_result = Tcl_NewStringObj("unknown CFNumberType", -1);
+		Tcl_SetObjResult(interp, tcl_result);
+		return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, tcl_result);
+	return result;
+}
+
+
+/* CFURL.h */
+
+// tcl string -> CFString implicit conversion
+static int tclObjToCFURL(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outURL) {
+	*outURL = NULL;
+	if (obj->typePtr != Tcl_GetObjType("CFURL")) {
+		int length;
+		char* buf = Tcl_GetStringFromObj(obj, &length);
+		if (buf) {
+			*outURL = CFURLCreateWithBytes(NULL, buf, length, kCFStringEncodingUTF8, NULL);
+		} else {
+			return TCL_ERROR;
+		}
+	} else {
+		*outURL = CFRetain(obj->internalRep.otherValuePtr);
+	}
+	return TCL_OK;
+}
+/*
+// CFString -> tcl string implicit conversion
+static Tcl_Obj* cfURLToTCLString(CFURLRef url) {
+	CFDataRef data = CFURLCreateData(NULL, url, kCFStringEncodingUTF8, 1);
+	Tcl_Obj* tcl_result = NULL;
+	if (data) {
+		CFIndex length = CFDataGetLength(data);
+		char* buffer = Tcl_Alloc(length);
+		if (buffer) {
+			CFDataGetBytes(data, CFRangeMake(0, length), buffer);
+			tcl_result = Tcl_NewStringObj(buffer, length);
+			Tcl_Free(buffer);
+		}
+	}
+	return tcl_result;
+}
+*/
+
+/* CFString ObjType */
+
+static int cfURLSetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	if (objPtr->bytes) {
+		objPtr->internalRep.otherValuePtr = (void*)CFURLCreateWithBytes(NULL, 
+												objPtr->bytes,
+												objPtr->length,
+												kCFStringEncodingUTF8,
+												NULL);
+		if (objPtr->internalRep.otherValuePtr == NULL) return TCL_ERROR;
+		return TCL_OK;
+	} else {
+		return TCL_ERROR;
+	}
+}
+
+static void cfURLUpdateStringProc(Tcl_Obj* objPtr) {
+	CFURLRef url = objPtr->internalRep.otherValuePtr;
+	if (url) {
+		CFURLRef absurl = CFURLCopyAbsoluteURL(url);
+		if (absurl) {
+			CFStringRef str = CFURLGetString(absurl);
+			cfTypeUpdateStringProc2(objPtr, str);
+			CFRelease(absurl);
+		}
+	}
+}
+
+static void cfURLRegister() {
+	static Tcl_ObjType cfURLType;
+	cfURLType.name = "CFURL";
+	cfURLType.freeIntRepProc = cfTypeFreeInternalRepProc;
+	cfURLType.dupIntRepProc = cfTypeDupInternalRepProc;
+	cfURLType.updateStringProc = cfURLUpdateStringProc;
+	cfURLType.setFromAnyProc = cfURLSetFromAnyProc;
+	Tcl_RegisterObjType(&cfURLType);
+}
+
+
+
+
+/* CFBase.h */
+
+static Tcl_Obj* cfTypeToTCLString(CFTypeRef cf) {
+	if (CFGetTypeID(cf) == CFStringGetTypeID()) {
+		return cfStringToTCLString(cf);
+	} else {
+		CFStringRef string = CFCopyDescription(cf);
+		return cfStringToTCLString(string);
+	}
+}
+
+
+// CFGetTypeID(cf)
+int tclCFGetTypeID(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
+	CFTypeRef cf;
+	Tcl_Obj* tcl_result;
+	if (objc != 2) {
+		Tcl_WrongNumArgs(interp, 1, objv, "cftype");
+		return TCL_ERROR;
+	}
+	cf = objv[1]->internalRep.otherValuePtr;
+	if (cf) {
+		// xxx: test for valid objv[1]->typePtr;
+		tcl_result = Tcl_NewIntObj(CFGetTypeID(cf));
+		if (!tcl_result) return TCL_ERROR;
+		Tcl_SetObjResult(interp, tcl_result);
+		return TCL_OK;
+	} else {
+		return TCL_ERROR;
+	}
+}
+
+// CFNumberGetTypeID(), CFStringGetTypeID(), et al.
+int tclCFGetTypeID2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
+	Tcl_Obj* tcl_result;
+	if (objc != 1) {
+		Tcl_WrongNumArgs(interp, 1, objv, "");
+		return TCL_ERROR;
+	}
+	tcl_result = Tcl_NewIntObj((int)clientData);
+	if (!tcl_result) return TCL_ERROR;
+	Tcl_SetObjResult(interp, tcl_result);
+	return TCL_OK;
+}
+
+
+/* CFPropertyList.h */
+
+static int tclObjToCFPropertyList(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	*outPtr = NULL;
+	if (obj->typePtr == Tcl_GetObjType("CFString") ||
+		obj->typePtr == Tcl_GetObjType("CFData") ||
+		obj->typePtr == Tcl_GetObjType("CFNumber") ||
+		obj->typePtr == Tcl_GetObjType("CFArray") ||
+		obj->typePtr == Tcl_GetObjType("CFDictionary")) {
+		*outPtr = CFRetain(obj->internalRep.otherValuePtr);
+	} else {
+		return tclObjToCFString(interp, obj, outPtr);
+	}
+	return TCL_OK;
+}
+
+static int tclObjToCFPropertyListFormat(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	int result = TCL_OK, length;
+	char* buf = Tcl_GetStringFromObj(obj, &length);
+	*outPtr = NULL;
+	if (buf && strcmp(buf, "kCFPropertyListOpenStepFormat") == 0) {
+		*outPtr = (CFTypeRef) kCFPropertyListOpenStepFormat;
+	} else if (buf && strcmp(buf, "kCFPropertyListXMLFormat_v1_0") == 0) {
+		*outPtr = (CFTypeRef) kCFPropertyListXMLFormat_v1_0;
+	} else if (buf && strcmp(buf, "kCFPropertyListBinaryFormat_v1_0") == 0) {
+		*outPtr = (CFTypeRef) kCFPropertyListBinaryFormat_v1_0;
+	} else {
+		Tcl_Obj* tcl_result = Tcl_NewStringObj("invalid property list format constant", -1);
+		Tcl_SetObjResult(interp, tcl_result);
+		result = TCL_ERROR;
+	}
+	return result;
+}
+
+static int tclObjToCFMutabilityOption(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	int result = TCL_OK, length;
+	char* buf = Tcl_GetStringFromObj(obj, &length);
+	*outPtr = NULL;
+	if (buf && strcmp(buf, "kCFPropertyListImmutable") == 0) {
+		*outPtr = (CFTypeRef) kCFPropertyListImmutable;
+	} else if (buf && strcmp(buf, "kCFPropertyListMutableContainers") == 0) {
+		*outPtr = (CFTypeRef) kCFPropertyListMutableContainers;
+	} else if (buf && strcmp(buf, "kCFPropertyListMutableContainersAndLeaves") == 0) {
+		*outPtr = (CFTypeRef) kCFPropertyListMutableContainersAndLeaves;
+	} else {
+		Tcl_Obj* tcl_result = Tcl_NewStringObj("invalid mutability option constant", -1);
+		Tcl_SetObjResult(interp, tcl_result);
+		result = TCL_ERROR;
+	}
+	return result;
+}
+
+
+
+/* CFBundle.h */
+/* CFBundle ObjType */
+
+static int tclObjToCFBundle(Tcl_Interp* interp, Tcl_Obj* obj, CFTypeRef* outPtr) {
+	*outPtr = NULL;
+	if (obj->typePtr == Tcl_GetObjType("CFBundle")) {
+		*outPtr = CFRetain(obj->internalRep.otherValuePtr);
+	} else {
+		Tcl_Obj* tcl_result = Tcl_NewStringObj("argument must be a CFBundle", -1);
+		Tcl_SetObjResult(interp, tcl_result);
+		return TCL_ERROR;
+	}
+	return TCL_OK;
+}
+
+static int cfBundleSetFromAnyProc(Tcl_Interp* interp, Tcl_Obj* objPtr) {
+	Tcl_Obj* tcl_result = Tcl_NewStringObj("CFBundles must be created with CFBundleCreate", -1);
+	Tcl_SetObjResult(interp, tcl_result);
+	return TCL_ERROR;
+}
+
+static void cfBundleUpdateStringProc(Tcl_Obj* objPtr) {
+	CFBundleRef bundle = objPtr->internalRep.otherValuePtr;
+	if (bundle) {
+		CFStringRef description = CFCopyDescription(bundle);
+		if (description) {
+			CFIndex length = CFStringGetLength(description);
+			CFIndex size = CFStringGetMaximumSizeForEncoding(length + 1, kCFStringEncodingUTF8);
+			objPtr->bytes = Tcl_Alloc(size);
+			if (objPtr->bytes) {
+				CFIndex bytesUsed;
+				CFStringGetBytes(description, CFRangeMake(0, length), kCFStringEncodingUTF8, '?', 0, objPtr->bytes, size, &bytesUsed);
+				objPtr->length = bytesUsed;
+				objPtr->bytes[bytesUsed] = 0;	// terminating NUL as per TCL spec.
+			}
+			CFRelease(description);
+		}
+	}
+}
+
+static void cfBundleDupInternalRepProc(Tcl_Obj* srcPtr, Tcl_Obj* dupPtr) {
+	CFBundleRef bundle = srcPtr->internalRep.otherValuePtr;
+	dupPtr->internalRep.otherValuePtr = bundle ? (void*)CFRetain(bundle) : NULL;
+}
+
+static void cfBundleFreeInternalRepProc(Tcl_Obj* objPtr) {
+	CFBundleRef bundle = objPtr->internalRep.otherValuePtr;
+	if (bundle) CFRelease(bundle);
+}
+
+static void cfBundleRegister() {
+	static Tcl_ObjType cfBundleType;
+	cfBundleType.name = "CFBundle";
+	cfBundleType.freeIntRepProc = cfBundleFreeInternalRepProc;
+	cfBundleType.dupIntRepProc = cfBundleDupInternalRepProc;
+	cfBundleType.updateStringProc = cfBundleUpdateStringProc;
+	cfBundleType.setFromAnyProc = cfBundleSetFromAnyProc;
+	Tcl_RegisterObjType(&cfBundleType);
+}
+
+enum {
+	LITERAL,
+	CFTYPE,
+	CFRANGE,
+	CFINDEX,
+	CFERRORSTR,
+	END
+};
+
+typedef struct cfParam {
+	int kind;			// LITERAL (doesn't pop argument), CFTYPE (32bit), CFRANGE (64bit)
+	char* class;		// if present, type check, if null, don't type check.
+	int (*func)(Tcl_Interp*, Tcl_Obj*, CFTypeRef*);	// conversion function or literal value.
+} cfParam;
+
+typedef struct cfSignature {
+	char* name;			// name of CF function to call
+	void* func;			// pointer to CF function to call
+	char* format;		// tcl format string
+	char* result;		// type of result
+	int releaseResult;	// true if result should be released (create and copy funcs)
+	cfParam argv[10];	// description of arguments
+} cfSignature;
+
+
+static int tclCFFunc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
+	cfSignature* sig = (cfSignature*)clientData;
+	int result = TCL_OK;
+	Tcl_Obj* tcl_result;
+	void* res;
+	
+	int i, j, k;
+	void** args;
+
+	// iterate through argv and count up all non-LITERALs
+	// this is the expected objc.
+	for (i = 0, j = 1; sig->argv[i].kind != END; ++i) {
+		if (sig->argv[i].kind != LITERAL && sig->argv[i].kind != CFERRORSTR) ++j;
+	}
+
+	if (objc != j) {
+		Tcl_WrongNumArgs(interp, 1, objv, sig->format);
+		return TCL_ERROR;
+	}
+	
+	args = (void**)Tcl_Alloc(sizeof(void*) * /* argc */ 20);
+
+	for (i = 0, j = 0, k = 1; sig->argv[j].kind != END; ++i, ++j) {
+		// i is index to local args array.
+		// j is index to argv
+		// k is index to objv
+		
+		// Copy literal value, don't pop from Tcl stack.
+		switch (sig->argv[j].kind) {
+			case LITERAL:
+				args[i] = (void*)sig->argv[j].func;
+				break;
+			
+			case CFTYPE:
+				// test that the classes match, if both are set.
+				//if (!sig->argv[j].class || objv[k]->typePtr == NULL || objv[k]->typePtr == Tcl_GetObjType(sig->argv[j].class)) {
+					result = sig->argv[j].func(interp, objv[k], (CFTypeRef*) &args[i]);
+				//} else {
+				//	Tcl_Obj* tcl_result = Tcl_NewStringObj("argument must be a ", -1);
+				//	Tcl_AppendToObj(tcl_result, sig->argv[j].class, -1);
+				//	Tcl_SetObjResult(interp, tcl_result);
+				//	result = TCL_ERROR;
+				//}
+				++k;
+				break;
+				
+			case CFINDEX:
+				result = Tcl_GetIntFromObj(interp, objv[k], (int*) &args[i]);
+				++k;
+				break;
+				
+			case CFERRORSTR:
+				args[i] = (void*) Tcl_Alloc(sizeof(CFStringRef));
+				break;
+				
+			case CFRANGE:
+				++k;
+			default:
+				break;
+		}
+		if (result != TCL_OK) break;
+	}
+	
+	if (result == TCL_OK) {
+	objc = i;
+	if (objc == 0) {
+		res = ((void* (*)())sig->func)();
+	} else if (objc == 1) {
+		res = ((void* (*)(void*))sig->func)(args[0]);
+	} else if (objc == 2) {
+		res = ((void* (*)(void*,void*))sig->func)(args[0],args[1]);
+	} else if (objc == 3) {
+		res = ((void* (*)(void*,void*,void*))sig->func)(args[0],args[1],args[2]);
+	} else if (objc == 4) {
+		res = ((void* (*)(void*,void*,void*,void*))sig->func)(args[0],args[1],args[2],args[3]);
+	} else if (objc == 5) {
+		res = ((void* (*)(void*,void*,void*,void*,void*))sig->func)(args[0],args[1],args[2],args[3],args[4]);
+	} else if (objc == 6) {
+		res = ((void* (*)(void*,void*,void*,void*,void*,void*))sig->func)(args[0],args[1],args[2],args[3],args[4],args[5]);
+	}
+
+	if (sig->result && strcmp(sig->result, "void") != 0) {
+		tcl_result = Tcl_NewObj();
+		tcl_result->bytes = NULL;
+		tcl_result->length = 0;
+		if (strcmp(sig->result, "CFType") == 0) {
+			if (res) {
+				CFTypeID id = CFGetTypeID(res);
+				if (id == CFStringGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFString");
+				else if (id == CFNumberGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFNumber");
+				else if (id == CFDataGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFData");
+				else if (id == CFURLGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFURL");
+				else if (id == CFBundleGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFBundle");
+				else if (id == CFDictionaryGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFDictionary");
+				else if (id == CFArrayGetTypeID()) tcl_result->typePtr = Tcl_GetObjType("CFArray");
+				else tcl_result->typePtr = Tcl_GetObjType("CFType");
+				tcl_result->internalRep.otherValuePtr = (void*)CFRetain(res);
+				Tcl_SetObjResult(interp, tcl_result);
+				if (sig->releaseResult) CFRelease(res);
+			} else {
+				tcl_result->typePtr = NULL;
+				tcl_result->internalRep.otherValuePtr = NULL;
+			}
+		} else if (strcmp(sig->result, "CFIndex") == 0) {
+			tcl_result = Tcl_NewIntObj((int)res);
+			Tcl_SetObjResult(interp, tcl_result);
+		}
+	}
+	} // end TCL_OK
+	
+	for (i = 0; sig->argv[i].kind != END; ++i) {
+		if (sig->argv[i].kind == CFERRORSTR && result == TCL_OK) {
+			if (*((CFStringRef*)args[i])) {
+				Tcl_Obj* tcl_result = cfStringToTCLString(*((CFStringRef*)args[i]));
+				Tcl_SetObjResult(interp, tcl_result);
+				result = TCL_ERROR;
+			}
+			Tcl_Free(args[i]);
+		}
+	}
+	
+	if (args) Tcl_Free((char*)args);
+	
+	return result;
+}
+
+int Cflib_Init(Tcl_Interp *interp)
+{
+	int i;
+	static cfSignature sig[] = {
+		/* CFBundle.h */
+		{
+			"CFBundleGetMainBundle", CFBundleGetMainBundle, "", "CFType", 0,
+			{ 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetBundleWithIdentifier", CFBundleGetBundleWithIdentifier, "", "CFType", 0,
+			{
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetAllBundles", CFBundleGetAllBundles, "", "CFType", 0,
+			{ 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCreate", CFBundleCreate, "bundleURL", "CFType", 1,
+			{ 
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, "CFURL", tclObjToCFURL },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCreateBundlesFromDirectory", CFBundleCreateBundlesFromDirectory, "directoryURL bundleType", "CFType", 1,
+			{ 
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, "CFURL", tclObjToCFURL },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyBundleURL", CFBundleCopyBundleURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetValueForInfoDictionaryKey", CFBundleGetValueForInfoDictionaryKey, "bundle key", "CFType", 0,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetInfoDictionary", CFBundleGetInfoDictionary, "bundle", "CFType", 0,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetLocalInfoDictionary", CFBundleGetLocalInfoDictionary, "bundle", "CFType", 0,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		// CFBundleGetPackageInfo
+		{
+			"CFBundleGetIdentifier", CFBundleGetIdentifier, "bundle", "CFType", 0,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetVersionNumber", CFBundleGetVersionNumber, "bundle", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleGetDevelopmentRegion", CFBundleGetDevelopmentRegion, "bundle", "CFType", 0,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopySupportFilesDirectoryURL", CFBundleCopySupportFilesDirectoryURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyResourcesDirectoryURL", CFBundleCopyResourcesDirectoryURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyPrivateFrameworksURL", CFBundleCopyPrivateFrameworksURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopySharedFrameworksURL", CFBundleCopySharedFrameworksURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopySharedSupportURL", CFBundleCopySharedSupportURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyBuiltInPlugInsURL", CFBundleCopyBuiltInPlugInsURL, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyInfoDictionaryInDirectory", CFBundleCopyResourcesDirectoryURL, "bundelURL", "CFType", 1,
+			{
+				{ CFTYPE, "CFURL", tclObjToCFURL },
+				{ END, NULL, NULL }
+			}
+		},
+		// CFBundleGetPackageInfoInDirectory
+		{
+			"CFBundleCopyResourceURL", CFBundleCopyResourceURL, "bundle resourceName resourceType subDirName", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyResourceURLsOfType", CFBundleCopyResourceURLsOfType, "bundle resourceType subDirName", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFType },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyLocalizedString", CFBundleCopyLocalizedString, "bundle key value tableName", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyResourceURLInDirectory", CFBundleCopyResourceURLInDirectory, "bundleURL resourceName resourceType subDirName", "CFType", 1,
+			{
+				{ CFTYPE, "CFURL", tclObjToCFURL },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyResourceURLsOfTypeInDirectory", CFBundleCopyResourceURLsOfTypeInDirectory, "bundleURL resourceType subDirName", "CFType", 1,
+			{
+				{ CFTYPE, "CFURL", tclObjToCFURL },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ CFTYPE, "CFString", tclObjToCFString },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyBundleLocalizations", CFBundleCopyBundleLocalizations, "bundle", "CFType", 1,
+			{
+				{ CFTYPE, "CFBundle", tclObjToCFBundle },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyPreferredLocalizationsFromArray", CFBundleCopyPreferredLocalizationsFromArray, "locArray", "CFType", 1,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFBundleCopyLocalizationsForPreferences", CFBundleCopyPreferredLocalizationsFromArray, "locArray prefArray", "CFType", 1,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ END, NULL, NULL }
+			}
+		},
+		// CFBundleCopyResourceURLForLocalization
+		// CFBundleCopyResourceURLsOfTypeForLocalization
+		// CFBundleCopyInfoDictionaryForURL
+		// CFBundleCopyLocalizationsForURL
+
+		/* CFPropertyList.h */
+		{
+			"CFPropertyListCreateFromXMLData", CFPropertyListCreateFromXMLData, "xmlData mutabilityOption", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, "CFData", tclObjToCFData },
+				{ CFTYPE, NULL, tclObjToCFMutabilityOption },
+				{ CFERRORSTR, NULL, NULL }, // xxx: error string
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFPropertyListCreateXMLData", CFPropertyListCreateXMLData, "propertyList", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, NULL, tclObjToCFPropertyList }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFPropertyListCreateDeepCopy", CFPropertyListCreateDeepCopy, "propertyList mutabilityOption", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, NULL, tclObjToCFPropertyList },
+				{ CFTYPE, NULL, tclObjToCFMutabilityOption },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFPropertyListIsValid", CFPropertyListIsValid, "propertyList format", "CFIndex", 1,
+			{
+				{ CFTYPE, NULL, tclObjToCFPropertyList },
+				{ CFTYPE, NULL, tclObjToCFPropertyListFormat },
+				{ END, NULL, NULL }
+			}
+		},
+		
+		// CFPropertyListWriteToStream
+		// CFPropertyListCreateFromStream
+		
+		/* CFArray.h */
+		// CFArrayCreate
+		{
+			"CFArrayCreateCopy", CFArrayCreateCopy, "theArray", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, "CFArray", NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayCreateMutable", CFArrayCreateMutable, "capacity", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFINDEX, "CFIndex", NULL },
+				{ LITERAL, NULL, (void*)&kCFTypeArrayCallBacks },	// xxx: func to handle callbacks
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayCreateMutableCopy", CFArrayCreateMutableCopy, "capacity theArray", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFINDEX, "CFIndex", NULL },
+				{ CFTYPE, "CFArray", NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayGetCount", CFDictionaryGetCount, "theArray", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayGetCountOfValue", CFArrayGetCountOfValue, "theArray start end value", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },	// xxx: these part of CFRange
+				{ CFINDEX, NULL, NULL }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayContainsValue", CFArrayContainsValue, "theArray start end value", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },	// xxx: these part of CFRange
+				{ CFINDEX, NULL, NULL }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayGetValueAtIndex", CFArrayGetValueAtIndex, "theArray index", "CFType", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL }, 
+				{ END, NULL, NULL }
+			}
+		},
+		// CFArrayGetValues
+		// CFArrayApplyFunction
+		{
+			"CFArrayGetFirstIndexOfValue", CFArrayGetFirstIndexOfValue, "theArray start end value", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },	// xxx: these part of CFRange
+				{ CFINDEX, NULL, NULL }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayGetLastIndexOfValue", CFArrayGetLastIndexOfValue, "theArray start end value", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },	// xxx: these part of CFRange
+				{ CFINDEX, NULL, NULL }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		// CFArrayBSearchValues
+		{
+			"CFArrayAppendValue", CFArrayAppendValue, "theArray index", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayInsertValueAtIndex", CFArrayInsertValueAtIndex, "theArray index value", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArraySetValueAtIndex", CFArraySetValueAtIndex, "theArray index value", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayRemoveValueAtIndex", CFArrayRemoveValueAtIndex, "theArray index", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFArrayRemoveAllValues", CFArrayRemoveAllValues, "theArray", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ END, NULL, NULL }
+			}
+		},
+		// CFArrayReplaceValues
+		{
+			"CFArrayExchangeValuesAtIndices", CFArrayExchangeValuesAtIndices, "theArray idx1 idx2", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },
+				{ CFINDEX, NULL, NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		// CFArraySortValues
+		{
+			"CFArrayAppendArray", CFArrayAppendArray, "theArray otherArray start end", "void", 0,
+			{
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFTYPE, "CFArray", tclObjToCFArray },
+				{ CFINDEX, NULL, NULL },
+				{ CFINDEX, NULL, NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		
+		
+		/* CFDictionary.h */
+		// CFDictionaryCreate
+		{
+			"CFDictionaryCreateCopy", CFDictionaryCreateCopy, "theDict", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFTYPE, "CFDictionary", NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryCreateMutable", CFDictionaryCreateMutable, "capacity", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFINDEX, "CFIndex", NULL },
+				{ LITERAL, NULL, (void*)&kCFTypeDictionaryKeyCallBacks },	// xxx: func to handle callbacks
+				{ LITERAL, NULL, (void*)&kCFTypeDictionaryValueCallBacks }, // xxx: func to handle callbacks
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryCreateMutableCopy", CFDictionaryCreateMutableCopy, "capacity theDict", "CFType", 1,
+			{
+				{ LITERAL, NULL, NULL },
+				{ CFINDEX, "CFIndex", NULL },
+				{ CFTYPE, "CFDictionary", NULL },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryGetCount", CFDictionaryGetCount, "dictionary", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryGetCountOfKey", CFDictionaryGetCountOfKey, "dictionary key", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryGetCountOfValue", CFDictionaryGetCountOfValue, "dictionary value", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryContainsKey", CFDictionaryContainsKey, "dictionary key", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryContainsValue", CFDictionaryContainsValue, "dictionary value", "CFIndex", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryGetValue", CFDictionaryGetValue, "dictionary key", "CFType", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		// CFDictionaryGetValueIfPresent
+		// CFDictionaryGetKeysAndValues
+		// CFDictionaryApplyFunction
+		{
+			"CFDictionaryAddValue", CFDictionaryAddValue, "dictionary key value", "void", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionarySetValue", CFDictionarySetValue, "dictionary key value", "void", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryReplaceValue", CFDictionaryReplaceValue, "dictionary key value", "void", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryRemoveValue", CFDictionaryRemoveValue, "dictionary key", "void", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ CFTYPE, NULL, tclObjToCFType }, 
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			"CFDictionaryRemoveAllValues", CFDictionaryRemoveAllValues, "dictionary", "void", 0,
+			{
+				{ CFTYPE, "CFDictionary", tclObjToCFDictionary },
+				{ END, NULL, NULL }
+			}
+		},
+		{
+			NULL, NULL, NULL, NULL, 0, { { END, NULL, NULL } }
+		}
+	};
+
+	if(Tcl_InitStubs(interp, "8.3", 0) == NULL)
+		return TCL_ERROR;
+
+	for (i = 0; sig[i].name != NULL; ++i) {
+		Tcl_CreateObjCommand(interp, sig[i].name, tclCFFunc, &sig[i], NULL);
+	}
+
+	cfTypeRegister();
+	cfStringRegister();
+	cfNumberRegister();
+	cfDataRegister();
+	cfBundleRegister();
+	cfURLRegister();
+	cfDictionaryRegister();
+	cfArrayRegister();
+	
+	Tcl_CreateObjCommand(interp, "CFGetTypeID", tclCFGetTypeID, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "CFStringGetTypeID", tclCFGetTypeID2, (void*)CFStringGetTypeID(), NULL);
+	Tcl_CreateObjCommand(interp, "CFNumberCreate", tclCFNumberCreate, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "CFNumberGetTypeID", tclCFGetTypeID2, (void*)CFNumberGetTypeID(), NULL);
+	Tcl_CreateObjCommand(interp, "CFURLGetTypeID", tclCFGetTypeID2, (void*)CFURLGetTypeID(), NULL);
+	Tcl_CreateObjCommand(interp, "CFBundleGetTypeID", tclCFGetTypeID2, (void*)CFBundleGetTypeID(), NULL);
+	Tcl_CreateObjCommand(interp, "CFDictionaryGetTypeID", tclCFGetTypeID2, (void*)CFDictionaryGetTypeID(), NULL);
+	Tcl_CreateObjCommand(interp, "CFArrayGetTypeID", tclCFGetTypeID2, (void*)CFArrayGetTypeID(), NULL);
+	//Tcl_CreateObjCommand(interp, "CFBundleCreateBundlesFromDirectory", tclCFBundleCreateBundlesFromDirectory, NULL, NULL);
+
+	if(Tcl_PkgProvide(interp, "CFLib", "1.0") != TCL_OK)
+		return TCL_ERROR;
+	return TCL_OK;
+}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070411/7b2a645d/attachment.html


More information about the macports-changes mailing list