[57383] users/toby/objcports
toby at macports.org
toby at macports.org
Thu Sep 10 02:46:02 PDT 2009
Revision: 57383
http://trac.macports.org/changeset/57383
Author: toby at macports.org
Date: 2009-09-10 02:46:02 -0700 (Thu, 10 Sep 2009)
Log Message:
-----------
finish converting to C - leaks like crazy though
Modified Paths:
--------------
users/toby/objcports/MPPort.h
users/toby/objcports/internal.c
users/toby/objcports/internal.h
users/toby/objcports/objcports.xcodeproj/project.pbxproj
Added Paths:
-----------
users/toby/objcports/MPPort.c
users/toby/objcports/port.c
Removed Paths:
-------------
users/toby/objcports/MPPort.m
users/toby/objcports/port.m
Copied: users/toby/objcports/MPPort.c (from rev 57371, users/toby/objcports/MPPort.m)
===================================================================
--- users/toby/objcports/MPPort.c (rev 0)
+++ users/toby/objcports/MPPort.c 2009-09-10 09:46:02 UTC (rev 57383)
@@ -0,0 +1,641 @@
+#include <CoreFoundation/CoreFoundation.h>
+#include <tcl.h>
+#include <sys/utsname.h>
+#include <mach-o/getsect.h>
+
+#include "MPPort.h"
+#include "MPArrayAdditions.h"
+#include "MPStringAdditions.h"
+#include "internal.h"
+
+struct mp_port_s {
+ CFURLRef _url;
+
+ CFMutableDictionaryRef _variableInfo;
+ CFMutableDictionaryRef _variables;
+
+ CFMutableArrayRef _platforms;
+ CFMutableDictionaryRef _variants;
+
+ Tcl_Interp *_interp;
+};
+
+static CFStringRef kPortVariableType = CFSTR("Type");
+static CFStringRef kPortVariableConstant = CFSTR("Constant");
+static CFStringRef kPortVariableDefault = CFSTR("Default");
+static CFStringRef kPortVariableCallback = CFSTR("Callback");
+
+static void command_create(Tcl_Interp *interp, const char *cmdName, ClientData clientData);
+static char *variable_read(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags);
+static int _nslog(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+static int _fake_boolean(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+
+static CFStringRef mp_port_portfile(mp_port_t);
+static CFArrayRef mp_port_targets(mp_port_t);
+static CFArrayRef mp_port_variables(mp_port_t);
+static CFArrayRef mp_port_settable_variables(mp_port_t);
+static CFArrayRef mp_port_settable_array_variables(mp_port_t);
+
+static Boolean mp_port_variable_is_array(mp_port_t, CFStringRef var);
+
+// essentially 'commands' from portutil.tcl
+static void
+add_command_var(CFMutableDictionaryRef varinfo, CFStringRef command)
+{
+ CFDictionaryRef emptydict;
+ CFMutableDictionaryRef arraydict;
+
+ emptydict = CFDictionaryCreate(NULL, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ arraydict = CFDictionaryCreateMutable(NULL, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(arraydict, kPortVariableType, CFSTR("Array"));
+
+ void (^addcomm_block)(CFStringRef, CFDictionaryRef) = ^(CFStringRef format, CFDictionaryRef dict) {
+ CFStringRef tmp;
+
+ tmp = CFStringCreateWithFormat(NULL, NULL, format, command);
+ CFDictionarySetValue(varinfo, tmp, dict);
+ CFRelease(tmp);
+ };
+
+ addcomm_block(CFSTR("use_%@"), emptydict);
+ addcomm_block(CFSTR("%@.dir"), emptydict);
+ addcomm_block(CFSTR("%@.pre_args"), arraydict);
+ addcomm_block(CFSTR("%@.args"), arraydict);
+ addcomm_block(CFSTR("%@.post_args"), arraydict);
+ addcomm_block(CFSTR("%@.env"), arraydict);
+ addcomm_block(CFSTR("%@.type"), emptydict);
+ addcomm_block(CFSTR("%@.cmd"), arraydict);
+
+ CFRelease(emptydict);
+ CFRelease(arraydict);
+}
+
+mp_port_t
+mp_port_create(CFURLRef url, CFDictionaryRef options)
+{
+ mp_port_t port;
+ char *sectdata;
+ unsigned long sectsize;
+ CFDataRef vdata;
+
+ port = calloc(1, sizeof(struct mp_port_s));
+
+ port->_url = CFRetain(url);
+
+ port->_platforms = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ port->_variants = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ port->_variables = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ sectdata = getsectdata("MacPorts", "variables", §size);
+ assert(sectdata);
+ vdata = CFDataCreateWithBytesNoCopy(NULL, (UInt8 *)sectdata, sectsize, kCFAllocatorNull);
+ port->_variableInfo = (CFMutableDictionaryRef)CFPropertyListCreateWithData(NULL, vdata, kCFPropertyListMutableContainersAndLeaves, NULL, NULL);
+ CFRelease(vdata);
+
+ add_command_var(port->_variableInfo, CFSTR("cvs")); // portfetch.tcl
+ add_command_var(port->_variableInfo, CFSTR("svn")); // portfetch.tcl
+ add_command_var(port->_variableInfo, CFSTR("extract")); // portextract.tcl
+ add_command_var(port->_variableInfo, CFSTR("patch")); // portpatch.tcl
+ add_command_var(port->_variableInfo, CFSTR("configure")); // portconfigure.tcl
+ add_command_var(port->_variableInfo, CFSTR("autoreconf")); // portconfigure.tcl
+ add_command_var(port->_variableInfo, CFSTR("automake")); // portconfigure.tcl
+ add_command_var(port->_variableInfo, CFSTR("autoconf")); // portconfigure.tcl
+ add_command_var(port->_variableInfo, CFSTR("xmkmf")); // portconfigure.tcl
+ add_command_var(port->_variableInfo, CFSTR("build")); // portbuild.tcl
+ add_command_var(port->_variableInfo, CFSTR("test")); // porttest.tcl
+ add_command_var(port->_variableInfo, CFSTR("destroot")); // portdestroot.tcl
+
+ port->_interp = Tcl_CreateInterp();
+ Tcl_MakeSafe(port->_interp);
+ Tcl_UnsetVar(port->_interp, "tcl_version", 0);
+ Tcl_UnsetVar(port->_interp, "tcl_patchLevel", 0);
+ Tcl_UnsetVar(port->_interp, "tcl_platform", 0);
+ Tcl_DeleteCommand(port->_interp, "tell");
+ Tcl_DeleteCommand(port->_interp, "eof");
+ // XXX: etc?
+
+ do {
+ Tcl_Preserve(port->_interp);
+
+ Tcl_CreateObjCommand(port->_interp, "nslog", _nslog, NULL, NULL); // XXX: debugging
+ //Tcl_Eval(_interp, "nslog [info commands]");
+
+ command_create(port->_interp, "PortSystem", port);
+ command_create(port->_interp, "PortGroup", port);
+ command_create(port->_interp, "platform", port);
+ command_create(port->_interp, "variant", port);
+
+ CFArrayApplyBlock2(mp_port_targets(port), ^(const void *target) {
+ CFStringRef tmp;
+ char *s;
+
+ s = strdup_cf(target);
+ command_create(port->_interp, s, port);
+ free(s);
+
+ tmp = CFStringCreateWithFormat(NULL, NULL, CFSTR("pre-%@"), target);
+ s = strdup_cf(tmp);
+ command_create(port->_interp, s, port);
+ free(s);
+ CFRelease(tmp);
+
+ tmp = CFStringCreateWithFormat(NULL, NULL, CFSTR("post-%@"), target);
+ s = strdup_cf(tmp);
+ command_create(port->_interp, s, port);
+ free(s);
+ CFRelease(tmp);
+ });
+
+ CFArrayApplyBlock2(mp_port_settable_variables(port), ^(const void *opt) {
+ char *s = strdup_cf(opt);
+ command_create(port->_interp, s, port);
+ free(s);
+ });
+
+ CFArrayApplyBlock2(mp_port_settable_array_variables(port), ^(const void *opt) {
+ CFStringRef tmp;
+ char *s;
+
+ tmp = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-append"), opt);
+ s = strdup_cf(tmp);
+ command_create(port->_interp, s, port);
+ free(s);
+ CFRelease(tmp);
+
+ tmp = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-delete"), opt);
+ s = strdup_cf(tmp);
+ command_create(port->_interp, s, port);
+ free(s);
+ CFRelease(tmp);
+ });
+
+ CFArrayApplyBlock2(mp_port_variables(port), ^(const void *var) {
+ char *s = strdup_cf(var);
+ Tcl_TraceVar(port->_interp, s, TCL_TRACE_READS, variable_read, port);
+ free(s);
+ });
+
+ // bogus targets
+ Tcl_CreateObjCommand(port->_interp, "pre-activate", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "post-activate", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "pre-install", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "post-install", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "post-pkg", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "post-mpkg", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "archive", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "install", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "activate", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "unarchive", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "post-clean", _nslog, NULL, NULL); // XXX: debugging
+
+ // functions we need to provide (?)
+ Tcl_CreateObjCommand(port->_interp, "variant_isset", _fake_boolean, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "variant_set", _fake_boolean, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "tbool", _fake_boolean, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "strsed", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "suffix", _nslog, NULL, NULL); // XXX: debugging
+ Tcl_CreateObjCommand(port->_interp, "include", _nslog, NULL, NULL); // XXX: debugging
+
+ // variables that should be constant
+ Tcl_CreateObjCommand(port->_interp, "prefix", _nslog, NULL, NULL);
+
+ char *s = strdup_cf(mp_port_portfile(port));
+ if (Tcl_EvalFile(port->_interp, s) != TCL_OK) {
+ fprintf(stderr, "Tcl_EvalFile(): %s\n", Tcl_GetStringResult(port->_interp));
+ exit(1);
+ }
+
+ Tcl_Release(port->_interp);
+ } while (0);
+
+ return port;
+}
+
+void
+mp_port_destroy(mp_port_t port)
+{
+ CFRelease(port->_url);
+
+ CFRelease(port->_variableInfo);
+ CFRelease(port->_variables);
+
+ CFRelease(port->_platforms);
+ CFRelease(port->_variants);
+
+ Tcl_DeleteInterp(port->_interp);
+
+ free(port); // XXX
+}
+
+CFStringRef
+mp_port_variable(mp_port_t port, CFStringRef name)
+{
+ CFDictionaryRef info;
+ CFTypeRef setValue;
+ CFTypeRef defValue;
+ CFTypeRef callback;
+ CFStringRef ret = nil;
+
+ info = CFDictionaryGetValue(port->_variableInfo, name);
+ if (info != NULL) {
+ if ((setValue = CFDictionaryGetValue(port->_variables, name))) {
+ if (mp_port_variable_is_array(port, name)) {
+ assert(CFGetTypeID(setValue) == CFArrayGetTypeID());
+ ret = CFStringCreateByCombiningStrings(NULL, setValue, CFSTR(" "));
+ } else {
+ assert(CFGetTypeID(setValue) == CFStringGetTypeID());
+ ret = CFRetain(setValue);
+ }
+ } else if ((defValue = CFDictionaryGetValue(info, kPortVariableDefault))) {
+ ret = CFRetain(defValue);
+ } else if ((callback = CFDictionaryGetValue(info, kPortVariableCallback))) {
+ assert(CFGetTypeID(callback) == CFStringGetTypeID());
+ // XXX
+ //ret = [self performSelector:NSSelectorFromString(callback) withObject:name];
+ ret = CFSTR("callback unimplemented");
+ } else {
+ ret = CFSTR("");
+ }
+ char *s = strdup_cf(ret);
+ ret = CFStringCreateWithTclObject(NULL, Tcl_SubstObj(port->_interp, Tcl_NewStringObj(s, -1), TCL_SUBST_VARIABLES));
+ free(s);
+ } else {
+ fprintf_cf(stderr, CFSTR("WARNING: unknown variable %@\n"), name);
+ }
+ return ret;
+}
+
+CFStringRef
+mp_port_portfile(mp_port_t port)
+{
+ CFStringRef path;
+ path = CFURLCopyStrictPath(port->_url, NULL);
+ return CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/Portfile"), path);
+}
+
+CFArrayRef
+mp_port_targets(mp_port_t port)
+{
+ CFMutableArrayRef results;
+
+ results = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(results, CFSTR("fetch"));
+ CFArrayAppendValue(results, CFSTR("checksum"));
+ CFArrayAppendValue(results, CFSTR("extract"));
+ CFArrayAppendValue(results, CFSTR("patch"));
+ CFArrayAppendValue(results, CFSTR("configure"));
+ CFArrayAppendValue(results, CFSTR("build"));
+ CFArrayAppendValue(results, CFSTR("test"));
+ CFArrayAppendValue(results, CFSTR("destroot"));
+
+ return results;
+}
+
+static Boolean
+mp_port_is_target(mp_port_t port, CFStringRef target)
+{
+ CFArrayRef tmp;
+
+ if (CFStringHasPrefix(target, CFSTR("pre-"))) {
+ target = CFStringCreateWithSubstring(NULL, target, CFRangeMake(4, CFStringGetLength(target) - 4));
+ } else if (CFStringHasPrefix(target, CFSTR("post-"))) {
+ target = CFStringCreateWithSubstring(NULL, target, CFRangeMake(5, CFStringGetLength(target) - 5));
+ }
+
+ tmp = mp_port_targets(port);
+ return CFArrayContainsValue(tmp, CFRangeMake(0, CFArrayGetCount(tmp)), target);
+}
+
+CFArrayRef
+mp_port_variables(mp_port_t port)
+{
+ CFIndex count = CFDictionaryGetCount(port->_variableInfo);
+ const void *keys[count];
+ CFArrayRef vars;
+
+ CFDictionaryGetKeysAndValues(port->_variableInfo, keys, NULL);
+ vars = CFArrayCreate(NULL, keys, count, &kCFTypeArrayCallBacks);
+
+ return vars;
+}
+
+static Boolean
+mp_port_variable_is_array(mp_port_t port, CFStringRef var)
+{
+ CFStringRef type;
+
+ type = CFDictionaryGetValue(CFDictionaryGetValue(port->_variableInfo, var), kPortVariableType);
+ return type && (CFStringCompare(type, CFSTR("Array"), 0) == kCFCompareEqualTo);
+}
+
+CFArrayRef
+mp_port_settable_variables(mp_port_t port)
+{
+ CFMutableArrayRef ret = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFArrayApplyBlock2(mp_port_variables(port), ^(const void *var) {
+ CFNumberRef constant = CFDictionaryGetValue(CFDictionaryGetValue(port->_variableInfo, var), kPortVariableConstant);
+ CFIndex b = 0;
+ if (constant) CFNumberGetValue(constant, kCFNumberCFIndexType, &b);
+
+ if (constant == NULL || b == 0) {
+ CFArrayAppendValue(ret, var);
+ }
+ });
+ return ret;
+}
+
+CFArrayRef
+mp_port_settable_array_variables(mp_port_t port)
+{
+ CFMutableArrayRef ret = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFArrayApplyBlock2(mp_port_settable_variables(port), ^(const void *var) {
+ if (mp_port_variable_is_array(port, var)) {
+ CFArrayAppendValue(ret, var);
+ }
+ });
+ return ret;
+}
+
+void
+mp_port_variable_set(mp_port_t port, CFStringRef var, CFArrayRef value)
+{
+ if (mp_port_variable_is_array(port, var)) {
+ CFDictionarySetValue(port->_variables, var, value);
+ } else {
+ CFStringRef str = CFStringCreateByCombiningStrings(NULL, value, CFSTR(" "));
+ CFDictionarySetValue(port->_variables, var, str);
+ CFRelease(str);
+ }
+}
+
+void
+mp_port_variable_append(mp_port_t port, CFStringRef var, CFArrayRef value)
+{
+ CFTypeRef old = CFDictionaryGetValue(port->_variables, var);
+ if (old) {
+ CFMutableArrayRef array;
+
+ assert(CFGetTypeID(old) == CFArrayGetTypeID());
+
+ array = CFArrayCreateMutableCopy(NULL, 0, old);
+ CFArrayAppendArray(array, value, CFRangeMake(0, CFArrayGetCount(value)));
+ CFDictionarySetValue(port->_variables, var, array);
+ CFRelease(array);
+ } else {
+ CFDictionarySetValue(port->_variables, var, value);
+ }
+}
+
+void
+mp_port_variable_delete(mp_port_t port, CFStringRef var, CFArrayRef value)
+{
+ CFTypeRef old;
+ CFMutableArrayRef tmp;
+
+ old = CFDictionaryGetValue(port->_variables, var);
+ if (old == NULL) {
+ return;
+ }
+ assert(CFGetTypeID(old) == CFArrayGetTypeID());
+ tmp = CFArrayCreateMutableCopy(NULL, 0, old);
+ CFArrayApplyBlock2(value, ^(const void *v) {
+ CFArrayRemoveValueAtIndex(tmp, CFArrayGetFirstIndexOfValue(tmp, CFRangeMake(0, CFArrayGetCount(tmp)), v));
+ });
+ CFDictionarySetValue(port->_variables, var, tmp);
+ CFRelease(tmp);
+}
+
+CFArrayRef
+mp_port_defined_platforms(mp_port_t port)
+{
+ CFMutableArrayRef ret = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFArrayApplyBlock2(port->_platforms, ^(const void *plat) {
+ CFStringRef tmp = CFStringCreateByCombiningStrings(NULL, plat, CFSTR("_"));
+ CFArrayAppendValue(ret, tmp);
+ CFRelease(tmp);
+ });
+ return ret;
+}
+
+Boolean
+mp_port_test_and_record_platform(mp_port_t port, CFArrayRef platform)
+{
+ struct utsname u;
+ CFStringRef os;
+ CFStringRef release;
+ CFStringRef arch;
+ CFTypeRef tmp;
+
+ CFArrayAppendValue(port->_platforms, platform);
+
+ assert(uname(&u) == 0);
+ os = CFStringCreateWithCString(NULL, u.sysname, kCFStringEncodingUTF8);
+ release = CFStringCreateWithCString(NULL, u.release, kCFStringEncodingUTF8);
+ arch = CFStringCreateWithCString(NULL, u.machine, kCFStringEncodingUTF8);
+
+ tmp = CFArrayGetValueAtIndex(platform, 0);
+ if (tmp != kCFNull && CFStringCompare(tmp, os, kCFCompareCaseInsensitive) != kCFCompareEqualTo) {
+ return FALSE;
+ }
+
+ tmp = CFArrayGetValueAtIndex(platform, 1);
+ if (tmp != kCFNull && CFStringCompare(tmp, release, kCFCompareCaseInsensitive) != kCFCompareEqualTo) {
+ return FALSE;
+ }
+
+ tmp = CFArrayGetValueAtIndex(platform, 2);
+ if (tmp != kCFNull && CFStringCompare(tmp, arch, kCFCompareCaseInsensitive) != kCFCompareEqualTo) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+CFArrayRef
+mp_port_defined_variants(mp_port_t port)
+{
+ CFIndex count = CFDictionaryGetCount(port->_variants);
+ const void *keys[count];
+ CFArrayRef vars;
+
+ CFDictionaryGetKeysAndValues(port->_variants, keys, NULL);
+ vars = CFArrayCreate(NULL, keys, count, &kCFTypeArrayCallBacks);
+
+ return vars;
+}
+
+Boolean
+mp_port_test_and_record_variant(mp_port_t port, CFStringRef variant, CFDictionaryRef props)
+{
+ // XXX: check for dupes (w/ platforms too)
+ CFDictionarySetValue(port->_variants, variant, props);
+ // XXX: make sure it's set, like platforms just pretend
+ return TRUE;
+}
+
+void
+mp_port_perform_command(mp_port_t port, CFArrayRef args)
+{
+ CFStringRef command;
+ CFIndex count;
+
+ command = CFArrayGetValueAtIndex(args, 0);
+ count = CFArrayGetCount(args);
+
+ if (CFStringCompare(command, CFSTR("PortSystem"), 0) == kCFCompareEqualTo) {
+ assert(count == 2);
+ assert(CFStringCompare(CFArrayGetValueAtIndex(args, 1), CFSTR("1.0"), 0) == kCFCompareEqualTo);
+ } else if (CFStringCompare(command, CFSTR("PortGroup"), 0) == kCFCompareEqualTo) {
+ fprintf_cf(stderr, CFSTR("ignoring %@, grps r hard m'kay\n"), command);
+ // XXX: this should probably set some state in parent port instance
+ // (ugh, more tcl parsing)
+ } else if (CFStringCompare(command, CFSTR("platform"), 0) == kCFCompareEqualTo) {
+ CFStringRef os = NULL;
+ CFTypeRef release = kCFNull;
+ CFTypeRef arch = kCFNull;
+
+ if (count < 3 || count > 5) {
+ fprintf(stderr, "bogus platform declaration\n");
+ return;
+ }
+
+ os = CFArrayGetValueAtIndex(args, 1);
+
+ if (count == 4) {
+ SInt32 rel = CFStringGetIntValue(CFArrayGetValueAtIndex(args, 2));
+ if (rel != 0) {
+ release = CFNumberCreate(NULL, kCFNumberIntType, &rel);
+ } else {
+ arch = CFArrayGetValueAtIndex(args, 2);
+ }
+ } else if (count == 5) {
+ SInt32 rel = CFStringGetIntValue(CFArrayGetValueAtIndex(args, 2));
+ release = CFNumberCreate(NULL, kCFNumberIntType, &rel);
+ arch = CFArrayGetValueAtIndex(args, 3);
+ }
+
+ CFMutableArrayRef platform = CFArrayCreateMutable(NULL, 3, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(platform, os);
+ CFArrayAppendValue(platform, release);
+ CFArrayAppendValue(platform, arch);
+
+ if (mp_port_test_and_record_platform(port, platform)) {
+ char *s = strdup_cf(CFArrayGetValueAtIndex(args, count - 1));
+ Tcl_Eval(port->_interp, s);
+ free(s);
+ }
+ } else if (CFStringCompare(command, CFSTR("variant"), 0) == kCFCompareEqualTo) {
+ CFStringRef name;
+ CFMutableDictionaryRef props;
+ CFIndex i;
+
+ // variant name [a b c d] {}
+ if (count < 3) {
+ fprintf(stderr, "bogus variant declaration\n");
+ return;
+ }
+
+ name = CFArrayGetValueAtIndex(args, 1);
+
+ // this isn't quite right, conflicts can take multiple "arguments"
+ props = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ for (i = 2; i < count - 1; i += 2) {
+ CFDictionarySetValue(props, CFArrayGetValueAtIndex(args, i), CFArrayGetValueAtIndex(args, i + 1));
+ }
+
+ if (mp_port_test_and_record_variant(port, name, props)) {
+ char *s = strdup_cf(CFArrayGetValueAtIndex(args, count - 1));
+ Tcl_Eval(port->_interp, s);
+ free(s);
+ }
+ } else if (mp_port_is_target(port, command)) {
+ // XXX: store for later use...
+ } else {
+ const void *values[count - 1];
+ CFArrayRef foo;
+ CFStringRef tmp;
+
+ CFArrayGetValues(args, CFRangeMake(1, count - 1), values);
+ foo = CFArrayCreate(NULL, values, count - 1, &kCFTypeArrayCallBacks);
+
+ if (CFStringHasSuffix(command, CFSTR("-append"))) {
+ tmp = CFStringCreateWithSubstring(NULL, command, CFRangeMake(0, CFStringGetLength(command) - 7));
+ mp_port_variable_append(port, tmp, foo);
+ CFRelease(tmp);
+ } else if (CFStringHasSuffix(command, CFSTR("-delete"))) {
+ tmp = CFStringCreateWithSubstring(NULL, command, CFRangeMake(0, CFStringGetLength(command) - 7));
+ mp_port_variable_delete(port, tmp, foo);
+ CFRelease(tmp);
+ } else {
+ mp_port_variable_set(port, command, foo);
+ }
+ }
+}
+
+static int
+command_trampoline(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ CFArrayRef args = CFArrayCreateWithTclObjects(NULL, objv, objc);
+ mp_port_perform_command(clientData, args);
+ CFRelease(args);
+
+ return TCL_OK;
+}
+
+static void
+command_create(Tcl_Interp *interp, const char *cmdName, ClientData clientData)
+{
+ Tcl_CmdInfo info;
+ if (Tcl_GetCommandInfo(interp, cmdName, &info) != 0) {
+ fprintf(stderr, "Command '%s' already exists, bailing.", cmdName);
+ abort();
+ }
+ Tcl_CreateObjCommand(interp, cmdName, command_trampoline, clientData, NULL);
+}
+
+static char *
+variable_read(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags)
+{
+ CFStringRef tmp, var;
+ char *s;
+
+ tmp = CFStringCreateWithCString(NULL, name1, kCFStringEncodingUTF8);
+ var = mp_port_variable(clientData, tmp);
+ CFRelease(tmp);
+
+ assert(var != nil);
+
+ s = strdup_cf(var);
+ Tcl_SetVar2(interp, name1, name2, s, 0);
+ free(s);
+
+ return NULL;
+}
+
+// debugging
+static int
+_nslog(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ CFArrayRef args;
+ CFStringRef str;
+
+ args = CFArrayCreateWithTclObjects(NULL, ++objv, --objc);
+ if (args) {
+ str = CFStringCreateByCombiningStrings(NULL, args, CFSTR(" "));
+ if (str) {
+ CFShow(str);
+ CFRelease(str);
+ }
+ CFRelease(args);
+ }
+
+ return TCL_OK;
+}
+
+static int
+_fake_boolean(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+ return TCL_OK;
+}
Modified: users/toby/objcports/MPPort.h
===================================================================
--- users/toby/objcports/MPPort.h 2009-09-10 09:42:07 UTC (rev 57382)
+++ users/toby/objcports/MPPort.h 2009-09-10 09:46:02 UTC (rev 57383)
@@ -1,21 +1,7 @@
- at class MPParser;
+typedef struct mp_port_s *mp_port_t;
- at interface MPPort : NSObject
-{
- NSURL *_url;
-
- NSMutableDictionary *_variableInfo;
- NSMutableDictionary *_variables;
-
- NSMutableArray *_platforms;
- NSMutableDictionary *_variants;
-
- Tcl_Interp *_interp;
-}
-
-- (id)initWithPath:(NSString *)url options:(NSDictionary *)options;
-- (NSString *)variable:(NSString *)name;
-- (NSArray *)definedVariants;
-- (NSArray *)definedPlatforms;
-
- at end
+mp_port_t mp_port_create(CFURLRef url, CFDictionaryRef options);
+void mp_port_destroy(mp_port_t port);
+CFStringRef mp_port_variable(mp_port_t port, CFStringRef var);
+CFArrayRef mp_port_defined_variants(mp_port_t port);
+CFArrayRef mp_port_defined_platforms(mp_port_t port);
Deleted: users/toby/objcports/MPPort.m
===================================================================
--- users/toby/objcports/MPPort.m 2009-09-10 09:42:07 UTC (rev 57382)
+++ users/toby/objcports/MPPort.m 2009-09-10 09:46:02 UTC (rev 57383)
@@ -1,557 +0,0 @@
-#include <Foundation/Foundation.h>
-#include <tcl.h>
-#include <sys/utsname.h>
-#include <mach-o/getsect.h>
-
-#include "MPPort.h"
-#include "MPArrayAdditions.h"
-#include "MPStringAdditions.h"
-#include "internal.h"
-
-static NSString *kPortVariableType = @"Type";
-static NSString *kPortVariableConstant = @"Constant";
-static NSString *kPortVariableDefault = @"Default";
-static NSString *kPortVariableCallback = @"Callback";
-
-static void command_create(Tcl_Interp *interp, const char *cmdName, ClientData clientData);
-static char *variable_read(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags);
-static int _nslog(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
-static int _fake_boolean(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
-
- at interface MPPort (private)
-- (NSString *)portfile;
-- (NSArray *)targets;
-- (NSArray *)variables;
-- (NSArray *)settableVariables;
-- (NSArray *)settableArrayVariables;
- at end
-
- at implementation MPPort
-
-- (id)initWithURL:(NSURL *)url options:(NSDictionary *)options
-{
- char *sectdata;
- unsigned long sectsize;
- NSData *vdata;
-
- self = [super init];
- _url = [url retain];
-
- _platforms = [[NSMutableArray alloc] initWithCapacity:0];
- _variants = [[NSMutableDictionary alloc] initWithCapacity:0];
-
- _variables = [[NSMutableDictionary alloc] initWithCapacity:0];
-
- //_variableInfo = [[NSMutableDictionary alloc] initWithContentsOfFile:@"variables.plist"];
- sectdata = getsectdata("MacPorts", "variables", §size);
- assert(sectdata);
- vdata = [[NSData alloc] initWithBytesNoCopy:sectdata length:sectsize freeWhenDone:NO];
- _variableInfo = [[NSPropertyListSerialization propertyListWithData:vdata options:kCFPropertyListMutableContainersAndLeaves format:NULL error:NULL] retain];
- [vdata release];
-
- NSArray *commands = [NSArray arrayWithObjects:
- @"cvs", // portfetch.tcl
- @"svn", // portfetch.tcl
- @"extract", // portextract.tcl
- @"patch", // portpatch.tcl
- @"configure", // portconfigure.tcl
- @"autoreconf", // portconfigure.tcl
- @"automake", // portconfigure.tcl
- @"autoconf", // portconfigure.tcl
- @"xmkmf", // portconfigure.tcl
- @"build", // portbuild.tcl
- @"test", // porttest.tcl
- @"destroot", // portdestroot.tcl
- nil];
-
- // essentially 'commands' from portutil.tcl
- for (NSString *command in commands) {
- [_variableInfo setObject:[NSDictionary dictionary] forKey:[NSString stringWithFormat:@"use_%@", command]];
- [_variableInfo setObject:[NSDictionary dictionary] forKey:[NSString stringWithFormat:@"%@.dir", command]];
- [_variableInfo setObject:[NSDictionary dictionaryWithObject:@"Array" forKey:kPortVariableType] forKey:[NSString stringWithFormat:@"%@.pre_args", command]];
- [_variableInfo setObject:[NSDictionary dictionaryWithObject:@"Array" forKey:kPortVariableType] forKey:[NSString stringWithFormat:@"%@.args", command]];
- [_variableInfo setObject:[NSDictionary dictionaryWithObject:@"Array" forKey:kPortVariableType] forKey:[NSString stringWithFormat:@"%@.post_args", command]];
- [_variableInfo setObject:[NSDictionary dictionaryWithObject:@"Array" forKey:kPortVariableType] forKey:[NSString stringWithFormat:@"%@.env", command]];
- [_variableInfo setObject:[NSDictionary dictionary] forKey:[NSString stringWithFormat:@"%@.type", command]];
- [_variableInfo setObject:[NSDictionary dictionaryWithObject:@"Array" forKey:kPortVariableType] forKey:[NSString stringWithFormat:@"%@.cmd", command]];
- }
-
- _interp = Tcl_CreateInterp();
- Tcl_MakeSafe(_interp);
- Tcl_UnsetVar(_interp, "tcl_version", 0);
- Tcl_UnsetVar(_interp, "tcl_patchLevel", 0);
- Tcl_UnsetVar(_interp, "tcl_platform", 0);
- Tcl_DeleteCommand(_interp, "tell");
- Tcl_DeleteCommand(_interp, "eof");
- // XXX: etc?
-
- @try {
- Tcl_Preserve(_interp);
-
- Tcl_CreateObjCommand(_interp, "nslog", _nslog, NULL, NULL); // XXX: debugging
- //Tcl_Eval(_interp, "nslog [info commands]");
-
- command_create(_interp, "PortSystem", self);
- command_create(_interp, "PortGroup", self);
- command_create(_interp, "platform", self);
- command_create(_interp, "variant", self);
-
- for (NSString *target in [self targets]) {
- command_create(_interp, [target UTF8String], self);
- command_create(_interp, [[@"pre-" stringByAppendingString:target] UTF8String], self);
- command_create(_interp, [[@"post-" stringByAppendingString:target] UTF8String], self);
- }
-
- for (NSString *opt in [self settableVariables]) {
- command_create(_interp, [opt UTF8String], self);
- }
- for (NSString *opt in [self settableArrayVariables]) {
- command_create(_interp, [[opt stringByAppendingString:@"-append"] UTF8String], self);
- command_create(_interp, [[opt stringByAppendingString:@"-delete"] UTF8String], self);
- }
-
- for (NSString *var in [self variables]) {
- Tcl_TraceVar(_interp, [var UTF8String], TCL_TRACE_READS, variable_read, self);
- }
-
- // bogus targets
- Tcl_CreateObjCommand(_interp, "pre-activate", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "post-activate", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "pre-install", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "post-install", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "post-pkg", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "post-mpkg", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "archive", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "install", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "activate", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "unarchive", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "post-clean", _nslog, NULL, NULL); // XXX: debugging
-
- // functions we need to provide (?)
- Tcl_CreateObjCommand(_interp, "variant_isset", _fake_boolean, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "variant_set", _fake_boolean, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "tbool", _fake_boolean, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "strsed", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "suffix", _nslog, NULL, NULL); // XXX: debugging
- Tcl_CreateObjCommand(_interp, "include", _nslog, NULL, NULL); // XXX: debugging
-
- // variables that should be constant
- Tcl_CreateObjCommand(_interp, "prefix", _nslog, NULL, NULL);
-
- if (Tcl_EvalFile(_interp, [[self portfile] UTF8String]) != TCL_OK) {
- NSLog(@"Tcl_EvalFile(): %s", Tcl_GetStringResult(_interp));
- exit(1);
- }
-
- Tcl_Release(_interp);
- }
- @catch (NSException *exception) {
- NSLog(@"%@: %@", [exception name], [exception reason]);
- [self release];
- self = nil;
- }
-
- for (NSString *vv in _variableInfo) {
- NSLog(@"%@ -- %@ -- %@", vv, [_variables objectForKey:vv], [self variable:vv]);
- }
-
- return self;
-}
-
-- (id)initWithPath:(NSString *)path options:(NSDictionary *)options
-{
- NSString *standardizedPath;
- NSURL *url;
-
- standardizedPath = [path stringByStandardizingPath];
- url = [NSURL fileURLWithPath:standardizedPath isDirectory:YES];
- return [self initWithURL:url options:options];
-}
-
-- (void)dealloc
-{
- [_url release];
-
- [_variableInfo release];
- [_variables release];
-
- [_platforms release];
- [_variants release];
-
- Tcl_DeleteInterp(_interp);
-
- [super dealloc];
-}
-
-- (NSString *)portfile
-{
- return [[_url path] stringByAppendingPathComponent:@"Portfile"];
-}
-
-- (NSArray *)targets
-{
- return [NSArray arrayWithObjects:
- @"fetch",
- @"checksum",
- @"extract",
- @"patch",
- @"configure",
- @"build",
- @"test",
- @"destroot",
- nil];
-}
-
-- (BOOL)isTarget:(NSString *)target
-{
- if ([target hasPrefix:@"pre-"]) {
- target = [target substringWithRange:NSMakeRange(4, [target length] - 4)];
- } else if ([target hasPrefix:@"post-"]) {
- target = [target substringWithRange:NSMakeRange(5, [target length] - 5)];
- }
-
- return [[self targets] containsObject:target];
-}
-
-- (NSArray *)variables
-{
- return [_variableInfo allKeys];
-}
-
-- (BOOL)variableIsArray:(NSString *)var
-{
- NSString *type = [[_variableInfo objectForKey:var] objectForKey:kPortVariableType];
- return [type isEqualToString:@"Array"];
-}
-
-- (id)defaultCallback:(NSString *)name
-{
- return @"";
-}
-
-- (id)osInfo:(NSString *)name
-{
- NSString *ret = nil;
- int rc;
- struct utsname u;
-
- rc = uname(&u);
- assert(rc == 0);
-
- if ([name isEqualToString:@"os.platform"]) {
- ret = [[NSString stringWithUTF8String:u.sysname] lowercaseString];
- } else if ([name isEqualToString:@"os.arch"]) {
- ret = [NSString stringWithUTF8String:u.machine];
- } else if ([name isEqualToString:@"os.endian"]) {
-#ifdef __BIG_ENDIAN__
- ret = @"big";
-#else
- ret = @"little";
-#endif
- } else if ([name isEqualToString:@"os.major"]) {
- ret = [[[NSString stringWithUTF8String:u.release] componentsSeparatedByString:@"."] objectAtIndex:0];
- } else if ([name isEqualToString:@"os.version"]) {
- ret = [NSString stringWithUTF8String:u.release];
- } else {
- abort();
- }
-
- return ret;
-}
-
-- (NSString *)variable:(NSString *)name
-{
- NSDictionary *info;
- id setValue;
- id defValue;
- id callback;
- NSString *ret = nil;
-
- info = [_variableInfo objectForKey:name];
- if (info != nil) {
- if ((setValue = [_variables objectForKey:name])) {
- if ([self variableIsArray:name]) {
- NSLog(@"%@ %@", name, setValue);
- assert([setValue isKindOfClass:[NSArray class]]);
- ret = [setValue componentsJoinedByString:@" "];
- } else {
- assert([setValue isKindOfClass:[NSString class]]);
- ret = setValue;
- }
- } else if ((defValue = [info objectForKey:kPortVariableDefault])) {
- ret = defValue;
- } else if ((callback = [info objectForKey:kPortVariableCallback])) {
- assert([callback isKindOfClass:[NSString class]]);
- ret = [self performSelector:NSSelectorFromString(callback) withObject:name];
- } else {
- ret = [NSString stringWithUTF8String:""];
- }
- ret = [(NSString *)CFStringCreateWithTclObject(NULL, Tcl_SubstObj(_interp, Tcl_NewStringObj([ret UTF8String], -1), TCL_SUBST_VARIABLES)) autorelease];
- } else {
- NSLog(@"WARNING: unknown variable %@", name);
- }
- return ret;
-}
-
-- (NSArray *)settableVariables
-{
- NSMutableArray *ret = [NSMutableArray arrayWithCapacity:0];
- for (NSString *var in [self variables]) {
- NSNumber *constant = [[_variableInfo objectForKey:var] objectForKey:kPortVariableConstant];
- if (constant == nil || [constant boolValue] == NO) {
- [ret addObject:var];
- }
- }
- return ret;
-}
-
-- (void)variable:(NSString *)var set:(NSArray *)value
-{
- if ([self variableIsArray:var]) {
- [_variables setObject:value forKey:var];
- } else {
- [_variables setObject:[value componentsJoinedByString:@" "] forKey:var];
- }
-}
-
-- (NSArray *)settableArrayVariables
-{
- NSMutableArray *ret = [NSMutableArray arrayWithCapacity:0];
- for (NSString *var in [self settableVariables]) {
- if ([self variableIsArray:var]) {
- [ret addObject:var];
- }
- }
- return ret;
-}
-
-- (void)variable:(NSString *)var append:(NSArray *)value
-{
- id old = [_variables objectForKey:var];
- if (old) {
- assert([old isKindOfClass:[NSArray class]]);
- [_variables setObject:[old arrayByAddingObjectsFromArray:value] forKey:var];
- } else {
- [_variables setObject:value forKey:var];
- }
-}
-
-- (void)variable:(NSString *)var delete:(NSArray *)value
-{
- id old;
- NSMutableArray *tmp;
-
- old = [_variables objectForKey:var];
- if (old == nil) {
- return;
- }
- assert([old isKindOfClass:[NSArray class]]);
- tmp = [old mutableCopy];
- for (NSString *v in value) {
- [tmp removeObject:v];
- }
- [_variables setObject:tmp forKey:var];
- [tmp release];
-}
-
-- (NSArray *)definedPlatforms
-{
- NSMutableArray *ret = [NSMutableArray arrayWithCapacity:0];
- for (NSArray *plat in _platforms) {
- [ret addObject:[plat componentsJoinedByString:@"_"]];
- }
- return ret;
-}
-
-- (BOOL)testAndRecordPlatform:(NSArray *)platform
-{
- struct utsname u;
- NSString *os;
- NSNumber *release;
- NSString *arch;
- id tmp;
-
- [_platforms addObject:platform];
-
- assert(uname(&u) == 0);
- os = [[NSString stringWithUTF8String:u.sysname] lowercaseString];
- release = [NSNumber numberWithInteger:[[NSString stringWithUTF8String:u.release] integerValue]];
- arch = [NSString stringWithUTF8String:u.machine];
-
- tmp = [platform objectAtIndex:0];
- if (tmp != [NSNull null] && ![tmp isEqualToString:os]) {
- return NO;
- }
-
- tmp = [platform objectAtIndex:1];
- if (tmp != [NSNull null] && ![tmp isEqual:release]) {
- return NO;
- }
-
- tmp = [platform objectAtIndex:2];
- if (tmp != [NSNull null] && ![tmp isEqual:arch]) {
- return NO;
- }
-
- return YES;
-}
-
-- (NSArray *)definedVariants
-{
- return [_variants allKeys];
-}
-
-- (BOOL)testAndRecordVariant:(NSString *)variant withProperties:(NSDictionary *)props
-{
- // XXX: check for dupes (w/ platforms too)
- [_variants setObject:props forKey:variant];
- // XXX: make sure it's set, like platforms just pretend
- return YES;
-}
-
-- (void)performCommand:(NSArray *)args
-{
- NSString *command;
-
- command = [args objectAtIndex:0];
-
- if ([command isEqualToString:@"PortSystem"]) {
- assert([args count] == 2);
- assert([[args objectAtIndex:1] isEqualToString:@"1.0"]);
- } else if ([command isEqualToString:@"PortGroup"]) {
- NSLog(@"ignoring %@, grps r hard m'kay", command);
- // XXX: this should probably set some state in parent port instance
- // (ugh, more tcl parsing)
- } else if ([command isEqualToString:@"platform"]) {
- NSUInteger count = [args count];
- NSString *os = nil;
- id release = [NSNull null];
- id arch = [NSNull null];
-
- if (count < 3 || count > 5) {
- NSLog(@"bogus platform declaration");
- return;
- }
-
- os = [args objectAtIndex:1];
-
- if (count == 4) {
- NSInteger rel = [[args objectAtIndex:2] integerValue];
- if (rel != 0) {
- release = [NSNumber numberWithInteger:rel];
- } else {
- arch = [args objectAtIndex:2];
- }
- } else if (count == 5) {
- release = [NSNumber numberWithInteger:[[args objectAtIndex:2] integerValue]];
- arch = [args objectAtIndex:3];
- }
-
- if ([self testAndRecordPlatform:[NSArray arrayWithObjects:os, release, arch, nil]]) {
- Tcl_Eval(_interp, [[args lastObject] UTF8String]);
- }
- } else if ([command isEqualToString:@"variant"]) {
- NSUInteger count = [args count];
- NSString *name;
- NSMutableDictionary *props;
- NSUInteger i;
-
- // variant name [a b c d] {}
- if (count < 3) {
- NSLog(@"bogus variant declaration");
- return;
- }
-
- name = [args objectAtIndex:1];
-
- // this isn't quite right, conflicts can take multiple "arguments"
- props = [NSMutableDictionary dictionaryWithCapacity:count-2];
- for (i = 2; i < count - 1; i += 2) {
- [props setObject:[args objectAtIndex:i+1] forKey:[args objectAtIndex:i]];
- }
-
- if ([self testAndRecordVariant:name withProperties:props]) {
- Tcl_Eval(_interp, [[args lastObject] UTF8String]);
- }
- } else if ([self isTarget:command]) {
- // XXX: store for later use...
- } else {
- NSArray *foo = [args subarrayWithRange:NSMakeRange(1, [args count] - 1)];
- if ([command hasSuffix:@"-append"]) {
- [self variable:[command substringWithRange:NSMakeRange(0, [command length] - 7)] append:foo];
- } else if ([command hasSuffix:@"-delete"]) {
- [self variable:[command substringWithRange:NSMakeRange(0, [command length] - 7)] delete:foo];
- } else {
- [self variable:command set:foo];
- }
- }
-}
-
- at end
-
-static int
-command_trampoline(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
-{
- CFArrayRef args = CFArrayCreateWithTclObjects(NULL, objv, objc);
- [(MPPort *)clientData performCommand:(NSArray *)args];
- CFRelease(args);
-
- return TCL_OK;
-}
-
-static void
-command_create(Tcl_Interp *interp, const char *cmdName, ClientData clientData)
-{
- Tcl_CmdInfo info;
- if (Tcl_GetCommandInfo(interp, cmdName, &info) != 0) {
- fprintf(stderr, "Command '%s' already exists, bailing.", cmdName);
- abort();
- }
- Tcl_CreateObjCommand(interp, cmdName, command_trampoline, clientData, NULL);
-}
-
-static char *
-variable_read(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags)
-{
- CFStringRef tmp, var;
- char *s;
-
- tmp = CFStringCreateWithCString(NULL, name1, kCFStringEncodingUTF8);
- var = (CFStringRef)[(MPPort *)clientData variable:(NSString *)tmp];
- CFRelease(tmp);
-
- assert(var != nil);
-
- s = strdup_cf(var);
- Tcl_SetVar2(interp, name1, name2, s, 0);
- free(s);
-
- return NULL;
-}
-
-// debugging
-static int
-_nslog(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
-{
- CFArrayRef args;
- CFStringRef str;
-
- args = CFArrayCreateWithTclObjects(NULL, ++objv, --objc);
- if (args) {
- str = CFStringCreateByCombiningStrings(NULL, args, CFSTR(" "));
- if (str) {
- CFShow(str);
- CFRelease(str);
- }
- CFRelease(args);
- }
-
- return TCL_OK;
-}
-
-static int
-_fake_boolean(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
-{
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
-}
Modified: users/toby/objcports/internal.c
===================================================================
--- users/toby/objcports/internal.c 2009-09-10 09:42:07 UTC (rev 57382)
+++ users/toby/objcports/internal.c 2009-09-10 09:46:02 UTC (rev 57383)
@@ -1,4 +1,5 @@
#include <CoreFoundation/CoreFoundation.h>
+#include <dispatch/dispatch.h>
#include "internal.h"
@@ -19,3 +20,55 @@
}
return result;
}
+
+int
+fprintf_cf(FILE *stream, CFStringRef format, ...)
+{
+ va_list ap;
+ CFStringRef str;
+ char *s;
+ int rc;
+
+ va_start(ap, format);
+ str = CFStringCreateWithFormatAndArguments(NULL, NULL, format, ap);
+ va_end(ap);
+
+ s = strdup_cf(str);
+ rc = fprintf(stream, "%s", s);
+ free(s);
+
+ CFRelease(str);
+
+ return rc;
+}
+
+void
+CFArrayApplyBlock(CFArrayRef theArray, CFRange range, CFArrayApplierBlock applier)
+{
+ dispatch_queue_t apply_queue = dispatch_queue_create("CFArrayApplyBlock", NULL);
+ const void *vals[range.length];
+ CFArrayGetValues(theArray, range, vals);
+ dispatch_apply(range.length, apply_queue, ^(size_t i) {
+ applier(vals[i]);
+ });
+ dispatch_release(apply_queue);
+}
+
+void
+CFArrayApplyBlock2(CFArrayRef theArray, CFArrayApplierBlock applier)
+{
+ CFArrayApplyBlock(theArray, CFRangeMake(0, CFArrayGetCount(theArray)), applier);
+}
+
+void
+CFDictionaryApplyBlock(CFDictionaryRef theDict, CFDictionaryApplierBlock applier)
+{
+ dispatch_queue_t apply_queue = dispatch_queue_create("CFDictionaryApplyBlock", NULL);
+ CFIndex count = CFDictionaryGetCount(theDict);
+ const void *keys[count], *vals[count];
+ CFDictionaryGetKeysAndValues(theDict, keys, vals);
+ dispatch_apply(count, apply_queue, ^(size_t i) {
+ applier(keys[i], vals[i]);
+ });
+ dispatch_release(apply_queue);
+}
Modified: users/toby/objcports/internal.h
===================================================================
--- users/toby/objcports/internal.h 2009-09-10 09:42:07 UTC (rev 57382)
+++ users/toby/objcports/internal.h 2009-09-10 09:46:02 UTC (rev 57383)
@@ -1 +1,9 @@
char *strdup_cf(CFStringRef str);
+int fprintf_cf(FILE *stream, CFStringRef format, ...);
+
+typedef void (^CFArrayApplierBlock)(const void *);
+typedef void (^CFDictionaryApplierBlock)(const void *, const void *);
+
+void CFArrayApplyBlock(CFArrayRef, CFRange, CFArrayApplierBlock);
+void CFArrayApplyBlock2(CFArrayRef, CFArrayApplierBlock);
+void CFDictionaryApplyBlock(CFDictionaryRef, CFDictionaryApplierBlock);
Modified: users/toby/objcports/objcports.xcodeproj/project.pbxproj
===================================================================
--- users/toby/objcports/objcports.xcodeproj/project.pbxproj 2009-09-10 09:42:07 UTC (rev 57382)
+++ users/toby/objcports/objcports.xcodeproj/project.pbxproj 2009-09-10 09:46:02 UTC (rev 57383)
@@ -12,9 +12,9 @@
DA7AF1BC1058D1E200CF2187 /* internal.c in Sources */ = {isa = PBXBuildFile; fileRef = DA7AF1BB1058D1E200CF2187 /* internal.c */; };
DA96BED00F7C9C2500362779 /* MPIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = DA96BECF0F7C9C2500362779 /* MPIndex.c */; };
DA96BF4C0F7CA1A700362779 /* MPDictionaryAdditions.c in Sources */ = {isa = PBXBuildFile; fileRef = DA96BF4B0F7CA1A700362779 /* MPDictionaryAdditions.c */; };
- DAD371710F0280EF0064AFF4 /* port.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD371680F0280EF0064AFF4 /* port.m */; };
+ DAD371710F0280EF0064AFF4 /* port.c in Sources */ = {isa = PBXBuildFile; fileRef = DAD371680F0280EF0064AFF4 /* port.c */; };
DAD371720F0280EF0064AFF4 /* MPArrayAdditions.c in Sources */ = {isa = PBXBuildFile; fileRef = DAD3716A0F0280EF0064AFF4 /* MPArrayAdditions.c */; };
- DAD371740F0280EF0064AFF4 /* MPPort.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD3716E0F0280EF0064AFF4 /* MPPort.m */; };
+ DAD371740F0280EF0064AFF4 /* MPPort.c in Sources */ = {isa = PBXBuildFile; fileRef = DAD3716E0F0280EF0064AFF4 /* MPPort.c */; };
DAD371750F0280EF0064AFF4 /* MPStringAdditions.c in Sources */ = {isa = PBXBuildFile; fileRef = DAD371700F0280EF0064AFF4 /* MPStringAdditions.c */; };
DAD371950F0281940064AFF4 /* libtcl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD371940F0281940064AFF4 /* libtcl.dylib */; };
/* End PBXBuildFile section */
@@ -42,11 +42,11 @@
DA96BECF0F7C9C2500362779 /* MPIndex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MPIndex.c; sourceTree = "<group>"; };
DA96BF4A0F7CA1A700362779 /* MPDictionaryAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDictionaryAdditions.h; sourceTree = "<group>"; };
DA96BF4B0F7CA1A700362779 /* MPDictionaryAdditions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MPDictionaryAdditions.c; sourceTree = "<group>"; };
- DAD371680F0280EF0064AFF4 /* port.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = port.m; sourceTree = "<group>"; };
+ DAD371680F0280EF0064AFF4 /* port.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = port.c; sourceTree = "<group>"; };
DAD371690F0280EF0064AFF4 /* MPArrayAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPArrayAdditions.h; sourceTree = "<group>"; };
DAD3716A0F0280EF0064AFF4 /* MPArrayAdditions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MPArrayAdditions.c; sourceTree = "<group>"; };
DAD3716D0F0280EF0064AFF4 /* MPPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPort.h; sourceTree = "<group>"; };
- DAD3716E0F0280EF0064AFF4 /* MPPort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPort.m; sourceTree = "<group>"; };
+ DAD3716E0F0280EF0064AFF4 /* MPPort.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MPPort.c; sourceTree = "<group>"; };
DAD3716F0F0280EF0064AFF4 /* MPStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPStringAdditions.h; sourceTree = "<group>"; };
DAD371700F0280EF0064AFF4 /* MPStringAdditions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MPStringAdditions.c; sourceTree = "<group>"; };
DAD371940F0281940064AFF4 /* libtcl.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libtcl.dylib; path = /usr/lib/libtcl.dylib; sourceTree = "<absolute>"; };
@@ -80,7 +80,7 @@
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
- DAD371680F0280EF0064AFF4 /* port.m */,
+ DAD371680F0280EF0064AFF4 /* port.c */,
DAD371690F0280EF0064AFF4 /* MPArrayAdditions.h */,
DAD3716A0F0280EF0064AFF4 /* MPArrayAdditions.c */,
DA96BF4A0F7CA1A700362779 /* MPDictionaryAdditions.h */,
@@ -88,7 +88,7 @@
DA96BECE0F7C9C2500362779 /* MPIndex.h */,
DA96BECF0F7C9C2500362779 /* MPIndex.c */,
DAD3716D0F0280EF0064AFF4 /* MPPort.h */,
- DAD3716E0F0280EF0064AFF4 /* MPPort.m */,
+ DAD3716E0F0280EF0064AFF4 /* MPPort.c */,
DAD3716F0F0280EF0064AFF4 /* MPStringAdditions.h */,
DAD371700F0280EF0064AFF4 /* MPStringAdditions.c */,
DA138879101AED7000F73A82 /* MPConfig.h */,
@@ -167,11 +167,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- DAD371710F0280EF0064AFF4 /* port.m in Sources */,
+ DAD371710F0280EF0064AFF4 /* port.c in Sources */,
DAD371720F0280EF0064AFF4 /* MPArrayAdditions.c in Sources */,
DAD371750F0280EF0064AFF4 /* MPStringAdditions.c in Sources */,
DA96BED00F7C9C2500362779 /* MPIndex.c in Sources */,
- DAD371740F0280EF0064AFF4 /* MPPort.m in Sources */,
+ DAD371740F0280EF0064AFF4 /* MPPort.c in Sources */,
DA96BF4C0F7CA1A700362779 /* MPDictionaryAdditions.c in Sources */,
DA13887B101AED7000F73A82 /* MPConfig.c in Sources */,
DA7AF1BC1058D1E200CF2187 /* internal.c in Sources */,
@@ -201,7 +201,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
- GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
Copied: users/toby/objcports/port.c (from rev 57365, users/toby/objcports/port.m)
===================================================================
--- users/toby/objcports/port.c (rev 0)
+++ users/toby/objcports/port.c 2009-09-10 09:46:02 UTC (rev 57383)
@@ -0,0 +1,81 @@
+#include <CoreFoundation/CoreFoundation.h>
+#include <tcl.h>
+
+#include "MPConfig.h"
+#include "MPIndex.h"
+#include "MPPort.h"
+
+static void
+do_showconfig()
+{
+ CFDictionaryRef config;
+
+ config = MPCopyConfig();
+ CFShow(config);
+ CFRelease(config);
+}
+
+static void
+do_showindex(char *f)
+{
+ CFStringRef filename;
+ CFDictionaryRef index;
+
+ filename = CFStringCreateWithCString(NULL, f, kCFStringEncodingUTF8);
+ index = MPCopyPortIndex(filename);
+ CFShow(index);
+ CFRelease(index);
+ CFRelease(filename);
+}
+
+static void
+do_info(int argc, char *argv[])
+{
+ while (--argc) {
+ CFStringRef path;
+ CFURLRef url;
+ mp_port_t port;
+ CFStringRef tmp;
+
+ path = CFStringCreateWithCString(NULL, *++argv, kCFStringEncodingUTF8);
+ url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, TRUE);
+ port = mp_port_create(url, NULL);
+ fprintf_cf(stdout, CFSTR("%@ @%@ (%@)\n"), mp_port_variable(port, CFSTR("name")), mp_port_variable(port, CFSTR("version")), mp_port_variable(port, CFSTR("categories")));
+ tmp = CFStringCreateByCombiningStrings(NULL, mp_port_defined_variants(port), CFSTR(", "));
+ fprintf_cf(stdout, CFSTR("Variants: %@\n"), tmp);
+ tmp = CFStringCreateByCombiningStrings(NULL, mp_port_defined_platforms(port), CFSTR(", "));
+ fprintf_cf(stdout, CFSTR("PlatformVariants: %@\n"), tmp);
+ fprintf_cf(stdout, CFSTR("Brief Description: %@\n"), mp_port_variable(port, CFSTR("description")));
+ fprintf_cf(stdout, CFSTR("Description: %@\n"), mp_port_variable(port, CFSTR("long_description")));
+ fprintf_cf(stdout, CFSTR("Homepage: %@\n"), mp_port_variable(port, CFSTR("homepage")));
+ fprintf_cf(stdout, CFSTR("Build Dependencies: %@\n"), mp_port_variable(port, CFSTR("depends_build")));
+ fprintf_cf(stdout, CFSTR("Library Dependencies: %@\n"), mp_port_variable(port, CFSTR("depends_lib")));
+ fprintf_cf(stdout, CFSTR("Platforms: %@\n"), mp_port_variable(port, CFSTR("platforms")));
+ fprintf_cf(stdout, CFSTR("Maintainers: %@\n"), mp_port_variable(port, CFSTR("maintainers")));
+ mp_port_destroy(port);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ if (argc < 2)
+ exit(1);
+
+ if (!strcmp(argv[1], "showconfig")) {
+ do_showconfig();
+ } else {
+ if (argc < 3)
+ exit(1);
+
+ if (!strcmp(argv[1], "showindex")) {
+ do_showindex(argv[2]);
+ } else {
+ do_info(argc - 1, argv + 1);
+ }
+ }
+
+ pause();
+ return 0;
+}
Deleted: users/toby/objcports/port.m
===================================================================
--- users/toby/objcports/port.m 2009-09-10 09:42:07 UTC (rev 57382)
+++ users/toby/objcports/port.m 2009-09-10 09:46:02 UTC (rev 57383)
@@ -1,76 +0,0 @@
-#include <Foundation/Foundation.h>
-#include <tcl.h>
-
-#include "MPConfig.h"
-#include "MPIndex.h"
-#include "MPPort.h"
-
-static void
-do_showconfig()
-{
- CFDictionaryRef config;
-
- config = MPCopyConfig();
- CFShow(config);
- CFRelease(config);
-}
-
-static void
-do_showindex(char *f)
-{
- CFStringRef filename;
- CFDictionaryRef index;
-
- filename = CFStringCreateWithCString(NULL, f, kCFStringEncodingUTF8);
- index = MPCopyPortIndex(filename);
- CFShow(index);
- CFRelease(index);
- CFRelease(filename);
-}
-
-static void
-do_info(int argc, char *argv[])
-{
- printf("%d\n", argc);
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
-
- while (--argc) {
- MPPort *port = [[MPPort alloc] initWithPath:[NSString stringWithUTF8String:*++argv] options:nil];
- NSLog(@"%@ @%@ (%@)", [port variable:@"name"], [port variable:@"version"], [port variable:@"categories"]);
- NSLog(@"Variants: %@", [[port definedVariants] componentsJoinedByString:@", "]);
- NSLog(@"PlatformVariants: %@", [[port definedPlatforms] componentsJoinedByString:@", "]);
- NSLog(@"Brief Description: %@", [port variable:@"description"]);
- NSLog(@"Description: %@", [port variable:@"long_description"]);
- NSLog(@"Homepage: %@", [port variable:@"homepage"]);
- NSLog(@"Build Dependencies: %@", [port variable:@"depends_build"]);
- NSLog(@"Library Dependencies: %@", [port variable:@"depends_lib"]);
- NSLog(@"Platforms: %@", [port variable:@"platforms"]);
- NSLog(@"Maintainers: %@", [port variable:@"maintainers"]);
- [port release];
- }
-
- [pool release];
-}
-
-int
-main(int argc, char *argv[])
-{
-
- if (argc < 2)
- exit(1);
-
- if (!strcmp(argv[1], "showconfig")) {
- do_showconfig();
- } else {
- if (argc < 3)
- exit(1);
-
- if (!strcmp(argv[1], "showindex")) {
- do_showindex(argv[2]);
- } else {
- do_info(argc - 1, argv + 1);
- }
- }
-
- return 0;
-}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20090910/3bedddbf/attachment-0001.html>
More information about the macports-changes
mailing list