[81411] branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c

fotanus at macports.org fotanus at macports.org
Fri Jul 29 21:26:36 PDT 2011


Revision: 81411
          http://trac.macports.org/changeset/81411
Author:   fotanus at macports.org
Date:     2011-07-29 21:26:36 -0700 (Fri, 29 Jul 2011)
Log Message:
-----------
Cleanup on C extension

More might be done, but this cleanup removes some code duplicity

Modified Paths:
--------------
    branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c

Modified: branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c
===================================================================
--- branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c	2011-07-30 04:25:17 UTC (rev 81410)
+++ branches/gsoc11-post-destroot/base/src/pextlib1.0/macho.c	2011-07-30 04:26:36 UTC (rev 81411)
@@ -39,13 +39,6 @@
 	return macho_read(input, result, length);
 }
 
-/* return a human readable formatted version number. the result must be free()'d. */
-char *macho_format_dylib_version (uint32_t version) {
-	char *result;
-	asprintf(&result, "%"PRIu32".%"PRIu32".%"PRIu32, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
-	return result;
-}
-
 /* Some byteswap wrappers */
 static uint32_t macho_swap32 (uint32_t input) {
 	return OSSwapInt32(input);
@@ -55,96 +48,106 @@
 	return input;
 }
 
-/* Parse a Mach-O header */
-Tcl_Obj * list_macho_dlibs_l(macho_input_t *input, Tcl_Interp * interp, Tcl_Obj * dlibs) {
-	/* Read the file type. */
-	const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t));
 
-	/* Parse the Mach-O header */
-	bool m64 = false;
-	bool universal = false;
-	uint32_t (*swap32)(uint32_t) = macho_nswap32;
+/* If the file is a universal binary, this function is called to call the callback function on each header */
+Tcl_Obj * handle_universal(macho_input_t *input, Tcl_Interp * interp,  const struct fat_header * fat_header,
+	Tcl_Obj* (*callback_func)(macho_input_t *, Tcl_Interp *, Tcl_Obj *) ){
+	uint32_t i;
+	uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch);
+	const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch));
+	Tcl_Obj * return_list = Tcl_NewListObj(0,NULL);
+	if (archs == NULL)
+		return (Tcl_Obj *)TCL_ERROR;
 
-	const struct mach_header *header;
-	const struct mach_header_64 *header64;
-	size_t header_size;
-	const struct fat_header *fat_header;
+	for (i = 0; i < nfat; i++) {
+		const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch));
+		macho_input_t arch_input;
+		if (arch == NULL)
+			return (Tcl_Obj *)TCL_ERROR;
 
-	const NXArchInfo *archInfo;
-	const struct load_command *cmd;
-	uint32_t ncmds;
-	uint32_t i;
+		/* Fetch a pointer to the architecture's Mach-O header. */
+		arch_input.length = OSSwapBigToHostInt32(arch->size);
+		arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length);
+		if (arch_input.data == NULL)
+			return (Tcl_Obj *)TCL_ERROR;
 
+		/* Parse the architecture's Mach-O header */
+		if (!callback_func(&arch_input, interp, return_list))
+			return (Tcl_Obj *)TCL_ERROR;
+	}
+	return return_list;
+}
 
-	if (magic == NULL)
-		return (Tcl_Obj *)TCL_ERROR;
+Tcl_Obj * check_magic(const uint32_t magic, macho_input_t *input, bool * universal, uint32_t (**swap32)(uint32_t), const struct mach_header ** header, size_t * header_size){
+	const struct mach_header_64 *header64;
 
-	switch (*magic) {
+	switch (magic) {
 		case MH_CIGAM:
-			swap32 = macho_swap32;
+			*swap32 = macho_swap32;
 			/* Fall-through */
 
 		case MH_MAGIC:
-			header_size = sizeof(*header);
-			header = macho_read(input, input->data, header_size);
-			if (header == NULL) {
-				return false;
+			*header_size = sizeof(**header);
+			*header = macho_read(input, input->data, *header_size);
+			if (*header == NULL) {
+				return (Tcl_Obj *)TCL_ERROR;
 			}
 			break;
 
 		case MH_CIGAM_64:
-			swap32 = macho_swap32;
+			*swap32 = macho_swap32;
 			/* Fall-through */
 
 		case MH_MAGIC_64:
-			header_size = sizeof(*header64);
+			*header_size = sizeof(*header64);
 			header64 = macho_read(input, input->data, sizeof(*header64));
 			if (header64 == NULL)
-				return false;
+				return (Tcl_Obj *)TCL_ERROR;
 
 			/* The 64-bit header is a direct superset of the 32-bit header */
 
-			header = (struct mach_header *) header64;
+			*header = (struct mach_header *) header64;
 
-			m64 = true;
 			break;
 
 		case FAT_CIGAM:
 		case FAT_MAGIC:
-			fat_header = macho_read(input, input->data, sizeof(*fat_header));
-			universal = true;
+			*header = macho_read(input, input->data, sizeof(**header));
+			*universal = true;
 			break;
 
 		default:
 			return (Tcl_Obj *)TCL_ERROR;
 	}
+}
+/* Parse a Mach-O header */
+Tcl_Obj * list_macho_dlibs_l(macho_input_t *input, Tcl_Interp * interp, Tcl_Obj * dlibs) {
 
-	/* Parse universal file. */
-	if (universal) {
-		uint32_t i;
-		uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch);
-		const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch));
-		if (archs == NULL)
-			return false;
+	/* Parse the Mach-O header */
+	const uint32_t *magic;
+	bool universal = false;
+	uint32_t (*swap32)(uint32_t) = macho_nswap32;
+	const struct mach_header *header;
+	size_t header_size;
 
-		for (i = 0; i < nfat; i++) {
-			const struct fat_arch *arch = macho_read(input, archs + i, sizeof(struct fat_arch));
-			macho_input_t arch_input;
-			if (arch == NULL)
-				return false;
+	const NXArchInfo *archInfo;
+	const struct load_command *cmd;
+	uint32_t ncmds;
+	uint32_t i;
 
-			/* Fetch a pointer to the architecture's Mach-O header. */
-			arch_input.length = OSSwapBigToHostInt32(arch->size);
-			arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length);
-			if (arch_input.data == NULL)
-				return false;
+	/* get file header magic */
+	magic = macho_read(input, input->data, sizeof(uint32_t));
+	if (magic == NULL)
+		return (Tcl_Obj *)TCL_ERROR;
 
-			/* Parse the architecture's Mach-O header */
-			if (!list_macho_dlibs_l(&arch_input, interp, dlibs))
-				return false;
-		}
+	/* Check file header magic */
+	if(check_magic(*magic, input, &universal, &swap32, &header, &header_size) == (Tcl_Obj *)TCL_ERROR){
+		return (Tcl_Obj *)TCL_ERROR;
+	}
 
-		return dlibs;
+	/* Parse universal file. */
+	if (universal) {
+		return handle_universal(input, interp, &header, list_macho_dlibs_l);
 	}
 
 	/* Fetch the arch name */
@@ -234,90 +237,31 @@
 
 /* List Mach-O archs */
 Tcl_Obj * list_macho_archs_l(macho_input_t *input, Tcl_Interp *interp, Tcl_Obj * archs_list) {
-	const struct mach_header *header;
-	const struct mach_header_64 *header64;
-	size_t header_size;
-	const NXArchInfo *archInfo;
-	const struct fat_header *fat_header;
-
 	/* Parse the Mach-O header */
+	const uint32_t *magic;
 	bool universal = false;
 	uint32_t (*swap32)(uint32_t) = macho_nswap32;
+	const struct mach_header *header;
+	size_t header_size;
 
-	/* Read the file type. */
-	const uint32_t *magic = macho_read(input, input->data, sizeof(uint32_t));
+	const NXArchInfo *archInfo;
+	const struct load_command *cmd;
+	uint32_t ncmds;
+	uint32_t i;
+
+	/* get file header magic */
+	magic = macho_read(input, input->data, sizeof(uint32_t));
 	if (magic == NULL)
-		return false;
+		return (Tcl_Obj *)TCL_ERROR;
 
-
-
-	switch (*magic) {
-		case MH_CIGAM:
-			swap32 = macho_swap32;
-			/* Fall-through */
-
-		case MH_MAGIC:
-			header_size = sizeof(*header);
-			header = macho_read(input, input->data, header_size);
-			if (header == NULL) {
-				return (Tcl_Obj *)TCL_ERROR;
-			}
-			break;
-
-
-		case MH_CIGAM_64:
-			swap32 = macho_swap32;
-			/* Fall-through */
-
-		case MH_MAGIC_64:
-			header_size = sizeof(*header64);
-			header64 = macho_read(input, input->data, sizeof(*header64));
-			if (header64 == NULL)
-				return (Tcl_Obj *)TCL_ERROR;
-
-			/* The 64-bit header is a direct superset of the 32-bit header */
-			header = (struct mach_header *) header64;
-
-			break;
-
-		case FAT_CIGAM:
-		case FAT_MAGIC:
-			fat_header = macho_read(input, input->data, sizeof(*fat_header));
-			universal = true;
-			break;
-
-		default:
-			return (Tcl_Obj *)TCL_ERROR;
+	/* Check file header magic */
+	if(check_magic(*magic, input, &universal, &swap32, &header, &header_size) == (Tcl_Obj *)TCL_ERROR){
+		return (Tcl_Obj *)TCL_ERROR;
 	}
 
 	/* Parse universal file. */
 	if (universal) {
-		uint32_t nfat = OSSwapBigToHostInt32(fat_header->nfat_arch);
-		const struct fat_arch *archs = macho_offset(input, fat_header, sizeof(struct fat_header), sizeof(struct fat_arch));
-		uint32_t i;
-		const struct fat_arch *arch;
-		macho_input_t arch_input;
-
-		if (archs == NULL)
-			return (Tcl_Obj *)TCL_ERROR;
-
-		for (i = 0; i < nfat; i++) {
-			arch = macho_read(input, archs + i, sizeof(struct fat_arch));
-			if (arch == NULL)
-				return (Tcl_Obj *)TCL_ERROR;
-
-			/* Fetch a pointer to the architecture's Mach-O header. */
-			arch_input.length = OSSwapBigToHostInt32(arch->size);
-			arch_input.data = macho_offset(input, input->data, OSSwapBigToHostInt32(arch->offset), arch_input.length);
-			if (arch_input.data == NULL)
-				return (Tcl_Obj *)TCL_ERROR;
-
-			/* Parse the architecture's Mach-O header */
-			if (!list_macho_archs_l(&arch_input, interp, archs_list))
-				return (Tcl_Obj *)TCL_ERROR;
-		}
-
-		return archs_list;
+		return handle_universal(input, interp, &header, list_macho_archs_l);
 	}
 
 	/* Fetch the arch name */
@@ -325,6 +269,7 @@
 	if (archInfo != NULL) {
 		Tcl_ListObjAppendElement(interp, archs_list, Tcl_NewStringObj(archInfo->name,-1));
 	}
+
 	return archs_list;
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110729/223ca972/attachment-0001.html>


More information about the macports-changes mailing list