[50288] trunk/dports/lang/erlang
nottwo at macports.org
nottwo at macports.org
Tue Apr 28 12:03:24 PDT 2009
Revision: 50288
http://trac.macports.org/changeset/50288
Author: nottwo at macports.org
Date: 2009-04-28 12:03:23 -0700 (Tue, 28 Apr 2009)
Log Message:
-----------
erlang: update to version R13B
Modified Paths:
--------------
trunk/dports/lang/erlang/Portfile
Added Paths:
-----------
trunk/dports/lang/erlang/files/patch-erts_configure.diff
Removed Paths:
-------------
trunk/dports/lang/erlang/files/mach_override.c
trunk/dports/lang/erlang/files/mach_override.h
trunk/dports/lang/erlang/files/patch-eunit_xml.diff
Modified: trunk/dports/lang/erlang/Portfile
===================================================================
--- trunk/dports/lang/erlang/Portfile 2009-04-28 19:03:13 UTC (rev 50287)
+++ trunk/dports/lang/erlang/Portfile 2009-04-28 19:03:23 UTC (rev 50288)
@@ -1,9 +1,8 @@
-# $Id$
+# $Id: Portfile 44939 2009-01-04 23:22:47Z bfulgham at macports.org $
PortSystem 1.0
name erlang
-version R12B-5
-revision 1
+version R13B
categories lang erlang
maintainers bfulgham at macports.org
platforms darwin
@@ -32,18 +31,18 @@
otp_doc_man_${version}${extract.suffix} \
otp_doc_html_${version}${extract.suffix}
-checksums otp_src_R12B-5.tar.gz \
- md5 3751ea3fea669d2b25c67eeb883734bb \
- sha1 6c45509acf70d35d5def2cbefd86ada093c1ac3a \
- rmd160 7265ae8ebd045ec5b977148a7c9b995eb7ef2d2d \
- otp_doc_man_R12B-5.tar.gz \
- md5 6231cb172847040395cc34b20781aa3b \
- sha1 ae7036bd2afc9d1fca97f0de2eca84f56656def8 \
- rmd160 e28d555d0a86fc69e0ee091864828c8eaa58d2be \
- otp_doc_html_R12B-5.tar.gz \
- md5 fb0c5454bbd865e881b6712295f6d41f \
- sha1 0bd369d02051e01bac58c9b8665bd3538e116f51 \
- rmd160 b460906043171b27735332ec90c45e38d888869a
+checksums otp_src_R13B.tar.gz \
+ md5 6d8c256468a198458b9f08ba6aa1a384 \
+ sha1 a69611923c48861aef157e7b4a06689d339571ff \
+ rmd160 625bf1b2c9051218dc6a4f3c89eaea50367fa112 \
+ otp_doc_man_R13B.tar.gz \
+ md5 9265ebf3b1041be6ae18e323b0933601 \
+ sha1 9a390f4e670db7b6596200031d4e0dbb6e96578d \
+ rmd160 ea0341750880a30359979d0e6aefcb2a7e1cecb5 \
+ otp_doc_html_R13B.tar.gz \
+ md5 a14b1111550ce2bce65090de5cf3b0ff \
+ sha1 d479dc6f865ae0cd59a9085de20698fae9d71b67 \
+ rmd160 632b54c5b4a2261d61377c171a9ca7e71176bd69
extract.only otp_src_${version}${extract.suffix}
@@ -51,7 +50,6 @@
# http://www.erlang.org/pipermail/erlang-bugs/2008-October/001023.html
# http://www.erlang.org/pipermail/erlang-bugs/2008-October/001024.html
-# http://support.process-one.net/browse/EUNIT-13
patchfiles patch-toolbar.erl \
patch-erts_emulator_Makefile.in \
patch-lib_ssl_c_src_esock_openssl.c \
@@ -59,17 +57,15 @@
patch-lib_ssl_c_src_Makefile.in \
patch-decode_big.c.diff \
patch-decode_fun.c.diff \
- patch-eunit_xml.diff
+ patch-erts_configure.diff
configure.args --prefix=${destroot}${prefix} \
--enable-kernel-poll \
- --disable-smp-support \
+ --enable-threads \
+ --enable-dynamic-ssl-lib \
+ --enable-smp-support \
--enable-hipe
-variant smp {
- configure.args-delete --disable-smp-support
-}
-
variant ssl {
configure.args-append --with-ssl=${prefix}
configure.ldflags-append -lz
@@ -78,29 +74,20 @@
}
variant no-hipe {
- # Currently produces bus errors in 10.5.3 due to changes in
- # signal handling
configure.args-delete --enable-hipe
}
-platform i386 {
- pre-configure {
- file copy ${filespath}/mach_override.h ${workpath}/${name}-${version}/erts/emulator/hipe
- file copy ${filespath}/mach_override.c ${workpath}/${name}-${version}/erts/emulator/hipe
- }
-}
-
-
-depends_build port:gawk
+depends_build port:gawk \
+ port:wxWidgets
depends_run port:tk
post-destroot {
system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_html_${version}${extract.suffix}"
system "tar -C ${destroot}${prefix}/lib/erlang -zxvf ${distpath}/otp_doc_man_${version}${extract.suffix}"
- set erts_dir erts-5.6.5
+ set erts_dir erts-5.7.1
reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/erl
reinplace s|${destroot}|| ${destroot}${prefix}/lib/erlang/bin/start
Deleted: trunk/dports/lang/erlang/files/mach_override.c
===================================================================
--- trunk/dports/lang/erlang/files/mach_override.c 2009-04-28 19:03:13 UTC (rev 50287)
+++ trunk/dports/lang/erlang/files/mach_override.c 2009-04-28 19:03:23 UTC (rev 50288)
@@ -1,603 +0,0 @@
-/*******************************************************************************
- mach_override.c
- Copyright (c) 2003-2005 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
- Some rights reserved: <http://creativecommons.org/licenses/by/2.0/>
-
- ***************************************************************************/
-
-#include "mach_override.h"
-
-#include <mach-o/dyld.h>
-#include <mach/mach_host.h>
-#include <mach/mach_init.h>
-#include <mach/vm_map.h>
-#include <sys/mman.h>
-
-#include <CoreServices/CoreServices.h>
-
-/**************************
-*
-* Constants
-*
-**************************/
-#pragma mark -
-#pragma mark (Constants)
-
-#if defined(__ppc__) || defined(__POWERPC__)
-
-long kIslandTemplate[] = {
- 0x9001FFFC, // stw r0,-4(SP)
- 0x3C00DEAD, // lis r0,0xDEAD
- 0x6000BEEF, // ori r0,r0,0xBEEF
- 0x7C0903A6, // mtctr r0
- 0x8001FFFC, // lwz r0,-4(SP)
- 0x60000000, // nop ; optionally replaced
- 0x4E800420 // bctr
-};
-
-#define kAddressHi 3
-#define kAddressLo 5
-#define kInstructionHi 10
-#define kInstructionLo 11
-
-#elif defined(__i386__)
-
-#define kOriginalInstructionsSize 16
-
-char kIslandTemplate[] = {
- // kOriginalInstructionsSize nop instructions so that we
- // should have enough space to host original instructions
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- // Now the real jump instruction
- 0xE9, 0xEF, 0xBE, 0xAD, 0xDE
-};
-
-#define kInstructions 0
-#define kJumpAddress kInstructions + kOriginalInstructionsSize + 1
-#endif
-
-
-#define kAllocateHigh 1
-#define kAllocateNormal 0
-
-/**************************
-*
-* Data Types
-*
-**************************/
-#pragma mark -
-#pragma mark (Data Types)
-
-typedef struct {
- char instructions[sizeof(kIslandTemplate)];
- int allocatedHigh;
-} BranchIsland;
-
-/**************************
-*
-* Funky Protos
-*
-**************************/
-#pragma mark -
-#pragma mark (Funky Protos)
-
- mach_error_t
-allocateBranchIsland(
- BranchIsland **island,
- int allocateHigh );
-
- mach_error_t
-freeBranchIsland(
- BranchIsland *island );
-
-#if defined(__ppc__) || defined(__POWERPC__)
- mach_error_t
-setBranchIslandTarget(
- BranchIsland *island,
- const void *branchTo,
- long instruction );
-#endif
-
-#if defined(__i386__)
-mach_error_t
-setBranchIslandTarget_i386(
- BranchIsland *island,
- const void *branchTo,
- char* instructions );
-void
-atomic_mov64(
- uint64_t *targetAddress,
- uint64_t value );
-
- static Boolean
-eatKnownInstructions(
- unsigned char *code,
- uint64_t *newInstruction,
- int *howManyEaten,
- char *originalInstructions );
-#endif
-
-/*******************************************************************************
-*
-* Interface
-*
-*******************************************************************************/
-#pragma mark -
-#pragma mark (Interface)
-
- mach_error_t
-mach_override(
- char *originalFunctionSymbolName,
- const char *originalFunctionLibraryNameHint,
- const void *overrideFunctionAddress,
- void **originalFunctionReentryIsland )
-{
- assert( originalFunctionSymbolName );
- assert( strlen( originalFunctionSymbolName ) );
- assert( overrideFunctionAddress );
-
- // Lookup the original function's code pointer.
- long *originalFunctionPtr;
- if( originalFunctionLibraryNameHint )
- _dyld_lookup_and_bind_with_hint(
- originalFunctionSymbolName,
- originalFunctionLibraryNameHint,
- (void*) &originalFunctionPtr,
- NULL );
- else
- _dyld_lookup_and_bind(
- originalFunctionSymbolName,
- (void*) &originalFunctionPtr,
- NULL );
-
- return mach_override_ptr( originalFunctionPtr, overrideFunctionAddress,
- originalFunctionReentryIsland );
-}
-
- mach_error_t
-mach_override_ptr(
- void *originalFunctionAddress,
- const void *overrideFunctionAddress,
- void **originalFunctionReentryIsland )
-{
- assert( originalFunctionAddress );
- assert( overrideFunctionAddress );
-
- long *originalFunctionPtr = (long*) originalFunctionAddress;
- mach_error_t err = err_none;
-
-#if defined(__ppc__) || defined(__POWERPC__)
- // Ensure first instruction isn't 'mfctr'.
- #define kMFCTRMask 0xfc1fffff
- #define kMFCTRInstruction 0x7c0903a6
-
- long originalInstruction = *originalFunctionPtr;
- if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) )
- err = err_cannot_override;
-#elif defined (__i386__)
- int eatenCount = 0;
- char originalInstructions[kOriginalInstructionsSize];
- uint64_t jumpRelativeInstruction = 0; // JMP
-
- Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr,
- &jumpRelativeInstruction, &eatenCount, originalInstructions);
- if (eatenCount > kOriginalInstructionsSize) {
- //printf ("Too many instructions eaten\n");
- overridePossible = false;
- }
- if (!overridePossible) err = err_cannot_override;
-#endif
-
- // Make the original function implementation writable.
- if( !err ) {
- err = vm_protect( mach_task_self(),
- (vm_address_t) originalFunctionPtr,
- sizeof(long), false, (VM_PROT_ALL | VM_PROT_COPY) );
- if( err )
- err = vm_protect( mach_task_self(),
- (vm_address_t) originalFunctionPtr, sizeof(long), false,
- (VM_PROT_DEFAULT | VM_PROT_COPY) );
- }
-
- // Allocate and target the escape island to the overriding function.
- BranchIsland *escapeIsland = NULL;
- if( !err )
- err = allocateBranchIsland( &escapeIsland, kAllocateHigh );
-
-#if defined(__ppc__) || defined(__POWERPC__)
- if( !err )
- err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 );
-
- // Build the branch absolute instruction to the escape island.
- long branchAbsoluteInstruction = 0; // Set to 0 just to silence warning.
- if( !err ) {
- long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF;
- branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress;
- }
-#elif defined (__i386__)
- if( !err )
- err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 );
-
- // Build the jump relative instruction to the escape island
- if (!err) {
- int32_t addressOffset = ((int32_t)escapeIsland - (int32_t)originalFunctionPtr - 5);
- addressOffset = OSSwapInt32(addressOffset);
-
- jumpRelativeInstruction |= 0xE900000000000000LL;
- jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24;
- jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction);
- }
-#endif
-
- // Optionally allocate & return the reentry island.
- BranchIsland *reentryIsland = NULL;
- if( !err && originalFunctionReentryIsland ) {
- err = allocateBranchIsland( &reentryIsland, kAllocateNormal );
- if( !err )
- *originalFunctionReentryIsland = reentryIsland;
- }
-
-#if defined(__ppc__) || defined(__POWERPC__)
- // Atomically:
- // o If the reentry island was allocated:
- // o Insert the original instruction into the reentry island.
- // o Target the reentry island at the 2nd instruction of the
- // original function.
- // o Replace the original instruction with the branch absolute.
- if( !err ) {
- int escapeIslandEngaged = false;
- do {
- if( reentryIsland )
- err = setBranchIslandTarget( reentryIsland,
- (void*) (originalFunctionPtr+1), originalInstruction );
- if( !err ) {
- escapeIslandEngaged = CompareAndSwap( originalInstruction,
- branchAbsoluteInstruction,
- (UInt32*)originalFunctionPtr );
- if( !escapeIslandEngaged ) {
- // Someone replaced the instruction out from under us,
- // re-read the instruction, make sure it's still not
- // 'mfctr' and try again.
- originalInstruction = *originalFunctionPtr;
- if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction)
- err = err_cannot_override;
- }
- }
- } while( !err && !escapeIslandEngaged );
- }
-#elif defined (__i386__)
- // Atomically:
- // o If the reentry island was allocated:
- // o Insert the original instructions into the reentry island.
- // o Target the reentry island at the first non-replaced
- // instruction of the original function.
- // o Replace the original first instructions with the jump relative.
- //
- // Note that on i386, we do not support someone else changing the code under our feet
- if ( !err ) {
- if( reentryIsland )
- err = setBranchIslandTarget_i386( reentryIsland,
- (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions );
- if ( !err )
- atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction);
- }
-#endif
-
- // Clean up on error.
- if( err ) {
- if( reentryIsland )
- freeBranchIsland( reentryIsland );
- if( escapeIsland )
- freeBranchIsland( escapeIsland );
- }
-
- return err;
-}
-
-/*******************************************************************************
-*
-* Implementation
-*
-*******************************************************************************/
-#pragma mark -
-#pragma mark (Implementation)
-
-/***************************************************************************//**
- Implementation: Allocates memory for a branch island.
-
- @param island <- The allocated island.
- @param allocateHigh -> Whether to allocate the island at the end of the
- address space (for use with the branch absolute
- instruction).
- @result <- mach_error_t
-
- ***************************************************************************/
-
- mach_error_t
-allocateBranchIsland(
- BranchIsland **island,
- int allocateHigh )
-{
- assert( island );
-
- mach_error_t err = err_none;
-
- if( allocateHigh ) {
- vm_size_t pageSize;
- err = host_page_size( mach_host_self(), &pageSize );
- if( !err ) {
- assert( sizeof( BranchIsland ) <= pageSize );
- vm_address_t first = 0xfeffffff;
- vm_address_t last = 0xfe000000 + pageSize;
- vm_address_t page = first;
- int allocated = 0;
- vm_map_t task_self = mach_task_self();
-
- while( !err && !allocated && page != last ) {
- err = vm_allocate( task_self, &page, pageSize, 0 );
- if( err == err_none )
- allocated = 1;
- else if( err == KERN_NO_SPACE ) {
- page += pageSize;
- err = err_none;
- }
- }
- if( allocated )
- *island = (void*) page;
- else if( !allocated && !err )
- err = KERN_NO_SPACE;
- }
- } else {
- void *block = malloc( sizeof( BranchIsland ) );
- if( block )
- *island = block;
- else
- err = KERN_NO_SPACE;
- }
- if( !err )
- (**island).allocatedHigh = allocateHigh;
-
- return err;
-}
-
-/***************************************************************************//**
- Implementation: Deallocates memory for a branch island.
-
- @param island -> The island to deallocate.
- @result <- mach_error_t
-
- ***************************************************************************/
-
- mach_error_t
-freeBranchIsland(
- BranchIsland *island )
-{
- assert( island );
- assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] );
- assert( island->allocatedHigh );
-
- mach_error_t err = err_none;
-
- if( island->allocatedHigh ) {
- vm_size_t pageSize;
- err = host_page_size( mach_host_self(), &pageSize );
- if( !err ) {
- assert( sizeof( BranchIsland ) <= pageSize );
- err = vm_deallocate(
- mach_task_self(),
- (vm_address_t) island, pageSize );
- }
- } else {
- free( island );
- }
-
- return err;
-}
-
-/***************************************************************************//**
- Implementation: Sets the branch island's target, with an optional
- instruction.
-
- @param island -> The branch island to insert target into.
- @param branchTo -> The address of the target.
- @param instruction -> Optional instruction to execute prior to branch. Set
- to zero for nop.
- @result <- mach_error_t
-
- ***************************************************************************/
-#if defined(__ppc__) || defined(__POWERPC__)
- mach_error_t
-setBranchIslandTarget(
- BranchIsland *island,
- const void *branchTo,
- long instruction )
-{
- // Copy over the template code.
- bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) );
-
- // Fill in the address.
- ((short*)island->instructions)[kAddressLo] = ((long) branchTo) & 0x0000FFFF;
- ((short*)island->instructions)[kAddressHi]
- = (((long) branchTo) >> 16) & 0x0000FFFF;
-
- // Fill in the (optional) instuction.
- if( instruction != 0 ) {
- ((short*)island->instructions)[kInstructionLo]
- = instruction & 0x0000FFFF;
- ((short*)island->instructions)[kInstructionHi]
- = (instruction >> 16) & 0x0000FFFF;
- }
-
- //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) );
- msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE );
-
- return err_none;
-}
-#endif
-
-#if defined(__i386__)
- mach_error_t
-setBranchIslandTarget_i386(
- BranchIsland *island,
- const void *branchTo,
- char* instructions )
-{
-
- // Copy over the template code.
- bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) );
-
- // copy original instructions
- if (instructions) {
- bcopy (instructions, island->instructions + kInstructions, kOriginalInstructionsSize);
- }
-
- // Fill in the address.
- int32_t addressOffset = (char *)branchTo - (island->instructions + kJumpAddress + 4);
- *((int32_t *)(island->instructions + kJumpAddress)) = addressOffset;
-
- //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) );
- msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE );
-
- return err_none;
-}
-#endif
-
-
-#if defined (__i386__)
-// simplistic instruction matching
-typedef struct {
- unsigned int length; // max 15
- unsigned char mask[15]; // sequence of bytes in memory order
- unsigned char constraint[15]; // sequence of bytes in memory order
-} AsmInstructionMatch;
-
-static AsmInstructionMatch possibleInstructions[] = {
- { 0x1, {0xFF}, {0x90} }, // nop
- { 0x1, {0xFF}, {0x55} }, // push %esp
- { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp
- { 0x1, {0xFF}, {0x53} }, // push %ebx
- { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp
- { 0x1, {0xFF}, {0x57} }, // push %edi
- { 0x1, {0xFF}, {0x56} }, // push %esi
- { 0x0 }
-};
-
-static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch* instruction)
-{
- Boolean match = true;
-
- int i;
- for (i=0; i<instruction->length; i++) {
- unsigned char mask = instruction->mask[i];
- unsigned char constraint = instruction->constraint[i];
- unsigned char codeValue = code[i];
- match = ((codeValue & mask) == constraint);
- if (!match) break;
- }
-
- return match;
-}
-
- static Boolean
-eatKnownInstructions(
- unsigned char *code,
- uint64_t* newInstruction,
- int* howManyEaten,
- char* originalInstructions )
-{
- Boolean allInstructionsKnown = true;
- int totalEaten = 0;
- unsigned char* ptr = code;
- int remainsToEat = 5; // a JMP instruction takes 5 bytes
-
- if (howManyEaten) *howManyEaten = 0;
- while (remainsToEat > 0) {
- Boolean curInstructionKnown = false;
-
- // See if instruction matches one we know
- AsmInstructionMatch* curInstr = possibleInstructions;
- do {
- if (curInstructionKnown = codeMatchesInstruction(ptr, curInstr)) break;
- curInstr++;
- } while (curInstr->length > 0);
-
- // if all instruction matches failed, we don't know current instruction then, stop here
- if (!curInstructionKnown) {
- allInstructionsKnown = false;
- break;
- }
-
- // At this point, we've matched curInstr
- int eaten = curInstr->length;
- ptr += eaten;
- remainsToEat -= eaten;
- totalEaten += eaten;
- }
-
-
- if (howManyEaten) *howManyEaten = totalEaten;
-
- if (originalInstructions) {
- Boolean enoughSpaceForOriginalInstructions = (totalEaten < kOriginalInstructionsSize);
-
- if (enoughSpaceForOriginalInstructions) {
- memset(originalInstructions, 0x90 /* NOP */, kOriginalInstructionsSize); // fill instructions with NOP
- bcopy(code, originalInstructions, totalEaten);
- } else {
- // printf ("Not enough space in island to store original instructions. Adapt the island definition and kOriginalInstructionsSize\n");
- return false;
- }
- }
-
- if (allInstructionsKnown) {
- // save last 3 bytes of first 64bits of codre we'll replace
- uint64_t currentFirst64BitsOfCode = *((uint64_t *)code);
- currentFirst64BitsOfCode = OSSwapInt64(currentFirst64BitsOfCode); // back to memory representation
- currentFirst64BitsOfCode &= 0x0000000000FFFFFFLL;
-
- // keep only last 3 instructions bytes, first 5 will be replaced by JMP instr
- *newInstruction &= 0xFFFFFFFFFF000000LL; // clear last 3 bytes
- *newInstruction |= (currentFirst64BitsOfCode & 0x0000000000FFFFFFLL); // set last 3 bytes
- }
-
- return allInstructionsKnown;
-}
-
-asm(
- ".text;"
- ".align 2, 0x90;"
- ".globl _atomic_mov64;"
- "_atomic_mov64:;"
- " pushl %ebp;"
- " movl %esp, %ebp;"
- " pushl %esi;"
- " pushl %ebx;"
- " pushl %ecx;"
- " pushl %eax;"
- " pushl %edx;"
-
- // atomic push of value to an address
- // we use cmpxchg8b, which compares content of an address with
- // edx:eax. If they are equal, it atomically puts 64bit value
- // ecx:ebx in address.
- // We thus put contents of address in edx:eax to force ecx:ebx
- // in address
- " mov 8(%ebp), %esi;" // esi contains target address
- " mov 12(%ebp), %ebx;"
- " mov 16(%ebp), %ecx;" // ecx:ebx now contains value to put in target address
- " mov (%esi), %eax;"
- " mov 4(%esi), %edx;" // edx:eax now contains value currently contained in target address
- " lock; cmpxchg8b (%esi);" // atomic move.
-
- // restore registers
- " popl %edx;"
- " popl %eax;"
- " popl %ecx;"
- " popl %ebx;"
- " popl %esi;"
- " popl %ebp;"
- " ret"
-);
-
-#endif
Deleted: trunk/dports/lang/erlang/files/mach_override.h
===================================================================
--- trunk/dports/lang/erlang/files/mach_override.h 2009-04-28 19:03:13 UTC (rev 50287)
+++ trunk/dports/lang/erlang/files/mach_override.h 2009-04-28 19:03:23 UTC (rev 50288)
@@ -1,123 +0,0 @@
-/*******************************************************************************
- mach_override.h
- Copyright (c) 2003-2005 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
- Some rights reserved: <http://creativecommons.org/licenses/by/2.0/>
-
- ***************************************************************************/
-
-/***************************************************************************//**
- @mainpage mach_override
- @author Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
-
- This package, coded in C to the Mach API, allows you to override ("patch")
- program- and system-supplied functions at runtime. You can fully replace
- functions with your implementations, or merely head- or tail-patch the
- original implementations.
-
- Use it by #include'ing mach_override.h from your .c, .m or .mm file(s).
-
- @todo Discontinue use of Carbon's MakeDataExecutable() and
- CompareAndSwap() calls and start using the Mach equivalents, if they
- exist. If they don't, write them and roll them in. That way, this
- code will be pure Mach, which will make it easier to use everywhere.
- Update: MakeDataExecutable() has been replaced by
- msync(MS_INVALIDATE). There is an OSCompareAndSwap in libkern, but
- I'm currently unsure if I can link against it. May have to roll in
- my own version...
- @todo Stop using an entire 4K high-allocated VM page per 28-byte escape
- branch island. Done right, this will dramatically speed up escape
- island allocations when they number over 250. Then again, if you're
- overriding more than 250 functions, maybe speed isn't your main
- concern...
- @todo Add detection of: b, bl, bla, bc, bcl, bcla, bcctrl, bclrl
- first-instructions. Initially, we should refuse to override
- functions beginning with these instructions. Eventually, we should
- dynamically rewrite them to make them position-independent.
- @todo Write mach_unoverride(), which would remove an override placed on a
- function. Must be multiple-override aware, which means an almost
- complete rewrite under the covers, because the target address can't
- be spread across two load instructions like it is now since it will
- need to be atomically updatable.
- @todo Add non-rentry variants of overrides to test_mach_override.
-
- ***************************************************************************/
-
-#ifndef _mach_override_
-#define _mach_override_
-
-#include <sys/types.h>
-#include <mach/error.h>
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/**
- Returned if the function to be overrided begins with a 'mfctr' instruction.
-*/
-#define err_cannot_override (err_local|1)
-
-/***************************************************************************//**
- Dynamically overrides the function implementation referenced by
- originalFunctionSymbolName with the implentation pointed to by
- overrideFunctionAddress. Optionally returns a pointer to a "reentry island"
- which, if jumped to, will resume the original implementation.
-
- @param originalFunctionSymbolName -> Required symbol name of the
- function to override (with
- overrideFunctionAddress).
- Remember, C function name
- symbols are prepended with an
- underscore.
- @param originalFunctionLibraryNameHint -> Optional name of the library
- which contains
- originalFunctionSymbolName. Can
- be NULL, but this may result in
- the wrong function being
- overridden and/or a crash.
- @param overrideFunctionAddress -> Required address to the
- overriding function.
- @param originalFunctionReentryIsland <- Optional pointer to pointer to
- the reentry island. Can be NULL.
- @result <- err_cannot_override if the
- original function's
- implementation begins with the
- 'mfctr' instruction.
-
- ***************************************************************************/
-
- mach_error_t
-mach_override(
- char *originalFunctionSymbolName,
- const char *originalFunctionLibraryNameHint,
- const void *overrideFunctionAddress,
- void **originalFunctionReentryIsland );
-
-/************************************************************************************//**
- Dynamically overrides the function implementation referenced by
- originalFunctionAddress with the implentation pointed to by overrideFunctionAddress.
- Optionally returns a pointer to a "reentry island" which, if jumped to, will resume
- the original implementation.
-
- @param originalFunctionAddress -> Required address of the function to
- override (with overrideFunctionAddress).
- @param overrideFunctionAddress -> Required address to the overriding
- function.
- @param originalFunctionReentryIsland <- Optional pointer to pointer to the
- reentry island. Can be NULL.
- @result <- err_cannot_override if the original
- function's implementation begins with
- the 'mfctr' instruction.
-
- ************************************************************************************/
-
- mach_error_t
-mach_override_ptr(
- void *originalFunctionAddress,
- const void *overrideFunctionAddress,
- void **originalFunctionReentryIsland );
-
-#ifdef __cplusplus
- }
-#endif
-#endif // _mach_override_
\ No newline at end of file
Added: trunk/dports/lang/erlang/files/patch-erts_configure.diff
===================================================================
--- trunk/dports/lang/erlang/files/patch-erts_configure.diff (rev 0)
+++ trunk/dports/lang/erlang/files/patch-erts_configure.diff 2009-04-28 19:03:23 UTC (rev 50288)
@@ -0,0 +1,220 @@
+--- erts/configure.orig 2009-04-21 11:33:14.000000000 -0400
++++ erts/configure 2009-04-21 10:49:56.000000000 -0400
+@@ -19528,6 +19742,91 @@
+ esac
+ fi
+ fi
++
++case $ARCH-$OPSYS in
++ amd64-darwin*|x86-darwin*)
++ { $as_echo "$as_me:$LINENO: checking For modern (leopard) style mcontext_t" >&5
++$as_echo_n "checking For modern (leopard) style mcontext_t... " >&6; }
++ cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++
++ #include <stdlib.h>
++ #include <sys/types.h>
++ #include <unistd.h>
++ #include <mach/mach.h>
++ #include <pthread.h>
++ #include <machine/signal.h>
++ #include <ucontext.h>
++
++int
++main ()
++{
++
++ #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
++ #define __DARWIN__ 1
++ #endif
++
++ #ifndef __DARWIN__
++ #error inpossible
++ #else
++
++ mcontext_t mc = NULL;
++ int x = mc->__fs.__fpu_mxcsr;
++
++ #endif
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (ac_try="$ac_compile"
++case "(($ac_try" in
++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++ *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
++$as_echo "$ac_try_echo") >&5
++ (eval "$ac_compile") 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } && {
++ test -z "$ac_c_werror_flag" ||
++ test ! -s conftest.err
++ } && test -s conftest.$ac_objext; then
++ darwin_mcontext_leopard=yes
++else
++ $as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ darwin_mcontext_leopard=no
++fi
++
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++ if test X"$darwin_mcontext_leopard" = X"yes"; then
++
++cat >>confdefs.h <<\_ACEOF
++#define DARWIN_MODERN_MCONTEXT /**/
++_ACEOF
++
++ { $as_echo "$as_me:$LINENO: result: yes" >&5
++$as_echo "yes" >&6; }
++ else
++ { $as_echo "$as_me:$LINENO: result: no" >&5
++$as_echo "no" >&6; }
++ fi
++ ;;
++ *)
++ darwin_mcontext_leopard=no
++ ;;
++esac
+ if test X${enable_fp_exceptions} = Xauto ; then
+ if test X${enable_hipe} = Xyes; then
+ enable_fp_exceptions=yes
+@@ -19920,6 +20219,7 @@
+ regs[PT_FPSCR] = 0x80|0x40|0x10; /* VE, OE, ZE; not UE or XE */
+ #endif
+ #elif defined(__DARWIN__)
++#if defined(DARWIN_MODERN_MCONTEXT)
+ #if defined(__x86_64__)
+ mcontext_t mc = uc->uc_mcontext;
+ struct __darwin_x86_float_state64 *fpstate = &mc->__fs;
+@@ -19935,6 +20235,23 @@
+ mc->ss.srr0 += 4;
+ mc->fs.fpscr = 0x80|0x40|0x10;
+ #endif
++#else
++#if defined(__x86_64__)
++ mcontext_t mc = uc->uc_mcontext;
++ struct x86_float_state64_t *fpstate = &mc->fs;
++ fpstate->fpu_mxcsr = 0x1F80;
++ *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
++#elif defined(__i386__)
++ mcontext_t mc = uc->uc_mcontext;
++ x86_float_state32_t *fpstate = &mc->fs;
++ fpstate->fpu_mxcsr = 0x1F80;
++ *(unsigned short *)&fpstate->fpu_fsw &= ~0xFF;
++#elif defined(__ppc__)
++ mcontext_t mc = uc->uc_mcontext;
++ mc->ss.srr0 += 4;
++ mc->fs.fpscr = 0x80|0x40|0x10;
++#endif
++#endif
+ #elif defined(__FreeBSD__) && defined(__x86_64__)
+ mcontext_t *mc = &uc->uc_mcontext;
+ struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate;
+@@ -20069,93 +20400,6 @@
+ fi
+ fi
+
+-case $ARCH-$OPSYS in
+- amd64-darwin*|x86-darwin*)
+- echo "$as_me:$LINENO: checking For modern (leopard) style mcontext_t" >&5
+-echo $ECHO_N "checking For modern (leopard) style mcontext_t... $ECHO_C" >&6
+- cat >conftest.$ac_ext <<_ACEOF
+-/* confdefs.h. */
+-_ACEOF
+-cat confdefs.h >>conftest.$ac_ext
+-cat >>conftest.$ac_ext <<_ACEOF
+-/* end confdefs.h. */
+-
+- #include <stdlib.h>
+- #include <sys/types.h>
+- #include <unistd.h>
+- #include <mach/mach.h>
+- #include <pthread.h>
+- #include <machine/signal.h>
+- #include <ucontext.h>
+-
+-int
+-main ()
+-{
+-
+- #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+- #define __DARWIN__ 1
+- #endif
+-
+- #ifndef __DARWIN__
+- #error inpossible
+- #else
+-
+- mcontext_t mc = NULL;
+- int x = mc->__fs.__fpu_mxcsr;
+-
+- #endif
+-
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest.$ac_objext
+-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+- (eval $ac_compile) 2>conftest.er1
+- ac_status=$?
+- grep -v '^ *+' conftest.er1 >conftest.err
+- rm -f conftest.er1
+- cat conftest.err >&5
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -z "$ac_c_werror_flag"
+- || test ! -s conftest.err'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; } &&
+- { ac_try='test -s conftest.$ac_objext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- darwin_mcontext_leopard=yes
+-else
+- echo "$as_me: failed program was:" >&5
+-sed 's/^/| /' conftest.$ac_ext >&5
+-
+-darwin_mcontext_leopard=no
+-fi
+-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+- if test X"$darwin_mcontext_leopard" = X"yes"; then
+-
+-cat >>confdefs.h <<\_ACEOF
+-#define DARWIN_MODERN_MCONTEXT
+-_ACEOF
+-
+- echo "$as_me:$LINENO: result: yes" >&5
+-echo "${ECHO_T}yes" >&6
+- else
+- echo "$as_me:$LINENO: result: no" >&5
+-echo "${ECHO_T}no" >&6
+- fi
+- ;;
+- *)
+- darwin_mcontext_leopard=no
+- ;;
+-esac
+
+
+
Deleted: trunk/dports/lang/erlang/files/patch-eunit_xml.diff
===================================================================
--- trunk/dports/lang/erlang/files/patch-eunit_xml.diff 2009-04-28 19:03:13 UTC (rev 50287)
+++ trunk/dports/lang/erlang/files/patch-eunit_xml.diff 2009-04-28 19:03:23 UTC (rev 50288)
@@ -1,542 +0,0 @@
-Index: lib/eunit/src/eunit_xml.erl
-===================================================================
---- lib/eunit/src/eunit_xml.erl (revision 0)
-+++ lib/eunit/src/eunit_xml.erl (revision 0)
-@@ -0,0 +1,496 @@
-+%% This library is free software; you can redistribute it and/or modify
-+%% it under the terms of the GNU Lesser General Public License as
-+%% published by the Free Software Foundation; either version 2 of the
-+%% License, or (at your option) any later version.
-+%%
-+%% This library is distributed in the hope that it will be useful, but
-+%% WITHOUT ANY WARRANTY; without even the implied warranty of
-+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+%% Lesser General Public License for more details.
-+%%
-+%% You should have received a copy of the GNU Lesser General Public
-+%% License along with this library; if not, write to the Free Software
-+%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-+%% USA
-+%%
-+%% $Id$
-+%%
-+%% @author Paul Guyot <paulguyot at ieee.org>
-+%% @copyright 2008 Paul Guyot
-+%% @private
-+%% @see eunit
-+%% @doc XML reports for EUnit
-+
-+-module(eunit_xml).
-+
-+-include("eunit.hrl").
-+-include("eunit_internal.hrl").
-+
-+-export([start/3]).
-+
-+%% ============================================================================
-+%% MACROS
-+%% ============================================================================
-+-define(INDENT, <<" ">>).
-+-define(NEWLINE, <<"\n">>).
-+
-+%% ============================================================================
-+%% TYPES
-+%% ============================================================================
-+-type(chars() :: [char() | any()]). % chars()
-+-type(item_name() :: {
-+ Module :: atom(),
-+ Function :: atom(),
-+ Line :: integer() } | {
-+ Module :: atom(),
-+ Function :: atom() }).
-+-type(tree_entry() :: {
-+ Kind :: group | item,
-+ Id :: [integer()],
-+ Description :: string(),
-+ item_name() | [any()]}). % tree_entry()
-+
-+%% ============================================================================
-+%% RECORDS
-+%% ============================================================================
-+-record(testcase,
-+ {
-+ name :: chars(),
-+ description :: chars(),
-+ result :: ok | {failed, tuple()} | {aborted, tuple()} | {skipped, tuple()},
-+ time :: integer(),
-+ output :: chars()
-+ }).
-+-record(testsuite,
-+ {
-+ name = [] :: chars(),
-+ time = 0 :: integer(),
-+ output = [] :: chars(),
-+ succeeded = 0 :: integer(),
-+ failed = 0 :: integer(),
-+ aborted = 0 :: integer(),
-+ skipped = 0 :: integer(),
-+ testcases = [] :: [#testcase{}]
-+ }).
-+
-+-spec(start/3::([any()], [any()], string())->pid()).
-+start(List, Options, XmlDir) ->
-+ spawn(fun() -> init(List, Options, XmlDir) end).
-+
-+init(List, _Options, XmlDir) ->
-+ TestSuites = dict:new(),
-+ loop(TestSuites, List, XmlDir).
-+
-+loop(TestSuites, List, XmlDir) ->
-+ receive
-+ {status, Id, Status} ->
-+ NewTestSuites = process_status(TestSuites, List, Id, Status),
-+ loop(NewTestSuites, List, XmlDir);
-+ {start, _Reference} ->
-+ loop(TestSuites, List, XmlDir);
-+ {stop, _Reference, _Pid} ->
-+ write_reports(TestSuites, XmlDir);
-+ Unknown ->
-+ io:format("Unknown message: ~p~n", [Unknown]),
-+ loop(TestSuites, List, XmlDir)
-+ end.
-+
-+%% ----------------------------------------------------------------------------
-+%% Process a status message.
-+%% ----------------------------------------------------------------------------
-+process_status(TestSuites, _List, _Id, {progress, 'begin', _Result}) ->
-+ TestSuites;
-+process_status(TestSuites, _List, [], {progress, 'end', _Result}) ->
-+ TestSuites;
-+process_status(TestSuites, List, [GroupId] = Id, {progress, 'end', {Count, Time, Output}}) when is_integer(Count) ->
-+ TestSuite = case dict:find(GroupId, TestSuites) of
-+ {ok, Value} -> Value;
-+ error -> #testsuite{}
-+ end,
-+ Name = case entry(List, Id) of
-+ {value, {group, Id, Description, _Items}} ->
-+ Description;
-+ _ -> ["Unknown-", integer_to_list(GroupId)]
-+ end,
-+ NewTestSuite = TestSuite#testsuite{
-+ name = Name,
-+ time = Time,
-+ output = Output},
-+ dict:store(GroupId, NewTestSuite, TestSuites);
-+process_status(TestSuites, _List, _Id, {progress, 'end', {Count, _Time, _Output}}) when is_integer(Count)->
-+ TestSuites;
-+process_status(TestSuites, List, [GroupId | _Tail] = Id, {progress, 'end', {ok, Time, Output}}) ->
-+ case entry(List, Id) of
-+ {value, {item, Id, Description, NameTuple}} ->
-+ TestSuite = case dict:find(GroupId, TestSuites) of
-+ {ok, Value} -> Value;
-+ error -> #testsuite{}
-+ end,
-+ Name = format_name(NameTuple),
-+ TestCase = #testcase{
-+ name = Name,
-+ description = Description,
-+ result = ok,
-+ time = Time,
-+ output = Output},
-+ NewTestSuite = TestSuite#testsuite{
-+ succeeded = TestSuite#testsuite.succeeded + 1,
-+ testcases = [TestCase | TestSuite#testsuite.testcases]},
-+ dict:store(GroupId, NewTestSuite, TestSuites);
-+ _ -> TestSuites
-+ end;
-+process_status(
-+ TestSuites, List, [GroupId | _Tail] = Id,
-+ {progress, 'end', {{error, {error, {AssertionException, _Details}, _Trace} = Exception}, Time, Output}})
-+ when
-+ AssertionException == assertion_failed;
-+ AssertionException == assertMatch_failed;
-+ AssertionException == assertEqual_failed;
-+ AssertionException == assertException_failed;
-+ AssertionException == assertCmd_failed;
-+ AssertionException == assertCmdOutput_failed ->
-+ case entry(List, Id) of
-+ {value, {item, Id, Description, NameTuple}} ->
-+ TestSuite = case dict:find(GroupId, TestSuites) of
-+ {ok, Value} -> Value;
-+ error -> #testsuite{}
-+ end,
-+ Name = format_name(NameTuple),
-+ TestCase = #testcase{
-+ name = Name,
-+ description = Description,
-+ result = {failed, Exception},
-+ time = Time,
-+ output = Output},
-+ NewTestSuite = TestSuite#testsuite{
-+ failed = TestSuite#testsuite.failed + 1,
-+ testcases = [TestCase | TestSuite#testsuite.testcases]},
-+ dict:store(GroupId, NewTestSuite, TestSuites);
-+ _ -> TestSuites
-+ end;
-+process_status(TestSuites, List, [GroupId | _Tail] = Id, {progress, 'end', {{error, Exception}, Time, Output}}) ->
-+ case entry(List, Id) of
-+ {value, {item, Id, Description, NameTuple}} ->
-+ TestSuite = case dict:find(GroupId, TestSuites) of
-+ {ok, Value} -> Value;
-+ error -> #testsuite{}
-+ end,
-+ Name = format_name(NameTuple),
-+ TestCase = #testcase{
-+ name = Name,
-+ description = Description,
-+ result = {aborted, Exception},
-+ time = Time,
-+ output = Output},
-+ NewTestSuite = TestSuite#testsuite{
-+ aborted = TestSuite#testsuite.aborted + 1,
-+ testcases = [TestCase | TestSuite#testsuite.testcases]},
-+ dict:store(GroupId, NewTestSuite, TestSuites);
-+ _ -> TestSuites
-+ end;
-+process_status(TestSuites, _List, _Id, {cancel, undefined}) -> TestSuites;
-+process_status(TestSuites, List, [GroupId, _Tail] = Id, {cancel, Reason}) ->
-+ TestSuite = case dict:find(GroupId, TestSuites) of
-+ {ok, Value} -> Value;
-+ error -> #testsuite{}
-+ end,
-+ dict:store(GroupId, process_cancel(TestSuite, List, Id, Reason), TestSuites);
-+process_status(TestSuites, _List, _Id, Status) ->
-+ io:format("Unknown status = ~p~n", [Status]),
-+ TestSuites.
-+
-+%% ----------------------------------------------------------------------------
-+%% Process a cancel status.
-+%% ----------------------------------------------------------------------------
-+process_cancel(TestSuite, List, Id, Reason) ->
-+ case entry(List, Id) of
-+ {value, {item, Id, _Description, _NameTuple} = Item} ->
-+ process_cancel_items(TestSuite, [Item], [], Reason);
-+ {value, {group, Id, _Description, Items}} ->
-+ process_cancel_items(TestSuite, Items, [], Reason);
-+ _ -> TestSuite
-+ end.
-+
-+%% ----------------------------------------------------------------------------
-+%% Process the tests that were skipped because of an error.
-+%%
-+-spec(process_cancel_items/4 :: (#testsuite{}, Items :: [tree_entry()], Acc :: [[tree_entry()]], Reason :: tuple()) -> #testsuite{}).
-+%% ----------------------------------------------------------------------------
-+process_cancel_items(TestSuite, [], [], _Reason) -> TestSuite;
-+process_cancel_items(TestSuite, [], [Acc | Tail], Reason) ->
-+ process_cancel_items(TestSuite, Acc, Tail, Reason);
-+process_cancel_items(TestSuite, [{item, _Id, Description, NameTuple} | Tail], Acc, Reason) ->
-+ Name = format_name(NameTuple),
-+ TestCase = #testcase{
-+ name = Name,
-+ description = Description,
-+ result = {skipped, Reason},
-+ time = 0,
-+ output = []},
-+ NewTestSuite = TestSuite#testsuite{
-+ skipped = TestSuite#testsuite.skipped + 1,
-+ testcases = [TestCase | TestSuite#testsuite.testcases]},
-+ process_cancel_items(NewTestSuite, Tail, Acc, Reason);
-+process_cancel_items(TestSuite, [{group, _Id, _Description, Items} | Tail], Acc, Reason) ->
-+ process_cancel_items(TestSuite, Items, [Tail | Acc], Reason).
-+
-+%% ----------------------------------------------------------------------------
-+%% Convert a test description into a test case name.
-+%% If the test description is a module function, use the function's name.
-+%% If the test description is a module function plus a line, use function.line.
-+%% ----------------------------------------------------------------------------
-+format_name({_Module, Function}) -> atom_to_list(Function);
-+format_name({_Module, Function, Line}) -> [atom_to_list(Function), $., integer_to_list(Line)].
-+
-+%% ----------------------------------------------------------------------------
-+%% Write the reports to the XML directory.
-+%% ----------------------------------------------------------------------------
-+write_reports(TestSuites, XmlDir) ->
-+ dict:fold(fun(_GroupId, TestSuite, Acc) -> write_report(TestSuite, XmlDir), Acc end, [], TestSuites).
-+
-+%% ----------------------------------------------------------------------------
-+%% Write a report to the XML directory.
-+%% This function opens the report file, calls write_report_to/2 and closes the file.
-+%% ----------------------------------------------------------------------------
-+write_report(#testsuite{name = Name} = TestSuite, XmlDir) ->
-+ Filename = filename:join(XmlDir, lists:flatten(["TEST-", escape_suitename(Name)], ".xml")),
-+ case file:open(Filename, [write, raw]) of
-+ {ok, FileDescriptor} ->
-+ try
-+ write_report_to(TestSuite, FileDescriptor)
-+ after
-+ file:close(FileDescriptor)
-+ end;
-+ {error, _Reason} = Error -> throw(Error)
-+ end.
-+
-+%% ----------------------------------------------------------------------------
-+%% Actually write a report.
-+%% ----------------------------------------------------------------------------
-+write_report_to(TestSuite, FileDescriptor) ->
-+ write_header(FileDescriptor),
-+ write_start_tag(TestSuite, FileDescriptor),
-+ write_testcases(TestSuite#testsuite.testcases, FileDescriptor),
-+ write_end_tag(FileDescriptor).
-+
-+%% ----------------------------------------------------------------------------
-+%% Write the XML header.
-+%% ----------------------------------------------------------------------------
-+write_header(FileDescriptor) ->
-+ file:write(FileDescriptor, [<<"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>">>, ?NEWLINE]).
-+
-+%% ----------------------------------------------------------------------------
-+%% Write the testsuite start tag, with attributes describing the statistics
-+%% of the test suite.
-+%% ----------------------------------------------------------------------------
-+write_start_tag(
-+ #testsuite{
-+ name = Name,
-+ time = Time,
-+ succeeded = Succeeded,
-+ failed = Failed,
-+ skipped = Skipped,
-+ aborted = Aborted},
-+ FileDescriptor) ->
-+ Total = Succeeded + Failed + Skipped + Aborted,
-+ StartTag = [
-+ <<"<testsuite tests=\"">>, integer_to_list(Total),
-+ <<"\" failures=\"">>, integer_to_list(Failed),
-+ <<"\" errors=\"">>, integer_to_list(Aborted),
-+ <<"\" skipped=\"">>, integer_to_list(Skipped),
-+ <<"\" time=\"">>, format_time(Time),
-+ <<"\" name=\"">>, escape_attr(Name),
-+ <<"\">">>, ?NEWLINE],
-+ file:write(FileDescriptor, StartTag).
-+
-+%% ----------------------------------------------------------------------------
-+%% Recursive function to write the test cases.
-+%% ----------------------------------------------------------------------------
-+write_testcases([], _FileDescriptor) -> void;
-+write_testcases([TestCase| Tail], FileDescriptor) ->
-+ write_testcase(TestCase, FileDescriptor),
-+ write_testcases(Tail, FileDescriptor).
-+
-+%% ----------------------------------------------------------------------------
-+%% Write the testsuite end tag.
-+%% ----------------------------------------------------------------------------
-+write_end_tag(FileDescriptor) ->
-+ file:write(FileDescriptor, [<<"</testsuite>">>, ?NEWLINE]).
-+
-+%% ----------------------------------------------------------------------------
-+%% Write a test case, as a testcase tag.
-+%% If the test case was successful and if there was no output, we write an empty
-+%% tag.
-+%% ----------------------------------------------------------------------------
-+write_testcase(
-+ #testcase{
-+ name = Name,
-+ description = Description,
-+ result = Result,
-+ time = Time,
-+ output = Output},
-+ FileDescriptor) ->
-+ DescriptionAttr = case Description of
-+ [] -> [];
-+ _ -> [<<" description=\"">>, escape_attr(Description), <<"\"">>]
-+ end,
-+ StartTag = [
-+ ?INDENT, <<"<testcase time=\"">>, format_time(Time),
-+ <<"\" name=\"">>, escape_attr(Name), <<"\"">>,
-+ DescriptionAttr],
-+ ContentAndEndTag = case {Result, Output} of
-+ {ok, []} -> [<<"/>">>, ?NEWLINE];
-+ _ -> [<<">">>, ?NEWLINE, format_testcase_result(Result), format_testcase_output(Output), ?INDENT, <<"</testcase>">>, ?NEWLINE]
-+ end,
-+ file:write(FileDescriptor, [StartTag, ContentAndEndTag]).
-+
-+%% ----------------------------------------------------------------------------
-+%% Format the result of the test.
-+%% Failed tests are represented with a failure tag.
-+%% Aborted tests are represented with an error tag.
-+%% Skipped tests are represented with a skipped tag.
-+%% ----------------------------------------------------------------------------
-+format_testcase_result(ok) -> [];
-+format_testcase_result({failed, {error, {Type, _}, _} = Exception}) when is_atom(Type) ->
-+ [?INDENT, ?INDENT, <<"<failure type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
-+ <<"::">>, escape_text(eunit_lib:format_exception(Exception)),
-+ ?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
-+format_testcase_result({failed, Term}) ->
-+ [?INDENT, ?INDENT, <<"<failure type=\"unknown\">">>, ?NEWLINE,
-+ escape_text(io_lib:write(Term)),
-+ ?INDENT, ?INDENT, <<"</failure>">>, ?NEWLINE];
-+format_testcase_result({aborted, {Class, _Term, _Trace} = Exception}) when is_atom(Class) ->
-+ [?INDENT, ?INDENT, <<"<error type=\"">>, escape_attr(atom_to_list(Class)), <<"\">">>, ?NEWLINE,
-+ <<"::">>, escape_text(eunit_lib:format_exception(Exception)),
-+ ?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
-+format_testcase_result({aborted, Term}) ->
-+ [?INDENT, ?INDENT, <<"<error type=\"unknown\">">>, ?NEWLINE,
-+ escape_text(io_lib:write(Term)),
-+ ?INDENT, ?INDENT, <<"</error>">>, ?NEWLINE];
-+format_testcase_result({skipped, {abort, Error}}) when is_tuple(Error) ->
-+ [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(element(1, Error))), <<"\">">>, ?NEWLINE,
-+ escape_text(eunit_lib:format_error(Error)),
-+ ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE];
-+format_testcase_result({skipped, {Type, Term}}) when is_atom(Type) ->
-+ [?INDENT, ?INDENT, <<"<skipped type=\"">>, escape_attr(atom_to_list(Type)), <<"\">">>, ?NEWLINE,
-+ escape_text(io_lib:write(Term)),
-+ ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE];
-+format_testcase_result({skipped, Term}) ->
-+ [?INDENT, ?INDENT, <<"<skipped type=\"unknown\">">>, ?NEWLINE,
-+ escape_text(io_lib:write(Term)),
-+ ?INDENT, ?INDENT, <<"</skipped>">>, ?NEWLINE].
-+
-+%% ----------------------------------------------------------------------------
-+%% Format the output of a test case in xml.
-+%% Empty output is simply the empty string.
-+%% Other output is inside a <system-out> xml tag.
-+%% ----------------------------------------------------------------------------
-+format_testcase_output([]) -> [];
-+format_testcase_output(Output) ->
-+ [?INDENT, ?INDENT, <<"<system-out>">>, escape_text(Output), ?NEWLINE, ?INDENT, ?INDENT, <<"</system-out>">>, ?NEWLINE].
-+
-+%% ----------------------------------------------------------------------------
-+%% Return the time in the SECS.MILLISECS format.
-+%% ----------------------------------------------------------------------------
-+format_time(Time) ->
-+ format_time_s(lists:reverse(integer_to_list(Time))).
-+format_time_s([Digit]) -> ["0.00", Digit];
-+format_time_s([Digit1, Digit2]) -> ["0.0", Digit2, Digit1];
-+format_time_s([Digit1, Digit2, Digit3]) -> ["0.", Digit3, Digit2, Digit1];
-+format_time_s([Digit1, Digit2, Digit3 | Tail]) -> [lists:reverse(Tail), $., Digit3, Digit2, Digit1].
-+
-+%% ----------------------------------------------------------------------------
-+%% Escape a suite's name to generate the filename.
-+%% Remark: we might overwrite another testsuite's file.
-+%% ----------------------------------------------------------------------------
-+escape_suitename([Head | _T] = List) when is_list(Head) ->
-+ escape_suitename(lists:flatten(List));
-+escape_suitename("module '" ++ String) ->
-+ escape_suitename(String);
-+escape_suitename(String) ->
-+ escape_suitename(String, []).
-+
-+escape_suitename([], Acc) -> lists:reverse(Acc);
-+escape_suitename([$ | Tail], Acc) -> escape_suitename(Tail, [$_ | Acc]);
-+escape_suitename([$' | Tail], Acc) -> escape_suitename(Tail, Acc);
-+escape_suitename([$/ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
-+escape_suitename([$\\ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
-+escape_suitename([Char | Tail], Acc) when Char < $! -> escape_suitename(Tail, Acc);
-+escape_suitename([Char | Tail], Acc) when Char > $~ -> escape_suitename(Tail, Acc);
-+escape_suitename([Char | Tail], Acc) -> escape_suitename(Tail, [Char | Acc]).
-+
-+%% ----------------------------------------------------------------------------
-+%% Escape text for XML text nodes.
-+%% Replace < with <, > with > and & with &
-+%% ----------------------------------------------------------------------------
-+escape_text(Text) -> escape_xml(lists:flatten(Text), [], false).
-+
-+%% ----------------------------------------------------------------------------
-+%% Escape text for XML attribute nodes.
-+%% Replace < with <, > with > and & with &
-+%% ----------------------------------------------------------------------------
-+escape_attr(Text) -> escape_xml(lists:flatten(Text), [], true).
-+
-+escape_xml([], Acc, _ForAttr) -> lists:reverse(Acc);
-+escape_xml([$< | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $l, $& | Acc], ForAttr);
-+escape_xml([$> | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $g, $& | Acc], ForAttr);
-+escape_xml([$& | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $p, $m, $a, $& | Acc], ForAttr);
-+escape_xml([$" | Tail], Acc, true) -> escape_xml(Tail, [$;, $t, $o, $u, $q, $& | Acc], true);
-+escape_xml([Char | Tail], Acc, ForAttr) when is_integer(Char) -> escape_xml(Tail, [Char | Acc], ForAttr).
-+
-+%% ----------------------------------------------------------------------------
-+%% Determine if the second list begins with the first list.
-+%% Return true if it does, false if it doesn't.
-+%% ----------------------------------------------------------------------------
-+begins_with([], _L2) -> true;
-+begins_with([H|T1], [H|T2]) -> begins_with(T1, T2);
-+begins_with(_, _) -> false.
-+
-+%% ----------------------------------------------------------------------------
-+%% Return the entry in the tree for a given ID.
-+%% Return {value, Entry} if the entry was found or
-+%% not_found if it wasn't.
-+-spec(entry/2 :: (List :: [tree_entry()], Id :: [integer()]) -> {value, tree_entry()} | not_found).
-+%% ----------------------------------------------------------------------------
-+entry([{_Kind, Id, _Description, _Data} = Entry | _Tail], Id) -> {value, Entry};
-+entry([{group, [H|_] = Id, _Description, Subnodes} | Tail], [H|_] = NodeId) ->
-+ case begins_with(Id, NodeId) of
-+ true -> entry(Subnodes, NodeId);
-+ false -> entry(Tail, NodeId)
-+ end;
-+entry([_Node | Tail], NodeId) -> entry(Tail, NodeId);
-+entry([], _NodeId) -> not_found.
-+
-+-ifdef(TEST).
-+
-+format_time_test_() ->
-+ [
-+ ?_assertEqual("0.000", lists:flatten(format_time(0))),
-+ ?_assertEqual("0.001", lists:flatten(format_time(1))),
-+ ?_assertEqual("0.042", lists:flatten(format_time(42))),
-+ ?_assertEqual("0.123", lists:flatten(format_time(123))),
-+ ?_assertEqual("1.000", lists:flatten(format_time(1000))),
-+ ?_assertEqual("1.001", lists:flatten(format_time(1001))),
-+ ?_assertEqual("1.042", lists:flatten(format_time(1042))),
-+ ?_assertEqual("20.042", lists:flatten(format_time(20042)))
-+ ].
-+
-+escape_suitename_test_() ->
-+ [
-+ ?_assertEqual("sqlite_test", escape_suitename("module 'sqlite_test'")),
-+ ?_assertEqual("Unknown-2", escape_suitename(["Unknown-", "2"]))
-+ ].
-+
-+escape_test_() ->
-+ [
-+ ?_assertEqual("bla bla bla", escape_text("bla bla bla")),
-+ ?_assertEqual("1 < 2 -> true", escape_text("1 < 2 -> true")),
-+ ?_assertEqual("1 & 2 -> 0", escape_text("1 & 2 -> 0")),
-+ ?_assertEqual("and then it said \"Hello, Dave!\"", escape_text("and then it said \"Hello, Dave!\"")),
-+ ?_assertEqual("bla bla bla", escape_attr("bla bla bla")),
-+ ?_assertEqual("1 < 2 -> true", escape_attr("1 < 2 -> true")),
-+ ?_assertEqual("1 & 2 -> 0", escape_attr("1 & 2 -> 0")),
-+ ?_assertEqual("and then it said "Hello, Dave!"", escape_attr("and then it said \"Hello, Dave!\""))
-+ ].
-+
-+-endif. % TEST
-Index: lib/eunit/src/eunit.erl
-===================================================================
---- lib/eunit/src/eunit.erl.orig 2008-11-04 11:52:12.000000000 +0100
-+++ lib/eunit/src/eunit.erl 2008-11-06 07:24:28.000000000 +0100
-@@ -148,7 +148,7 @@
- try eunit_data:list(Tests) of
- List ->
- Listeners = [eunit_tty:start(List, Options)
-- | listeners(Options)],
-+ | listeners(List, Options)],
- Serial = eunit_serial:start(Listeners),
- case eunit_server:start_test(Server, Serial, Tests, Options) of
- {ok, Reference} -> test_run(Reference, Listeners);
-@@ -197,10 +197,12 @@
- Dummy = spawn(fun devnull/0),
- eunit_server:start_test(Server, Dummy, T, Options).
-
--listeners(Options) ->
-+listeners(List, Options) ->
- case proplists:get_value(event_log, Options) of
- undefined ->
- [];
-+ {xml, XmlDirectory} ->
-+ [eunit_xml:start(List, Options, XmlDirectory)];
- LogFile ->
- [spawn(fun () -> event_logger(LogFile) end)]
- end.
-Index: lib/eunit/src/Makefile
-===================================================================
---- lib/eunit/src/Makefile.orig 2008-11-04 11:52:12.000000000 +0100
-+++ lib/eunit/src/Makefile 2008-11-06 07:23:09.000000000 +0100
-@@ -37,7 +37,8 @@
- eunit_test.erl \
- eunit_lib.erl \
- eunit_data.erl \
-- eunit_tty.erl
-+ eunit_tty.erl \
-+ eunit_xml.erl
-
- OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
-
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20090428/e9a04fd2/attachment-0001.html>
More information about the macports-changes
mailing list