Merge pull request #1 from klickverbot/remove-phobos1

Removed Phobos 1 from LDC tree.
This commit is contained in:
David Nadlinger
2011-08-08 12:07:30 -07:00
122 changed files with 0 additions and 51732 deletions

View File

@@ -1,4 +0,0 @@
[Environment]
DFLAGS=-I%@P%/../lphobos -L-L%@P%/../lib -R%@P%/../lib

View File

@@ -1,2 +0,0 @@
The code in this directory is not maintained and is most likely broken.
There are no plans to revive official Phobos support.

View File

@@ -1,104 +0,0 @@
#!/bin/bash
echo "removing old objects"
mkdir -p obj
rm -f obj/*.bc
rm -f ../lib/*.bc
LDCFLAGS_ASM="-c -oq -release"
LDCFLAGS="$LDCFLAGS_ASM -noasm"
echo "compiling contract runtime"
ldc internal/contract.d -c -of../lib/ldcore.bc || exit 1 #-noruntime || exit 1
echo "compiling common runtime"
./ldc-build internal/arrays.d \
internal/mem.d \
internal/critical.d \
internal/dmain2.d \
internal/inv.d \
$LDCFLAGS_ASM || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc obj/internal.*.bc ../lib/ldcore.bc
echo "compiling typeinfo 1"
./ldc-build typeinfos1.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc `ls obj/typeinfo1.*.bc` ../lib/ldcore.bc || exit 1
echo "compiling typeinfo 2"
./ldc-build typeinfos2.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc `ls obj/typeinfo2.*.bc` ../lib/ldcore.bc || exit 1
echo "compiling exceptions"
./ldc-build internal/eh.d $LDCFLAGS -debug || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc obj/*eh.bc ../lib/ldcore.bc || exit 1
echo "compiling object/interface casting runtime support"
ldc internal/cast.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc obj/cast.bc ../lib/ldcore.bc || exit 1
echo "compiling string foreach/switch runtime support"
ldc internal/aApply.d $LDCFLAGS || exit 1
ldc internal/aApplyR.d $LDCFLAGS || exit 1
ldc internal/switch.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc obj/aApply.bc obj/aApplyR.bc obj/switch.bc ../lib/ldcore.bc || exit 1
echo "compiling array runtime support"
ldc internal/qsort2.d internal/adi.d internal/aaA.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc obj/qsort2.bc obj/adi.bc obj/aaA.bc ../lib/ldcore.bc || exit 1
echo "compiling object implementation"
ldc internal/objectimpl.d $LDCFLAGS || exit 1
mv object.bc objectimpl.bc
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc obj/objectimpl.bc ../lib/ldcore.bc || exit 1
echo "compiling crc32"
ldc crc32.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc ../lib/ldcore.bc obj/crc32.bc || exit 1
echo "compiling llvm runtime support"
# ./ldc-build llvmsupport.d $LDCFLAGS || exit 1
ldc llvmsupport.d -oq -c || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc `ls obj/llvm*.bc` ../lib/ldcore.bc || exit 1
echo "compiling garbage collector"
cd gc
ldc $(ls *.d |grep -v win32) $LDCFLAGS_ASM -I.. ||exit 1
# ldc gclinux.d $LDCFLAGS -I.. || exit 1
# ldc gcx.d $LDCFLAGS -I.. || exit 1
# ldc gcbits.d $LDCFLAGS -I.. || exit 1
# ldc gc.d -oq -c -I.. || exit 1
mv std.gc.bc std_gc.bc
mv *.bc ../obj
# mv -v obj/*.bc ../obj
cd ..
llvm-link -f -o=../lib/ldcore.bc obj/gclinux.bc obj/gcx.bc obj/gcbits.bc obj/std_gc.bc ../lib/ldcore.bc || exit 1
echo "compiling phobos"
./ldc-build phobos.d $LDCFLAGS || exit 1
mv *.bc obj
echo "linking phobos"
# llvm-link -f -o=../lib/ldcore.bc `ls obj/std.*.bc` ../lib/ldcore.bc || exit 1
for i in $(ls obj/std.*.bc); do
echo $i
llvm-link -f -o=../lib/ldcore.bc ../lib/ldcore.bc $i || exit 1
done
echo "Compiling auxiliary"
./ldc-build etc/c/zlib.d $LDCFLAGS || exit 1
mv *.bc obj
llvm-link -f -o=../lib/ldcore.bc `ls obj/etc.*.bc` ../lib/ldcore.bc || exit 1
echo "optimizing"
opt -stats -p -f -std-compile-opts -o=../lib/ldcore.bc ../lib/ldcore.bc || exit 1
echo "SUCCESS"

View File

@@ -1,79 +0,0 @@
/*
* Copyright (c) 2001, 2002
* Pavel "EvilOne" Minayev
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Author makes no representations about
* the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*/
// CRC-32 calculation
module crc32;
private uint[256] crc32_table =
[
0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535,
0x9e6495a3,0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,0x09b64c2b,0x7eb17cbd,
0xe7b82d07,0x90bf1d91,0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de,0x1adad47d,
0x6ddde4eb,0xf4d4b551,0x83d385c7,0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,
0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5,0x3b6e20c8,0x4c69105e,0xd56041e4,
0xa2677172,0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b,0x35b5a8fa,0x42b2986c,
0xdbbbc9d6,0xacbcf940,0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,0x26d930ac,
0x51de003a,0xc8d75180,0xbfd06116,0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f,
0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924,0x2f6f7c87,0x58684c11,0xc1611dab,
0xb6662d3d,0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a,0x71b18589,0x06b6b51f,
0x9fbfe4a5,0xe8b8d433,0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818,0x7f6a0dbb,
0x086d3d2d,0x91646c97,0xe6635c01,0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,
0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,0x65b0d9c6,0x12b7e950,0x8bbeb8ea,
0xfcb9887c,0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,0x4db26158,0x3ab551ce,
0xa3bc0074,0xd4bb30e2,0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,0x4369e96a,
0x346ed9fc,0xad678846,0xda60b8d0,0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9,
0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,0x5768b525,0x206f85b3,0xb966d409,
0xce61e49f,0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,0x59b33d17,0x2eb40d81,
0xb7bd5c3b,0xc0ba6cad,0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a,0xead54739,
0x9dd277af,0x04db2615,0x73dc1683,0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8,
0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1,0xf00f9344,0x8708a3d2,0x1e01f268,
0x6906c2fe,0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7,0xfed41b76,0x89d32be0,
0x10da7a5a,0x67dd4acc,0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5,0xd6d6a3e8,
0xa1d1937e,0x38d8c2c4,0x4fdff252,0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b,
0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60,0xdf60efc3,0xa867df55,0x316e8eef,
0x4669be79,0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236,0xcc0c7795,0xbb0b4703,
0x220216b9,0x5505262f,0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,0xc2d7ffa7,
0xb5d0cf31,0x2cd99e8b,0x5bdeae1d,0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a,
0x9c0906a9,0xeb0e363f,0x72076785,0x05005713,0x95bf4a82,0xe2b87a14,0x7bb12bae,
0x0cb61b38,0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21,0x86d3d2d4,0xf1d4e242,
0x68ddb3f8,0x1fda836e,0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,0x88085ae6,
0xff0f6a70,0x66063bca,0x11010b5c,0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45,
0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,0xa7672661,0xd06016f7,0x4969474d,
0x3e6e77db,0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,0xa9bcae53,0xdebb9ec5,
0x47b2cf7f,0x30b5ffe9,0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,0xbad03605,
0xcdd70693,0x54de5729,0x23d967bf,0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94,
0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d
];
uint init_crc32()
{
return cast(uint)-1;
}
uint update_crc32(ubyte val, uint crc)
{
return crc32_table[cast(ubyte) crc ^ val] ^ (crc >> 8);
}
uint update_crc32(char val, uint crc)
{
return update_crc32(cast(ubyte) val, crc);
}
uint strcrc32(char[] s)
{
uint crc = init_crc32();
for (size_t i = 0; i < s.length; i++)
crc = update_crc32(s[i], crc);
return crc;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
module gcc.gc_guess_stack;
void * stackOriginGuess;

View File

@@ -1,187 +0,0 @@
// Copyright (C) 2001-2002 by Digital Mars
// All Rights Reserved
// www.digitalmars.com
// Written by Walter Bright
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, September 2004
*/
import std.c.string;
import std.c.stdlib;
import std.outofmemory;
import std.intrinsic;
//version = Asm86;
version (GNU) {
// bitop intrinsics not implemented yet
} else {
version = bitops;
}
struct GCBits
{
const int BITS_PER_WORD = 32;
const int BITS_SHIFT = 5;
const int BITS_MASK = 31;
uint *data = null;
uint nwords = 0; // allocated words in data[] excluding sentinals
uint nbits = 0; // number of bits in data[] excluding sentinals
void Dtor()
{
if (data)
{
free(data);
data = null;
}
}
invariant
{
if (data)
{
assert(nwords * data[0].sizeof * 8 >= nbits);
}
}
void alloc(uint nbits)
{
this.nbits = nbits;
nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
data = cast(uint *)calloc(nwords + 2, uint.sizeof);
if (!data)
_d_OutOfMemory();
}
uint test(uint i)
in
{
assert(i < nbits);
}
body
{
//return (cast(bit *)(data + 1))[i];
return data[1 + (i >> BITS_SHIFT)] & (1 << (i & BITS_MASK));
}
void set(uint i)
in
{
assert(i < nbits);
}
body
{
//(cast(bit *)(data + 1))[i] = 1;
data[1 + (i >> BITS_SHIFT)] |= (1 << (i & BITS_MASK));
}
void clear(uint i)
in
{
assert(i < nbits);
}
body
{
//(cast(bit *)(data + 1))[i] = 0;
data[1 + (i >> BITS_SHIFT)] &= ~(1 << (i & BITS_MASK));
}
uint testClear(uint i)
{
version (bitops)
{
return std.intrinsic.btr(data + 1, i);
}
else version (Asm86)
{
asm
{
naked ;
mov EAX,data[EAX] ;
mov ECX,i-4[ESP] ;
btr 4[EAX],ECX ;
sbb EAX,EAX ;
ret 4 ;
}
}
else
{ uint result;
//result = (cast(bit *)(data + 1))[i];
//(cast(bit *)(data + 1))[i] = 0;
uint *p = &data[1 + (i >> BITS_SHIFT)];
uint mask = (1 << (i & BITS_MASK));
result = *p & mask;
*p &= ~mask;
return result;
}
}
void zero()
{
memset(data + 1, 0, nwords * uint.sizeof);
}
void copy(GCBits *f)
in
{
assert(nwords == f.nwords);
}
body
{
memcpy(data + 1, f.data + 1, nwords * uint.sizeof);
}
uint *base()
in
{
assert(data);
}
body
{
return data + 1;
}
}
unittest
{
GCBits b;
b.alloc(786);
assert(b.test(123) == 0);
assert(b.testClear(123) == 0);
b.set(123);
assert(b.test(123) != 0);
assert(b.testClear(123) != 0);
assert(b.test(123) == 0);
b.set(785);
b.set(0);
assert(b.test(785) != 0);
assert(b.test(0) != 0);
b.zero();
assert(b.test(785) == 0);
assert(b.test(0) == 0);
GCBits b2;
b2.alloc(786);
b2.set(38);
b.copy(&b2);
assert(b.test(38) != 0);
b2.Dtor();
b.Dtor();
}
/+
void main()
{
}
+/

View File

@@ -1,107 +0,0 @@
// Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com
// All Rights Reserved
// Written by Walter Bright
import std.c.linux.linuxextern;
import std.c.linux.linux;
/+
extern (C)
{
// from <sys/mman.h>
void* mmap(void* addr, uint len, int prot, int flags, int fd, uint offset);
int munmap(void* addr, uint len);
const void* MAP_FAILED = cast(void*)-1;
// from <bits/mman.h>
enum { PROT_NONE = 0, PROT_READ = 1, PROT_WRITE = 2, PROT_EXEC = 4 }
enum { MAP_SHARED = 1, MAP_PRIVATE = 2, MAP_TYPE = 0x0F,
MAP_FIXED = 0x10, MAP_FILE = 0, MAP_ANON = 0x20 }
}
+/
/***********************************
* Map memory.
*/
void *os_mem_map(uint nbytes)
{ void *p;
//errno = 0;
p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
return (p == MAP_FAILED) ? null : p;
}
/***********************************
* Commit memory.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_commit(void *base, uint offset, uint nbytes)
{
return 0;
}
/***********************************
* Decommit memory.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_decommit(void *base, uint offset, uint nbytes)
{
return 0;
}
/***********************************
* Unmap memory allocated with os_mem_map().
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_unmap(void *base, uint nbytes)
{
return munmap(base, nbytes);
}
/**********************************************
* Determine "bottom" of stack (actually the top on x86 systems).
*/
void *os_query_stackBottom()
{
version (none)
{ // See discussion: http://autopackage.org/forums/viewtopic.php?t=22
static void** libc_stack_end;
if (libc_stack_end == libc_stack_end.init)
{
void* handle = dlopen(null, RTLD_NOW);
libc_stack_end = cast(void **)dlsym(handle, "__libc_stack_end");
dlclose(handle);
}
return *libc_stack_end;
}
else
{ // This doesn't resolve on all versions of Linux
return __libc_stack_end;
}
}
/**********************************************
* Determine base address and size of static data segment.
*/
void os_query_staticdataseg(void **base, uint *nbytes)
{
*base = cast(void *)&__data_start;
*nbytes = cast(byte *)&_end - cast(byte *)&__data_start;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,168 +0,0 @@
// Copyright (C) 2001-2002 by Digital Mars
// All Rights Reserved
// www.digitalmars.com
// Written by Walter Bright
import std.c.windows.windows;
alias int pthread_t;
/***********************************
* Map memory.
*/
void *os_mem_map(uint nbytes)
{
return VirtualAlloc(null, nbytes, MEM_RESERVE, PAGE_READWRITE);
}
/***********************************
* Commit memory.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_commit(void *base, uint offset, uint nbytes)
{
void *p;
p = VirtualAlloc(base + offset, nbytes, MEM_COMMIT, PAGE_READWRITE);
return cast(int)(p == null);
}
/***********************************
* Decommit memory.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_decommit(void *base, uint offset, uint nbytes)
{
return cast(int)VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0;
}
/***********************************
* Unmap memory allocated with os_mem_map().
* Memory must have already been decommitted.
* Returns:
* 0 success
* !=0 failure
*/
int os_mem_unmap(void *base, uint nbytes)
{
return cast(int)VirtualFree(base, 0, MEM_RELEASE) == 0;
}
/********************************************
*/
pthread_t pthread_self()
{
//printf("pthread_self() = %x\n", GetCurrentThreadId());
return cast(pthread_t) GetCurrentThreadId();
}
/**********************************************
* Determine "bottom" of stack (actually the top on Win32 systems).
*/
void *os_query_stackBottom()
{
asm
{
naked ;
mov EAX,FS:4 ;
ret ;
}
}
/**********************************************
* Determine base address and size of static data segment.
*/
version (GNU)
{
// This is MinGW specific
extern (C)
{
// TODO: skip the .rdata between .data and .bss?
extern int _data_start__;
extern int _bss_end__;
}
void os_query_staticdataseg(void **base, uint *nbytes)
{
*base = cast(void *)&_data_start__;
*nbytes = cast(uint)(cast(char *)&_bss_end__ - cast(char *)&_data_start__);
}
}
else
{
extern (C)
{
extern int _xi_a; // &_xi_a just happens to be start of data segment
extern int _edata; // &_edata is start of BSS segment
extern int _end; // &_end is past end of BSS
}
void os_query_staticdataseg(void **base, uint *nbytes)
{
*base = cast(void *)&_xi_a;
*nbytes = cast(uint)(cast(char *)&_end - cast(char *)&_xi_a);
}
}
/++++
void os_query_staticdataseg(void **base, uint *nbytes)
{
static char dummy = 6;
SYSTEM_INFO si;
MEMORY_BASIC_INFORMATION mbi;
char *p;
void *bottom = null;
uint size = 0;
// Tests show the following does not work reliably.
// The reason is that the data segment is arbitrarily divided
// up into PAGE_READWRITE and PAGE_WRITECOPY.
// This means there are multiple regions to query, and
// can even wind up including the code segment.
assert(0); // fix implementation
GetSystemInfo(&si);
p = (char *)((uint)(&dummy) & ~(si.dwPageSize - 1));
while (VirtualQuery(p, &mbi, sizeof(mbi)) == sizeof(mbi) &&
mbi.Protect & (PAGE_READWRITE | PAGE_WRITECOPY) &&
!(mbi.Protect & PAGE_GUARD) &&
mbi.AllocationBase != 0)
{
bottom = (void *)mbi.BaseAddress;
size = (uint)mbi.RegionSize;
printf("dwPageSize = x%x\n", si.dwPageSize);
printf("&dummy = %p\n", &dummy);
printf("BaseAddress = %p\n", mbi.BaseAddress);
printf("AllocationBase = %p\n", mbi.AllocationBase);
printf("AllocationProtect = x%x\n", mbi.AllocationProtect);
printf("RegionSize = x%x\n", mbi.RegionSize);
printf("State = x%x\n", mbi.State);
printf("Protect = x%x\n", mbi.Protect);
printf("Type = x%x\n\n", mbi.Type);
p -= si.dwPageSize;
}
*base = bottom;
*nbytes = size;
}
++++/

View File

@@ -1,15 +0,0 @@
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
struct GCStats
{
size_t poolsize; // total size of pool
size_t usedsize; // bytes allocated
size_t freeblocks; // number of blocks marked FREE
size_t freelistsize; // total of memory on free lists
size_t pageblocks; // number of blocks marked PAGE
}

View File

@@ -1,5 +0,0 @@
module hello;
import std.stdio;
void main() { writefln("Hello World"); }

View File

@@ -1,410 +0,0 @@
/**
* Part of the D programming language runtime library.
*/
/*
* Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, in both source and binary form, subject to the following
* restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
/* This code handles decoding UTF strings for foreach loops.
* There are 6 combinations of conversions between char, wchar,
* and dchar, and 2 of each of those.
*/
import std.utf;
//debug=apply;
/**********************************************
*/
// dg is D, but _aApplycd() is C
extern (D) typedef int delegate(void *) dg_t;
extern (C) int _aApplycd1(char[] aa, dg_t dg)
{ int result;
size_t i;
size_t len = aa.length;
debug(apply) printf("_aApplycd1(), len = %d\n", len);
for (i = 0; i < len; )
{ dchar d;
d = aa[i];
if (d & 0x80)
d = std.utf.decode(aa, i);
else
i++;
result = dg(cast(void *)&d);
if (result)
break;
}
return result;
}
extern (C) int _aApplywd1(wchar[] aa, dg_t dg)
{ int result;
size_t i;
size_t len = aa.length;
debug(apply) printf("_aApplywd1(), len = %d\n", len);
for (i = 0; i < len; )
{ dchar d;
d = aa[i];
if (d & ~0x7F)
d = std.utf.decode(aa, i);
else
i++;
result = dg(cast(void *)&d);
if (result)
break;
}
return result;
}
extern (C) int _aApplycw1(char[] aa, dg_t dg)
{ int result;
size_t i;
size_t len = aa.length;
debug(apply) printf("_aApplycw1(), len = %d\n", len);
for (i = 0; i < len; )
{ dchar d;
wchar w;
w = aa[i];
if (w & 0x80)
{ d = std.utf.decode(aa, i);
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(cast(void *)&w);
if (result)
break;
w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
}
}
else
i++;
result = dg(cast(void *)&w);
if (result)
break;
}
return result;
}
extern (C) int _aApplywc1(wchar[] aa, dg_t dg)
{ int result;
size_t i;
size_t len = aa.length;
debug(apply) printf("_aApplywc1(), len = %d\n", len);
for (i = 0; i < len; )
{ dchar d;
wchar w;
char c;
w = aa[i];
if (w & ~0x7F)
{
char[4] buf;
char[] b;
d = std.utf.decode(aa, i);
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(cast(void *)&c2);
if (result)
return result;
}
continue;
}
else
{ c = cast(char)w;
i++;
}
result = dg(cast(void *)&c);
if (result)
break;
}
return result;
}
extern (C) int _aApplydc1(dchar[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplydc1(), len = %d\n", aa.length);
foreach (dchar d; aa)
{
char c;
if (d & ~0x7F)
{
char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(cast(void *)&c2);
if (result)
return result;
}
continue;
}
else
{
c = cast(char)d;
}
result = dg(cast(void *)&c);
if (result)
break;
}
return result;
}
extern (C) int _aApplydw1(dchar[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplydw1(), len = %d\n", aa.length);
foreach (dchar d; aa)
{
wchar w;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(cast(void *)&w);
if (result)
break;
w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
}
result = dg(cast(void *)&w);
if (result)
break;
}
return result;
}
/****************************************************************************/
// dg is D, but _aApplycd2() is C
extern (D) typedef int delegate(void *, void *) dg2_t;
extern (C) int _aApplycd2(char[] aa, dg2_t dg)
{ int result;
size_t i;
size_t n;
size_t len = aa.length;
debug(apply) printf("_aApplycd2(), len = %d\n", len);
for (i = 0; i < len; i += n)
{ dchar d;
d = aa[i];
if (d & 0x80)
{
n = i;
d = std.utf.decode(aa, n);
n -= i;
}
else
n = 1;
result = dg(&i, cast(void *)&d);
if (result)
break;
}
return result;
}
extern (C) int _aApplywd2(wchar[] aa, dg2_t dg)
{ int result;
size_t i;
size_t n;
size_t len = aa.length;
debug(apply) printf("_aApplywd2(), len = %d\n", len);
for (i = 0; i < len; i += n)
{ dchar d;
d = aa[i];
if (d & ~0x7F)
{
n = i;
d = std.utf.decode(aa, n);
n -= i;
}
else
n = 1;
result = dg(&i, cast(void *)&d);
if (result)
break;
}
return result;
}
extern (C) int _aApplycw2(char[] aa, dg2_t dg)
{ int result;
size_t i;
size_t n;
size_t len = aa.length;
debug(apply) printf("_aApplycw2(), len = %d\n", len);
for (i = 0; i < len; i += n)
{ dchar d;
wchar w;
w = aa[i];
if (w & 0x80)
{ n = i;
d = std.utf.decode(aa, n);
n -= i;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(&i, cast(void *)&w);
if (result)
break;
w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
}
}
else
n = 1;
result = dg(&i, cast(void *)&w);
if (result)
break;
}
return result;
}
extern (C) int _aApplywc2(wchar[] aa, dg2_t dg)
{ int result;
size_t i;
size_t n;
size_t len = aa.length;
debug(apply) printf("_aApplywc2(), len = %d\n", len);
for (i = 0; i < len; i += n)
{ dchar d;
wchar w;
char c;
w = aa[i];
if (w & ~0x7F)
{
char[4] buf;
char[] b;
n = i;
d = std.utf.decode(aa, n);
n -= i;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(&i, cast(void *)&c2);
if (result)
return result;
}
continue;
}
else
{ c = cast(char)w;
n = 1;
}
result = dg(&i, cast(void *)&c);
if (result)
break;
}
return result;
}
extern (C) int _aApplydc2(dchar[] aa, dg2_t dg)
{ int result;
size_t i;
size_t len = aa.length;
debug(apply) printf("_aApplydc2(), len = %d\n", len);
for (i = 0; i < len; i++)
{ dchar d;
char c;
d = aa[i];
if (d & ~0x7F)
{
char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(&i, cast(void *)&c2);
if (result)
return result;
}
continue;
}
else
{ c = cast(char)d;
}
result = dg(&i, cast(void *)&c);
if (result)
break;
}
return result;
}
extern (C) int _aApplydw2(dchar[] aa, dg2_t dg)
{ int result;
debug(apply) printf("_aApplydw2(), len = %d\n", aa.length);
foreach (size_t i, dchar d; aa)
{
wchar w;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(&i, cast(void *)&w);
if (result)
break;
w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
}
result = dg(&i, cast(void *)&w);
if (result)
break;
}
return result;
}

View File

@@ -1,977 +0,0 @@
/**
* Part of the D programming language runtime library.
*/
/*
* Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, in both source and binary form, subject to the following
* restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
/* This code handles decoding UTF strings for foreach_reverse loops.
* There are 6 combinations of conversions between char, wchar,
* and dchar, and 2 of each of those.
*/
import std.utf;
//debug=apply;
/**********************************************/
/* 1 argument versions */
// dg is D, but _aApplyRcd() is C
extern (D) typedef int delegate(void *) dg_t;
extern (C) int _aApplyRcd1(char[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplyRcd1(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
i--;
d = aa[i];
if (d & 0x80)
{ char c = cast(char)d;
uint j;
uint m = 0x3F;
d = 0;
while ((c & 0xC0) != 0xC0)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-8 sequence", 0);
i--;
d |= (c & 0x3F) << j;
j += 6;
m >>= 1;
c = aa[i];
}
d |= (c & m) << j;
}
result = dg(cast(void *)&d);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRcd1.unittest\n");
char[] s = "hello";
int i;
foreach_reverse(dchar d; s)
{
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(dchar d; s)
{
//printf("i = %d, d = %x\n", i, d);
switch (i)
{
case 0: assert(d == 'b'); break;
case 1: assert(d == '\U00100456'); break;
case 2: assert(d == '\u1234'); break;
case 3: assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 4);
}
/*****************************/
extern (C) int _aApplyRwd1(wchar[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplyRwd1(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
i--;
d = aa[i];
if (d >= 0xDC00 && d <= 0xDFFF)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-16 sequence", 0);
i--;
d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
}
result = dg(cast(void *)&d);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRwd1.unittest\n");
wchar[] s = "hello";
int i;
foreach_reverse(dchar d; s)
{
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(dchar d; s)
{
//printf("i = %d, d = %x\n", i, d);
switch (i)
{
case 0: assert(d == 'b'); break;
case 1: assert(d == '\U00100456'); break;
case 2: assert(d == '\u1234'); break;
case 3: assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 4);
}
/*****************************/
extern (C) int _aApplyRcw1(char[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplyRcw1(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
wchar w;
i--;
w = aa[i];
if (w & 0x80)
{ char c = cast(char)w;
uint j;
uint m = 0x3F;
d = 0;
while ((c & 0xC0) != 0xC0)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-8 sequence", 0);
i--;
d |= (c & 0x3F) << j;
j += 6;
m >>= 1;
c = aa[i];
}
d |= (c & m) << j;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(cast(void *)&w);
if (result)
break;
w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
}
}
result = dg(cast(void *)&w);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRcw1.unittest\n");
char[] s = "hello";
int i;
foreach_reverse(wchar d; s)
{
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(wchar d; s)
{
//printf("i = %d, d = %x\n", i, d);
switch (i)
{
case 0: assert(d == 'b'); break;
case 1: assert(d == 0xDBC1); break;
case 2: assert(d == 0xDC56); break;
case 3: assert(d == 0x1234); break;
case 4: assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
}
/*****************************/
extern (C) int _aApplyRwc1(wchar[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplyRwc1(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
char c;
i--;
d = aa[i];
if (d >= 0xDC00 && d <= 0xDFFF)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-16 sequence", 0);
i--;
d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
}
if (d & ~0x7F)
{
char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(cast(void *)&c2);
if (result)
return result;
}
continue;
}
c = cast(char)d;
result = dg(cast(void *)&c);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRwc1.unittest\n");
wchar[] s = "hello";
int i;
foreach_reverse(char d; s)
{
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(char d; s)
{
//printf("i = %d, d = %x\n", i, d);
switch (i)
{
case 0: assert(d == 'b'); break;
case 1: assert(d == 0xF4); break;
case 2: assert(d == 0x80); break;
case 3: assert(d == 0x91); break;
case 4: assert(d == 0x96); break;
case 5: assert(d == 0xE1); break;
case 6: assert(d == 0x88); break;
case 7: assert(d == 0xB4); break;
case 8: assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 9);
}
/*****************************/
extern (C) int _aApplyRdc1(dchar[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplyRdc1(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0;)
{ dchar d = aa[--i];
char c;
if (d & ~0x7F)
{
char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(cast(void *)&c2);
if (result)
return result;
}
continue;
}
else
{
c = cast(char)d;
}
result = dg(cast(void *)&c);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRdc1.unittest\n");
dchar[] s = "hello";
int i;
foreach_reverse(char d; s)
{
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(char d; s)
{
//printf("i = %d, d = %x\n", i, d);
switch (i)
{
case 0: assert(d == 'b'); break;
case 1: assert(d == 0xF4); break;
case 2: assert(d == 0x80); break;
case 3: assert(d == 0x91); break;
case 4: assert(d == 0x96); break;
case 5: assert(d == 0xE1); break;
case 6: assert(d == 0x88); break;
case 7: assert(d == 0xB4); break;
case 8: assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 9);
}
/*****************************/
extern (C) int _aApplyRdw1(dchar[] aa, dg_t dg)
{ int result;
debug(apply) printf("_aApplyRdw1(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d = aa[--i];
wchar w;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(cast(void *)&w);
if (result)
break;
w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
}
result = dg(cast(void *)&w);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRdw1.unittest\n");
dchar[] s = "hello";
int i;
foreach_reverse(wchar d; s)
{
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(wchar d; s)
{
//printf("i = %d, d = %x\n", i, d);
switch (i)
{
case 0: assert(d == 'b'); break;
case 1: assert(d == 0xDBC1); break;
case 2: assert(d == 0xDC56); break;
case 3: assert(d == 0x1234); break;
case 4: assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
}
/****************************************************************************/
/* 2 argument versions */
// dg is D, but _aApplyRcd2() is C
extern (D) typedef int delegate(void *, void *) dg2_t;
extern (C) int _aApplyRcd2(char[] aa, dg2_t dg)
{ int result;
size_t i;
size_t len = aa.length;
debug(apply) printf("_aApplyRcd2(), len = %d\n", len);
for (i = len; i != 0; )
{ dchar d;
i--;
d = aa[i];
if (d & 0x80)
{ char c = cast(char)d;
uint j;
uint m = 0x3F;
d = 0;
while ((c & 0xC0) != 0xC0)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-8 sequence", 0);
i--;
d |= (c & 0x3F) << j;
j += 6;
m >>= 1;
c = aa[i];
}
d |= (c & m) << j;
}
result = dg(&i, cast(void *)&d);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRcd2.unittest\n");
char[] s = "hello";
int i;
foreach_reverse(k, dchar d; s)
{
assert(k == 4 - i);
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(k, dchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
switch (i)
{
case 0: assert(d == 'b'); assert(k == 8); break;
case 1: assert(d == '\U00100456'); assert(k == 4); break;
case 2: assert(d == '\u1234'); assert(k == 1); break;
case 3: assert(d == 'a'); assert(k == 0); break;
default: assert(0);
}
i++;
}
assert(i == 4);
}
/*****************************/
extern (C) int _aApplyRwd2(wchar[] aa, dg2_t dg)
{ int result;
debug(apply) printf("_aApplyRwd2(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
i--;
d = aa[i];
if (d >= 0xDC00 && d <= 0xDFFF)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-16 sequence", 0);
i--;
d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
}
result = dg(&i, cast(void *)&d);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRwd2.unittest\n");
wchar[] s = "hello";
int i;
foreach_reverse(k, dchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
assert(k == 4 - i);
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(k, dchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
switch (i)
{
case 0: assert(k == 4); assert(d == 'b'); break;
case 1: assert(k == 2); assert(d == '\U00100456'); break;
case 2: assert(k == 1); assert(d == '\u1234'); break;
case 3: assert(k == 0); assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 4);
}
/*****************************/
extern (C) int _aApplyRcw2(char[] aa, dg2_t dg)
{ int result;
debug(apply) printf("_aApplyRcw2(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
wchar w;
i--;
w = aa[i];
if (w & 0x80)
{ char c = cast(char)w;
uint j;
uint m = 0x3F;
d = 0;
while ((c & 0xC0) != 0xC0)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-8 sequence", 0);
i--;
d |= (c & 0x3F) << j;
j += 6;
m >>= 1;
c = aa[i];
}
d |= (c & m) << j;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(&i, cast(void *)&w);
if (result)
break;
w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
}
}
result = dg(&i, cast(void *)&w);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRcw2.unittest\n");
char[] s = "hello";
int i;
foreach_reverse(k, wchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
assert(k == 4 - i);
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(k, wchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
switch (i)
{
case 0: assert(k == 8); assert(d == 'b'); break;
case 1: assert(k == 4); assert(d == 0xDBC1); break;
case 2: assert(k == 4); assert(d == 0xDC56); break;
case 3: assert(k == 1); assert(d == 0x1234); break;
case 4: assert(k == 0); assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
}
/*****************************/
extern (C) int _aApplyRwc2(wchar[] aa, dg2_t dg)
{ int result;
debug(apply) printf("_aApplyRwc2(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d;
char c;
i--;
d = aa[i];
if (d >= 0xDC00 && d <= 0xDFFF)
{ if (i == 0)
throw new std.utf.UtfException("Invalid UTF-16 sequence", 0);
i--;
d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
}
if (d & ~0x7F)
{
char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(&i, cast(void *)&c2);
if (result)
return result;
}
continue;
}
c = cast(char)d;
result = dg(&i, cast(void *)&c);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRwc2.unittest\n");
wchar[] s = "hello";
int i;
foreach_reverse(k, char d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
assert(k == 4 - i);
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(k, char d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
switch (i)
{
case 0: assert(k == 4); assert(d == 'b'); break;
case 1: assert(k == 2); assert(d == 0xF4); break;
case 2: assert(k == 2); assert(d == 0x80); break;
case 3: assert(k == 2); assert(d == 0x91); break;
case 4: assert(k == 2); assert(d == 0x96); break;
case 5: assert(k == 1); assert(d == 0xE1); break;
case 6: assert(k == 1); assert(d == 0x88); break;
case 7: assert(k == 1); assert(d == 0xB4); break;
case 8: assert(k == 0); assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 9);
}
/*****************************/
extern (C) int _aApplyRdc2(dchar[] aa, dg2_t dg)
{ int result;
debug(apply) printf("_aApplyRdc2(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d = aa[--i];
char c;
if (d & ~0x7F)
{
char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, d);
foreach (char c2; b)
{
result = dg(&i, cast(void *)&c2);
if (result)
return result;
}
continue;
}
else
{ c = cast(char)d;
}
result = dg(&i, cast(void *)&c);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRdc2.unittest\n");
dchar[] s = "hello";
int i;
foreach_reverse(k, char d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
assert(k == 4 - i);
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(k, char d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
switch (i)
{
case 0: assert(k == 3); assert(d == 'b'); break;
case 1: assert(k == 2); assert(d == 0xF4); break;
case 2: assert(k == 2); assert(d == 0x80); break;
case 3: assert(k == 2); assert(d == 0x91); break;
case 4: assert(k == 2); assert(d == 0x96); break;
case 5: assert(k == 1); assert(d == 0xE1); break;
case 6: assert(k == 1); assert(d == 0x88); break;
case 7: assert(k == 1); assert(d == 0xB4); break;
case 8: assert(k == 0); assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 9);
}
/*****************************/
extern (C) int _aApplyRdw2(dchar[] aa, dg2_t dg)
{ int result;
debug(apply) printf("_aApplyRdw2(), len = %d\n", aa.length);
for (size_t i = aa.length; i != 0; )
{ dchar d = aa[--i];
wchar w;
if (d <= 0xFFFF)
w = cast(wchar) d;
else
{
w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
result = dg(&i, cast(void *)&w);
if (result)
break;
w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
}
result = dg(&i, cast(void *)&w);
if (result)
break;
}
return result;
}
unittest
{
debug(apply) printf("_aApplyRdw2.unittest\n");
dchar[] s = "hello";
int i;
foreach_reverse(k, wchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
assert(k == 4 - i);
switch (i)
{
case 0: assert(d == 'o'); break;
case 1: assert(d == 'l'); break;
case 2: assert(d == 'l'); break;
case 3: assert(d == 'e'); break;
case 4: assert(d == 'h'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
s = "a\u1234\U00100456b";
i = 0;
foreach_reverse(k, wchar d; s)
{
//printf("i = %d, k = %d, d = %x\n", i, k, d);
switch (i)
{
case 0: assert(k == 3); assert(d == 'b'); break;
case 1: assert(k == 2); assert(d == 0xDBC1); break;
case 2: assert(k == 2); assert(d == 0xDC56); break;
case 3: assert(k == 1); assert(d == 0x1234); break;
case 4: assert(k == 0); assert(d == 'a'); break;
default: assert(0);
}
i++;
}
assert(i == 5);
}

View File

@@ -1,825 +0,0 @@
//_ aaA.d
/**
* Part of the D programming language runtime library.
* Implementation of associative arrays.
*/
/*
* Copyright (C) 2000-2007 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
/*
* Modified for LDC by Tomas Lindquist Olsen.
* The DMD implementation wont quite work due to the differences in how
* structs are handled.
*/
//import std.stdio;
import std.c.stdarg;
import std.c.stdio;
import std.c.stdlib;
import std.c.string;
//import std.string;
import std.outofmemory;
// Auto-rehash and pre-allocate - Dave Fladebo
static size_t[] prime_list = [
97UL, 389UL,
1543UL, 6151UL,
24593UL, 98317UL,
393241UL, 1572869UL,
6291469UL, 25165843UL,
100663319UL, 402653189UL,
1610612741UL, 4294967291UL
];
/* This is the type of the return value for dynamic arrays.
* It should be a type that is returned in registers.
*/
alias Array ArrayRet_t;
pragma(no_typeinfo)
struct Array
{
size_t length;
void* ptr;
}
pragma(no_typeinfo)
struct aaA
{
aaA *left;
aaA *right;
hash_t hash;
/* key */
/* value */
}
pragma(no_typeinfo)
struct BB
{
aaA*[] b;
size_t nodes; // total number of aaA nodes
}
/* This is the type actually seen by the programmer, although
* it is completely opaque.
*/
alias BB* AA;
/**********************************
* Align to next pointer boundary, so that
* GC won't be faced with misaligned pointers
* in value.
*/
size_t aligntsize(size_t tsize)
{
// Is pointer alignment on the x86-64 4 bytes or 8?
//return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
return (tsize + 3) & (~3);
}
extern (C):
/*************************************************
* Invariant for aa.
*/
/+
void _aaInvAh(aaA*[] aa)
{
for (size_t i = 0; i < aa.length; i++)
{
if (aa[i])
_aaInvAh_x(aa[i]);
}
}
private int _aaCmpAh_x(aaA *e1, aaA *e2)
{ int c;
c = e1.hash - e2.hash;
if (c == 0)
{
c = e1.key.length - e2.key.length;
if (c == 0)
c = memcmp((char *)e1.key, (char *)e2.key, e1.key.length);
}
return c;
}
private void _aaInvAh_x(aaA *e)
{
hash_t key_hash;
aaA *e1;
aaA *e2;
key_hash = getHash(e.key);
assert(key_hash == e.hash);
while (1)
{ int c;
e1 = e.left;
if (e1)
{
_aaInvAh_x(e1); // ordinary recursion
do
{
c = _aaCmpAh_x(e1, e);
assert(c < 0);
e1 = e1.right;
} while (e1 != null);
}
e2 = e.right;
if (e2)
{
do
{
c = _aaCmpAh_x(e, e2);
assert(c < 0);
e2 = e2.left;
} while (e2 != null);
e = e.right; // tail recursion
}
else
break;
}
}
+/
/****************************************************
* Determine number of entries in associative array.
*/
size_t _aaLen(AA aa)
in
{
//printf("_aaLen()+\n");
//_aaInv(aa);
}
out (result)
{
size_t len = 0;
void _aaLen_x(aaA* ex)
{
auto e = ex;
len++;
while (1)
{
if (e.right)
_aaLen_x(e.right);
e = e.left;
if (!e)
break;
len++;
}
}
if (aa)
{
foreach (e; aa.b)
{
if (e)
_aaLen_x(e);
}
}
assert(len == result);
//printf("_aaLen()-\n");
}
body
{
return aa ? aa.nodes : 0;
}
/*************************************************
* Get pointer to value in associative array indexed by key.
* Add entry for key if it is not already there.
*/
void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey)
in
{
assert(aa);
}
out (result)
{
assert(result);
assert(*aa);
assert((*aa).b.length);
//assert(_aaInAh(*aa, key));
}
body
{
//auto pkey = cast(void *)(&valuesize + 1);
size_t i;
aaA* e;
auto keysize = aligntsize(keyti.tsize());
if (!*aa)
*aa = new BB();
if (!(*aa).b.length)
{
alias aaA *pa;
auto len = prime_list[0];
(*aa).b = new pa[len];
}
auto key_hash = keyti.getHash(pkey);
//printf("hash = %d\n", key_hash);
i = key_hash % (*aa).b.length;
auto pe = &(*aa).b[i];
while ((e = *pe) != null)
{
if (key_hash == e.hash)
{
auto c = keyti.compare(pkey, e + 1);
if (c == 0)
goto Lret;
pe = (c < 0) ? &e.left : &e.right;
}
else
pe = (key_hash < e.hash) ? &e.left : &e.right;
}
// Not found, create new elem
//printf("create new one\n");
e = cast(aaA *) cast(void*) new void[aaA.sizeof + keysize + valuesize];
memcpy(e + 1, pkey, keysize);
e.hash = key_hash;
*pe = e;
auto nodes = ++(*aa).nodes;
//printf("length = %d, nodes = %d\n", (*aa).length, nodes);
if (nodes > (*aa).b.length * 4)
{
_aaRehash(aa,keyti);
}
Lret:
return cast(void *)(e + 1) + keysize;
}
/*************************************************
* Get pointer to value in associative array indexed by key.
* Returns null if it is not already there.
*/
void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void* pkey)
{
//printf("_aaGetRvalue(valuesize = %u)\n", valuesize);
if (!aa)
return null;
//auto pkey = cast(void *)(&valuesize + 1);
auto keysize = aligntsize(keyti.tsize());
auto len = aa.b.length;
if (len)
{
auto key_hash = keyti.getHash(pkey);
//printf("hash = %d\n", key_hash);
size_t i = key_hash % len;
auto e = aa.b[i];
while (e != null)
{
if (key_hash == e.hash)
{
auto c = keyti.compare(pkey, e + 1);
if (c == 0)
return cast(void *)(e + 1) + keysize;
e = (c < 0) ? e.left : e.right;
}
else
e = (key_hash < e.hash) ? e.left : e.right;
}
}
return null; // not found, caller will throw exception
}
/*************************************************
* Determine if key is in aa.
* Returns:
* null not in aa
* !=null in aa, return pointer to value
*/
void* _aaIn(AA aa, TypeInfo keyti, void* pkey)
in
{
}
out (result)
{
//assert(result == 0 || result == 1);
}
body
{
if (aa)
{
//auto pkey = cast(void *)(&keyti + 1);
//printf("_aaIn(), .length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr);
auto len = aa.b.length;
if (len)
{
auto key_hash = keyti.getHash(pkey);
//printf("hash = %d\n", key_hash);
size_t i = key_hash % len;
auto e = aa.b[i];
while (e != null)
{
if (key_hash == e.hash)
{
auto c = keyti.compare(pkey, e + 1);
if (c == 0)
return cast(void *)(e + 1) + aligntsize(keyti.tsize());
e = (c < 0) ? e.left : e.right;
}
else
e = (key_hash < e.hash) ? e.left : e.right;
}
}
}
// Not found
return null;
}
/*************************************************
* Delete key entry in aa[].
* If key is not in aa[], do nothing.
*/
void _aaDel(AA aa, TypeInfo keyti, void* pkey)
{
//auto pkey = cast(void *)(&keyti + 1);
aaA* e;
if (aa && aa.b.length)
{
auto key_hash = keyti.getHash(pkey);
//printf("hash = %d\n", key_hash);
size_t i = key_hash % aa.b.length;
auto pe = &aa.b[i];
while ((e = *pe) != null) // null means not found
{
if (key_hash == e.hash)
{
auto c = keyti.compare(pkey, e + 1);
if (c == 0)
{
if (!e.left && !e.right)
{
*pe = null;
}
else if (e.left && !e.right)
{
*pe = e.left;
e.left = null;
}
else if (!e.left && e.right)
{
*pe = e.right;
e.right = null;
}
else
{
*pe = e.left;
e.left = null;
do
pe = &(*pe).right;
while (*pe);
*pe = e.right;
e.right = null;
}
aa.nodes--;
// Should notify GC that e can be free'd now
break;
}
pe = (c < 0) ? &e.left : &e.right;
}
else
pe = (key_hash < e.hash) ? &e.left : &e.right;
}
}
}
/********************************************
* Produce array of values from aa.
*/
ArrayRet_t _aaValues(AA aa, size_t keysize, size_t valuesize)
in
{
assert(keysize == aligntsize(keysize));
}
body
{
size_t resi;
Array a;
void _aaValues_x(aaA* e)
{
do
{
memcpy(a.ptr + resi * valuesize,
cast(byte*)e + aaA.sizeof + keysize,
valuesize);
resi++;
if (e.left)
{ if (!e.right)
{ e = e.left;
continue;
}
_aaValues_x(e.left);
}
e = e.right;
} while (e != null);
}
if (aa)
{
a.length = _aaLen(aa);
a.ptr = (new void[a.length * valuesize]).ptr;
resi = 0;
foreach (e; aa.b)
{
if (e)
_aaValues_x(e);
}
assert(resi == a.length);
}
return a;
}
/********************************************
* Rehash an array.
*/
void* _aaRehash(AA* paa, TypeInfo keyti)
in
{
assert(paa);
//_aaInvAh(paa);
}
out (result)
{
//_aaInvAh(result);
}
body
{
BB newb;
void _aaRehash_x(aaA* olde)
{
while (1)
{
auto left = olde.left;
auto right = olde.right;
olde.left = null;
olde.right = null;
aaA* e;
//printf("rehash %p\n", olde);
auto key_hash = olde.hash;
size_t i = key_hash % newb.b.length;
auto pe = &newb.b[i];
while ((e = *pe) != null)
{
//printf("\te = %p, e.left = %p, e.right = %p\n", e, e.left, e.right);
assert(e.left != e);
assert(e.right != e);
if (key_hash == e.hash)
{
auto c = keyti.compare(olde + 1, e + 1);
assert(c != 0);
pe = (c < 0) ? &e.left : &e.right;
}
else
pe = (key_hash < e.hash) ? &e.left : &e.right;
}
*pe = olde;
if (right)
{
if (!left)
{ olde = right;
continue;
}
_aaRehash_x(right);
}
if (!left)
break;
olde = left;
}
}
//printf("Rehash\n");
if (paa)
{
auto aa = *paa;
auto len = _aaLen(*paa);
if (len)
{ size_t i;
for (i = 0; i < prime_list.length - 1; i++)
{
if (len <= prime_list[i])
break;
}
len = prime_list[i];
newb.b = new aaA*[len];
foreach (e; aa.b)
{
if (e)
_aaRehash_x(e);
}
newb.nodes = aa.nodes;
}
**paa = newb;
}
return *paa;
}
/********************************************
* Produce array of N byte keys from aa.
*/
ArrayRet_t _aaKeys(AA aa, size_t keysize)
{
byte[] res;
size_t resi;
void _aaKeys_x(aaA* e)
{
do
{
memcpy(&res[resi * keysize], cast(byte*)(e + 1), keysize);
resi++;
if (e.left)
{ if (!e.right)
{ e = e.left;
continue;
}
_aaKeys_x(e.left);
}
e = e.right;
} while (e != null);
}
auto len = _aaLen(aa);
if (!len)
return ArrayRet_t.init;
res = cast(byte[])new void[len * keysize];
resi = 0;
foreach (e; aa.b)
{
if (e)
_aaKeys_x(e);
}
assert(resi == len);
return Array(len, res.ptr);
}
/**********************************************
* 'apply' for associative arrays - to support foreach
*/
// dg is D, but _aaApply() is C
extern (D) typedef int delegate(void *) dg_t;
int _aaApply(AA aa, size_t keysize, dg_t dg)
in
{
assert(aligntsize(keysize) == keysize);
}
body
{ int result;
//printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
int treewalker(aaA* e)
{ int result;
do
{
//printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
result = dg(cast(void *)(e + 1) + keysize);
if (result)
break;
if (e.right)
{ if (!e.left)
{
e = e.right;
continue;
}
result = treewalker(e.right);
if (result)
break;
}
e = e.left;
} while (e);
return result;
}
if (aa)
{
foreach (e; aa.b)
{
if (e)
{
result = treewalker(e);
if (result)
break;
}
}
}
return result;
}
// dg is D, but _aaApply2() is C
extern (D) typedef int delegate(void *, void *) dg2_t;
int _aaApply2(AA aa, size_t keysize, dg2_t dg)
in
{
assert(aligntsize(keysize) == keysize);
}
body
{ int result;
//printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
int treewalker(aaA* e)
{ int result;
do
{
//printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
result = dg(cast(void *)(e + 1), cast(void *)(e + 1) + keysize);
if (result)
break;
if (e.right)
{ if (!e.left)
{
e = e.right;
continue;
}
result = treewalker(e.right);
if (result)
break;
}
e = e.left;
} while (e);
return result;
}
if (aa)
{
foreach (e; aa.b)
{
if (e)
{
result = treewalker(e);
if (result)
break;
}
}
}
return result;
}
/***********************************
* Construct an associative array of type ti from
* length pairs of key/value pairs.
*/
version(none) // not used, C variadics can't be implemented in LLVM on x86-64
{
BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
{
auto valuesize = ti.next.tsize(); // value size
auto keyti = ti.key;
auto keysize = keyti.tsize(); // key size
BB* result;
//printf("_d_assocarrayliteralT(keysize = %d, valuesize = %d, length = %d)\n", keysize, valuesize, length);
//writefln("tivalue = %s", ti.next.classinfo.name);
if (length == 0 || valuesize == 0 || keysize == 0)
{
;
}
else
{
va_list q;
va_start!(size_t)(q, length);
result = new BB();
size_t i;
for (i = 0; i < prime_list.length - 1; i++)
{
if (length <= prime_list[i])
break;
}
auto len = prime_list[i];
result.b = new aaA*[len];
size_t keystacksize = (keysize + int.sizeof - 1) & ~(int.sizeof - 1);
size_t valuestacksize = (valuesize + int.sizeof - 1) & ~(int.sizeof - 1);
size_t keytsize = aligntsize(keysize);
for (size_t j = 0; j < length; j++)
{ void* pkey = q;
q += keystacksize;
void* pvalue = q;
q += valuestacksize;
aaA* e;
auto key_hash = keyti.getHash(pkey);
//printf("hash = %d\n", key_hash);
i = key_hash % len;
auto pe = &result.b[i];
while (1)
{
e = *pe;
if (!e)
{
// Not found, create new elem
//printf("create new one\n");
e = cast(aaA *) cast(void*) new void[aaA.sizeof + keytsize + valuesize];
memcpy(e + 1, pkey, keysize);
e.hash = key_hash;
*pe = e;
result.nodes++;
break;
}
if (key_hash == e.hash)
{
auto c = keyti.compare(pkey, e + 1);
if (c == 0)
break;
pe = (c < 0) ? &e.left : &e.right;
}
else
pe = (key_hash < e.hash) ? &e.left : &e.right;
}
memcpy(cast(void *)(e + 1) + keytsize, pvalue, valuesize);
}
va_end(q);
}
return result;
}
}

View File

@@ -1,838 +0,0 @@
//_ adi.d
/**
* Part of the D programming language runtime library.
* Dynamic array property support routines
*/
/*
* Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, in both source and binary form, subject to the following
* restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
//debug=adi; // uncomment to turn on debugging printf's
//import std.stdio;
import std.c.stdio;
import std.c.stdlib;
import std.c.string;
//import std.string;
import std.outofmemory;
import std.utf;
pragma(no_typeinfo)
struct Array
{
size_t length;
void* ptr;
}
/**********************************************
* Reverse array of chars.
* Handled separately because embedded multibyte encodings should not be
* reversed.
*/
extern (C) char[] _adReverseChar(char[] a)
{
if (a.length > 1)
{
char[6] tmp;
char[6] tmplo;
char* lo = a.ptr;
char* hi = &a[length - 1];
while (lo < hi)
{ auto clo = *lo;
auto chi = *hi;
//printf("lo = %d, hi = %d\n", lo, hi);
if (clo <= 0x7F && chi <= 0x7F)
{
//printf("\tascii\n");
*lo = chi;
*hi = clo;
lo++;
hi--;
continue;
}
uint stridelo = std.utf.UTF8stride[clo];
uint stridehi = 1;
while ((chi & 0xC0) == 0x80)
{
chi = *--hi;
stridehi++;
assert(hi >= lo);
}
if (lo == hi)
break;
//printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi);
if (stridelo == stridehi)
{
memcpy(tmp.ptr, lo, stridelo);
memcpy(lo, hi, stridelo);
memcpy(hi, tmp.ptr, stridelo);
lo += stridelo;
hi--;
continue;
}
/* Shift the whole array. This is woefully inefficient
*/
memcpy(tmp.ptr, hi, stridehi);
memcpy(tmplo.ptr, lo, stridelo);
memmove(lo + stridehi, lo + stridelo , (hi - lo) - stridelo);
memcpy(lo, tmp.ptr, stridehi);
memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo);
lo += stridehi;
hi = hi - 1 + (stridehi - stridelo);
}
}
return a;
}
unittest
{
string a = "abcd";
string r;
r = a.dup.reverse;
//writefln(r);
assert(r == "dcba");
a = "a\u1235\u1234c";
//writefln(a);
r = a.dup.reverse;
//writefln(r);
assert(r == "c\u1234\u1235a");
a = "ab\u1234c";
//writefln(a);
r = a.dup.reverse;
//writefln(r);
assert(r == "c\u1234ba");
a = "\u3026\u2021\u3061\n";
r = a.dup.reverse;
assert(r == "\n\u3061\u2021\u3026");
}
/**********************************************
* Reverse array of wchars.
* Handled separately because embedded multiword encodings should not be
* reversed.
*/
extern (C) wchar[] _adReverseWchar(wchar[] a)
{
if (a.length > 1)
{
wchar[2] tmp;
wchar* lo = a.ptr;
wchar* hi = &a[length - 1];
while (lo < hi)
{ auto clo = *lo;
auto chi = *hi;
if ((clo < 0xD800 || clo > 0xDFFF) &&
(chi < 0xD800 || chi > 0xDFFF))
{
*lo = chi;
*hi = clo;
lo++;
hi--;
continue;
}
int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF);
int stridehi = 1;
if (chi >= 0xDC00 && chi <= 0xDFFF)
{
chi = *--hi;
stridehi++;
assert(hi >= lo);
}
if (lo == hi)
break;
if (stridelo == stridehi)
{ int stmp;
assert(stridelo == 2);
assert(stmp.sizeof == 2 * (*lo).sizeof);
stmp = *cast(int*)lo;
*cast(int*)lo = *cast(int*)hi;
*cast(int*)hi = stmp;
lo += stridelo;
hi--;
continue;
}
/* Shift the whole array. This is woefully inefficient
*/
memcpy(tmp.ptr, hi, stridehi * wchar.sizeof);
memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof);
memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof);
memcpy(lo, tmp.ptr, stridehi * wchar.sizeof);
lo += stridehi;
hi = hi - 1 + (stridehi - stridelo);
}
}
return a;
}
unittest
{
wstring a = "abcd";
wstring r;
r = a.dup.reverse;
assert(r == "dcba");
a = "a\U00012356\U00012346c";
r = a.dup.reverse;
assert(r == "c\U00012346\U00012356a");
a = "ab\U00012345c";
r = a.dup.reverse;
assert(r == "c\U00012345ba");
}
/**********************************************
* Support for array.reverse property.
*/
extern (C) Array _adReverse(Array a, size_t szelem)
{
if (a.length >= 2)
{
byte* tmp;
byte[16] buffer;
void* lo = a.ptr;
void* hi = a.ptr + (a.length - 1) * szelem;
tmp = buffer.ptr;
if (szelem > 16)
{
//version (Win32)
//tmp = cast(byte*) alloca(szelem);
//else
tmp = (new byte[szelem]).ptr;
}
for (; lo < hi; lo += szelem, hi -= szelem)
{
memcpy(tmp, lo, szelem);
memcpy(lo, hi, szelem);
memcpy(hi, tmp, szelem);
}
version (Win32)
{
}
else
{
//if (szelem > 16)
// BUG: bad code is generate for delete pointer, tries
// to call delclass.
//delete tmp;
}
}
return a;
}
unittest
{
debug(adi) printf("array.reverse.unittest\n");
int[] a = new int[5];
int[] b;
size_t i;
for (i = 0; i < 5; i++)
a[i] = i;
b = a.reverse;
assert(b is a);
for (i = 0; i < 5; i++)
assert(a[i] == 4 - i);
struct X20
{ // More than 16 bytes in size
int a;
int b, c, d, e;
}
X20[] c = new X20[5];
X20[] d;
for (i = 0; i < 5; i++)
{ c[i].a = i;
c[i].e = 10;
}
d = c.reverse;
assert(d is c);
for (i = 0; i < 5; i++)
{
assert(c[i].a == 4 - i);
assert(c[i].e == 10);
}
}
/**********************************************
* Support for array.reverse property for bit[].
*/
version (none)
{
extern (C) bit[] _adReverseBit(bit[] a)
out (result)
{
assert(result is a);
}
body
{
if (a.length >= 2)
{
bit t;
int lo, hi;
lo = 0;
hi = a.length - 1;
for (; lo < hi; lo++, hi--)
{
t = a[lo];
a[lo] = a[hi];
a[hi] = t;
}
}
return a;
}
unittest
{
debug(adi) printf("array.reverse_Bit[].unittest\n");
bit[] b;
b = new bit[5];
static bit[5] data = [1,0,1,1,0];
int i;
b[] = data[];
b.reverse;
for (i = 0; i < 5; i++)
{
assert(b[i] == data[4 - i]);
}
}
}
/**********************************************
* Sort array of chars.
*/
extern (C) char[] _adSortChar(char[] a)
{
if (a.length > 1)
{
dstring da = toUTF32(a);
da.sort;
size_t i = 0;
foreach (dchar d; da)
{ char[4] buf;
string t = toUTF8(buf, d);
a[i .. i + t.length] = t[];
i += t.length;
}
delete da;
}
return a;
}
/**********************************************
* Sort array of wchars.
*/
extern (C) wchar[] _adSortWchar(wchar[] a)
{
if (a.length > 1)
{
dstring da = toUTF32(a);
da.sort;
size_t i = 0;
foreach (dchar d; da)
{ wchar[2] buf;
wstring t = toUTF16(buf, d);
a[i .. i + t.length] = t[];
i += t.length;
}
delete da;
}
return a;
}
/**********************************************
* Support for array.sort property for bit[].
*/
version (none)
{
extern (C) bit[] _adSortBit(bit[] a)
out (result)
{
assert(result is a);
}
body
{
if (a.length >= 2)
{
size_t lo, hi;
lo = 0;
hi = a.length - 1;
while (1)
{
while (1)
{
if (lo >= hi)
goto Ldone;
if (a[lo] == true)
break;
lo++;
}
while (1)
{
if (lo >= hi)
goto Ldone;
if (a[hi] == false)
break;
hi--;
}
a[lo] = false;
a[hi] = true;
lo++;
hi--;
}
Ldone:
;
}
return a;
}
unittest
{
debug(adi) printf("array.sort_Bit[].unittest\n");
}
}
/***************************************
* Support for array equality test.
*/
extern (C) int _adEq(Array a1, Array a2, TypeInfo ti)
{
// printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
if (a1.length != a2.length)
return 0; // not equal
auto sz = ti.next.tsize();
auto p1 = a1.ptr;
auto p2 = a2.ptr;
/+
for (int i = 0; i < a1.length; i++)
{
printf("%4x %4x\n", (cast(short*)p1)[i], (cast(short*)p2)[i]);
}
printf("sz = %u\n", sz);
+/
if (sz == 1)
// We should really have a ti.isPOD() check for this
return (memcmp(p1, p2, a1.length) == 0);
for (size_t i = 0; i < a1.length; i++)
{
if (!ti.next.equals(p1 + i * sz, p2 + i * sz))
return 0; // not equal
}
return 1; // equal
}
unittest
{
debug(adi) printf("array.Eq unittest\n");
string a = "hello";
assert(a != "hel");
assert(a != "helloo");
assert(a != "betty");
assert(a == "hello");
assert(a != "hxxxx");
}
/***************************************
* Support for bit array equality test for bit arrays.
*/
version (none)
{
extern (C) int _adEqBit(Array a1, Array a2)
{ size_t i;
if (a1.length != a2.length)
return 0; // not equal
auto p1 = cast(byte*)a1.ptr;
auto p2 = cast(byte*)a2.ptr;
auto n = a1.length / 8;
for (i = 0; i < n; i++)
{
if (p1[i] != p2[i])
return 0; // not equal
}
ubyte mask;
n = a1.length & 7;
mask = cast(ubyte)((1 << n) - 1);
//printf("i = %d, n = %d, mask = %x, %x, %x\n", i, n, mask, p1[i], p2[i]);
return (mask == 0) || (p1[i] & mask) == (p2[i] & mask);
}
unittest
{
debug(adi) printf("array.EqBit unittest\n");
static bit[] a = [1,0,1,0,1];
static bit[] b = [1,0,1];
static bit[] c = [1,0,1,0,1,0,1];
static bit[] d = [1,0,1,1,1];
static bit[] e = [1,0,1,0,1];
assert(a != b);
assert(a != c);
assert(a != d);
assert(a == e);
}
}
/***************************************
* Support for array compare test.
*/
extern (C) int _adCmp(Array a1, Array a2, TypeInfo ti)
{
//printf("adCmp()\n");
auto len = a1.length;
if (a2.length < len)
len = a2.length;
auto sz = ti.tsize();
void *p1 = a1.ptr;
void *p2 = a2.ptr;
if (sz == 1)
{ // We should really have a ti.isPOD() check for this
auto c = memcmp(p1, p2, len);
if (c)
return c;
}
else
{
for (size_t i = 0; i < len; i++)
{
auto c = ti.compare(p1 + i * sz, p2 + i * sz);
if (c)
return c;
}
}
if (a1.length == a2.length)
return 0;
return (a1.length > a2.length) ? 1 : -1;
}
unittest
{
debug(adi) printf("array.Cmp unittest\n");
string a = "hello";
assert(a > "hel");
assert(a >= "hel");
assert(a < "helloo");
assert(a <= "helloo");
assert(a > "betty");
assert(a >= "betty");
assert(a == "hello");
assert(a <= "hello");
assert(a >= "hello");
}
/***************************************
* Support for char array compare test.
*/
extern (C) int _adCmpChar(Array a1, Array a2)
{
version (D_InlineAsm_X86)
{
asm
{ naked ;
push EDI ;
push ESI ;
mov ESI,a1+4[4+ESP] ;
mov EDI,a2+4[4+ESP] ;
mov ECX,a1[4+ESP] ;
mov EDX,a2[4+ESP] ;
cmp ECX,EDX ;
jb GotLength ;
mov ECX,EDX ;
GotLength:
cmp ECX,4 ;
jb DoBytes ;
// Do alignment if neither is dword aligned
test ESI,3 ;
jz Aligned ;
test EDI,3 ;
jz Aligned ;
DoAlign:
mov AL,[ESI] ; //align ESI to dword bounds
mov DL,[EDI] ;
cmp AL,DL ;
jnz Unequal ;
inc ESI ;
inc EDI ;
test ESI,3 ;
lea ECX,[ECX-1] ;
jnz DoAlign ;
Aligned:
mov EAX,ECX ;
// do multiple of 4 bytes at a time
shr ECX,2 ;
jz TryOdd ;
repe ;
cmpsd ;
jnz UnequalQuad ;
TryOdd:
mov ECX,EAX ;
DoBytes:
// if still equal and not end of string, do up to 3 bytes slightly
// slower.
and ECX,3 ;
jz Equal ;
repe ;
cmpsb ;
jnz Unequal ;
Equal:
mov EAX,a1[4+ESP] ;
mov EDX,a2[4+ESP] ;
sub EAX,EDX ;
pop ESI ;
pop EDI ;
ret ;
UnequalQuad:
mov EDX,[EDI-4] ;
mov EAX,[ESI-4] ;
cmp AL,DL ;
jnz Unequal ;
cmp AH,DH ;
jnz Unequal ;
shr EAX,16 ;
shr EDX,16 ;
cmp AL,DL ;
jnz Unequal ;
cmp AH,DH ;
Unequal:
sbb EAX,EAX ;
pop ESI ;
or EAX,1 ;
pop EDI ;
ret ;
}
}
else
{
int len;
int c;
//printf("adCmpChar()\n");
len = a1.length;
if (a2.length < len)
len = a2.length;
c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len);
if (!c)
c = cast(int)a1.length - cast(int)a2.length;
return c;
}
}
unittest
{
debug(adi) printf("array.CmpChar unittest\n");
string a = "hello";
assert(a > "hel");
assert(a >= "hel");
assert(a < "helloo");
assert(a <= "helloo");
assert(a > "betty");
assert(a >= "betty");
assert(a == "hello");
assert(a <= "hello");
assert(a >= "hello");
}
/***************************************
* Support for bit array compare test.
*/
version (none)
{
extern (C) int _adCmpBit(Array a1, Array a2)
{
int len;
uint i;
len = a1.length;
if (a2.length < len)
len = a2.length;
ubyte *p1 = cast(ubyte*)a1.ptr;
ubyte *p2 = cast(ubyte*)a2.ptr;
uint n = len / 8;
for (i = 0; i < n; i++)
{
if (p1[i] != p2[i])
break; // not equal
}
for (uint j = i * 8; j < len; j++)
{ ubyte mask = cast(ubyte)(1 << j);
int c;
c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask);
if (c)
return c;
}
return cast(int)a1.length - cast(int)a2.length;
}
unittest
{
debug(adi) printf("array.CmpBit unittest\n");
static bit[] a = [1,0,1,0,1];
static bit[] b = [1,0,1];
static bit[] c = [1,0,1,0,1,0,1];
static bit[] d = [1,0,1,1,1];
static bit[] e = [1,0,1,0,1];
assert(a > b);
assert(a >= b);
assert(a < c);
assert(a <= c);
assert(a < d);
assert(a <= d);
assert(a == e);
assert(a <= e);
assert(a >= e);
}
}
/**********************************
* Support for array.dup property.
*/
extern(C)
void* _d_realloc(void*, size_t);
extern(C)
Array _adDupT(TypeInfo ti, Array a)
{
Array r;
if (a.length)
{
auto sizeelem = ti.next.tsize(); // array element size
auto size = a.length * sizeelem;
r.ptr = _d_realloc(null,size);
r.length = a.length;
memcpy(r.ptr, a.ptr, size);
}
return r;
}
unittest
{
int[] a;
int[] b;
int i;
debug(adi) printf("array.dup.unittest\n");
a = new int[3];
a[0] = 1; a[1] = 2; a[2] = 3;
b = a.dup;
assert(b.length == 3);
for (i = 0; i < 3; i++)
assert(b[i] == i + 1);
}

View File

@@ -1,111 +0,0 @@
module internal.arrays;
private import llvm.intrinsic;
extern(C):
int memcmp(void*,void*,size_t);
size_t strlen(char*);
version(LLVM64)
alias llvm_memcpy_i64 llvm_memcpy;
else
alias llvm_memcpy_i32 llvm_memcpy;
// per-element array init routines
void _d_array_init_i1(bool* a, size_t n, bool v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_i8(ubyte* a, size_t n, ubyte v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_i16(ushort* a, size_t n, ushort v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_i32(uint* a, size_t n, uint v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_i64(ulong* a, size_t n, ulong v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_float(float* a, size_t n, float v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_double(double* a, size_t n, double v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_pointer(void** a, size_t n, void* v)
{
auto p = a;
auto end = a+n;
while (p !is end)
*p++ = v;
}
void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
{
auto p = a;
auto end = a + na*nv;
while (p !is end) {
llvm_memcpy(p,v,nv,0);
p += nv;
}
}
// for array cast
size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
{
if (newelemsz == 1) {
return len*elemsz;
}
else if (len % newelemsz) {
throw new Exception("Bad array cast");
}
return (len*elemsz)/newelemsz;
}
// creating args for main
void _d_main_args(uint n, char** args, ref char[][] res)
{
assert(res.length == n);
foreach(i,v; args[0..n])
{
res[i] = v[0 .. strlen(v)];
}
}

View File

@@ -1,182 +0,0 @@
/*
* Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, in both source and binary form, subject to the following
* restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
import object;
import std.c.stdio;
extern (C):
/******************************************
* Given a pointer:
* If it is an Object, return that Object.
* If it is an interface, return the Object implementing the interface.
* If it is null, return null.
* Else, undefined crash
*/
Object _d_toObject(void* p)
{ Object o;
if (p)
{
o = cast(Object)p;
//ClassInfo oc = o.classinfo;
Interface *pi = **cast(Interface ***)p;
/* Interface.offset lines up with ClassInfo.name.ptr,
* so we rely on pointers never being less than 64K,
* and Objects never being greater.
*/
if (pi.offset < 0x10000)
{
//printf("\tpi.offset = %d\n", pi.offset);
o = cast(Object)(p - pi.offset);
}
}
return o;
}
/*************************************
* Attempts to cast Object o to class c.
* Returns o if successful, null if not.
*/
Object _d_interface_cast(void* p, ClassInfo c)
{ Object o;
//printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name);
if (p)
{
Interface *pi = **cast(Interface ***)p;
//printf("\tpi.offset = %d\n", pi.offset);
o = cast(Object)(p - pi.offset);
return _d_dynamic_cast(o, c);
}
return o;
}
Object _d_dynamic_cast(Object o, ClassInfo c)
{ ClassInfo oc;
uint offset = 0;
//printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
if (o)
{
oc = o.classinfo;
if (_d_isbaseof2(oc, c, offset))
{
//printf("\toffset = %d\n", offset);
o = cast(Object)(cast(void*)o + offset);
}
else
o = null;
}
//printf("\tresult = %p\n", o);
return o;
}
int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout uint offset)
{ int i;
if (oc is c)
return 1;
do
{
if (oc.base is c)
return 1;
for (i = 0; i < oc.interfaces.length; i++)
{
ClassInfo ic;
ic = oc.interfaces[i].classinfo;
if (ic is c)
{ offset = oc.interfaces[i].offset;
return 1;
}
}
for (i = 0; i < oc.interfaces.length; i++)
{
ClassInfo ic;
ic = oc.interfaces[i].classinfo;
if (_d_isbaseof2(ic, c, offset))
{ offset = oc.interfaces[i].offset;
return 1;
}
}
oc = oc.base;
} while (oc);
return 0;
}
int _d_isbaseof(ClassInfo oc, ClassInfo c)
{ int i;
if (oc is c)
return 1;
do
{
if (oc.base is c)
return 1;
for (i = 0; i < oc.interfaces.length; i++)
{
ClassInfo ic;
ic = oc.interfaces[i].classinfo;
if (ic is c || _d_isbaseof(ic, c))
return 1;
}
oc = oc.base;
} while (oc);
return 0;
}
/*********************************
* Find the vtbl[] associated with Interface ic.
*/
void *_d_interface_vtbl(ClassInfo ic, Object o)
{ int i;
ClassInfo oc;
//printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
assert(o);
oc = o.classinfo;
for (i = 0; i < oc.interfaces.length; i++)
{
ClassInfo oic;
oic = oc.interfaces[i].classinfo;
if (oic is ic)
{
return cast(void *)oc.interfaces[i].vtbl;
}
}
assert(0);
}

View File

@@ -1,21 +0,0 @@
module internal.contract;
import std.string: toString;
extern(C):
void exit(int);
/*void _d_assert(bool cond, uint line, char[] msg)
{
if (!cond) {
printf("Aborted(%u): %.*s\n", line, msg.length, msg.ptr);
exit(1);
}
}*/
void _d_assert(string file, uint line) {
throw new Exception(file~":"~.toString(line)~": Assertion failed!");
}
void _d_assert_msg(string msg, string file, uint line) {
throw new Exception(file~": "~.toString(line)~": Assertion failed: \""~msg~"\"");
}

View File

@@ -1,49 +0,0 @@
module internal.critical;
extern(C):
import std.c.linux.linux, std.c.stdlib:ccalloc=calloc, cmalloc=malloc, cfree=free;
struct CritSec {
pthread_mutex_t* p;
}
const PTHREAD_MUTEX_RECURSIVE = 1, PTHREAD_MUTEX_ERRORCHECK=2;
extern(C) int pthread_self();
void _d_criticalenter(CritSec* cs) {
if (!cs.p) {
auto newp = cast(pthread_mutex_t*) cmalloc(pthread_mutex_t.sizeof);
auto cspp = &cs.p;
pthread_mutexattr_t mt; pthread_mutexattr_init(&mt);
pthread_mutexattr_settype(&mt, PTHREAD_MUTEX_RECURSIVE);
printf("Create -> %i\n", pthread_mutex_init(newp, &mt));
asm { xor EAX, EAX; mov ECX, newp; mov EDX, cspp; lock; cmpxchg int ptr [EDX], ECX; }
if (cs.p != newp) pthread_mutex_destroy(newp);
}
auto count = (cast(uint*) cs.p)[1];
// printf("%i ::%u\n", pthread_self(), count);
//printf("%i: Lock %p -> %i\n", pthread_self(), cs.p,
pthread_mutex_lock(cs.p);//);
}
void _d_criticalexit(CritSec* cs) {
//printf("%i: Unlock %p -> %i\n", pthread_self(), cs.p,
pthread_mutex_unlock(cs.p);//);
}
void _d_monitorenter(Object h)
{
_d_criticalenter(cast(CritSec*) &h.__monitor);
}
void _d_monitorexit(Object h)
{
_d_criticalexit(cast(CritSec*) &h.__monitor);
}
void _STI_monitor_staticctor() { }
void _STI_critical_init() { }
void _STI_critical_term() { }
void _STD_monitor_staticdtor() { }
void _STD_critical_term() { }

View File

@@ -1,122 +0,0 @@
/*
* Placed into the Public Domain.
* written by Walter Bright
* www.digitalmars.com
*/
module internal.dmain2;
import object;
import std.c.stdio;
import std.c.string;
import std.c.stdlib;
import std.string;
extern (C) void _STI_monitor_staticctor();
extern (C) void _STD_monitor_staticdtor();
extern (C) void _STI_critical_init();
extern (C) void _STD_critical_term();
extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleDtor();
extern (C) void _moduleUnitTests();
extern (C) bool no_catch_exceptions;
/***********************************
* The D main() function supplied by the user's program
*/
int main(char[][] args);
/***********************************
* Substitutes for the C main() function.
* It's purpose is to wrap the call to the D main()
* function and catch any unhandled exceptions.
*/
extern (C) int main(size_t argc, char **argv)
{
char[] *am;
char[][] args;
int result;
int myesp;
int myebx;
version (linux)
{
_STI_monitor_staticctor();
_STI_critical_init();
gc_init();
am = cast(char[] *) malloc(argc * (char[]).sizeof);
// BUG: alloca() conflicts with try-catch-finally stack unwinding
//am = (char[] *) alloca(argc * (char[]).sizeof);
}
version (Win32)
{
gc_init();
_minit();
am = cast(char[] *) alloca(argc * (char[]).sizeof);
}
if (no_catch_exceptions)
{
_moduleCtor();
_moduleUnitTests();
for (size_t i = 0; i < argc; i++)
{
auto len = strlen(argv[i]);
am[i] = argv[i][0 .. len];
}
args = am[0 .. argc];
result = main(args);
_moduleDtor();
gc_term();
}
else
{
try
{
_moduleCtor();
_moduleUnitTests();
for (size_t i = 0; i < argc; i++)
{
auto len = strlen(argv[i]);
am[i] = argv[i][0 .. len];
}
args = am[0 .. argc];
result = main(args);
_moduleDtor();
gc_term();
}
catch (Object o)
{
version (none)
{
printf("Error: ");
o.print();
}
else
{
auto foo = o.toString();
fprintf(stderr, "Error: %.*s\n", foo.length, foo.ptr);
}
exit(EXIT_FAILURE);
}
}
version (linux)
{
free(am);
_STD_critical_term();
_STD_monitor_staticdtor();
}
return result;
}

View File

@@ -1,376 +0,0 @@
/**
* This module contains functions and structures required for
* exception handling.
*/
module eh;
// debug = EH_personality;
// debug = EH_personality_verbose;
// current EH implementation works on x86 linux only
version(X86) version(linux) version=X86_LINUX;
private extern(C) void abort();
private extern(C) int printf(char*, ...);
// D runtime functions
extern(C) {
int _d_isbaseof(ClassInfo oc, ClassInfo c);
}
// libunwind headers
extern(C)
{
enum _Unwind_Reason_Code
{
NO_REASON = 0,
FOREIGN_EXCEPTION_CAUGHT = 1,
FATAL_PHASE2_ERROR = 2,
FATAL_PHASE1_ERROR = 3,
NORMAL_STOP = 4,
END_OF_STACK = 5,
HANDLER_FOUND = 6,
INSTALL_CONTEXT = 7,
CONTINUE_UNWIND = 8
}
enum _Unwind_Action
{
SEARCH_PHASE = 1,
CLEANUP_PHASE = 2,
HANDLER_PHASE = 3,
FORCE_UNWIND = 4
}
alias void* _Unwind_Context_Ptr;
alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn;
struct _Unwind_Exception
{
char[8] exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
int private_1;
int private_2;
}
version(X86_LINUX)
{
void _Unwind_Resume(_Unwind_Exception*);
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*);
ulong _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context);
ulong _Unwind_GetIP(_Unwind_Context_Ptr context);
ulong _Unwind_SetIP(_Unwind_Context_Ptr context, ulong new_value);
ulong _Unwind_SetGR(_Unwind_Context_Ptr context, int index, ulong new_value);
ulong _Unwind_GetRegionStart(_Unwind_Context_Ptr context);
}
else
{
// runtime calls these directly
void _Unwind_Resume(_Unwind_Exception*)
{
printf("_Unwind_Resume is not implemented on this platform.\n");
}
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*)
{
printf("_Unwind_RaiseException is not implemented on this platform.\n");
return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
}
}
}
// helpers for reading certain DWARF data
//TODO: It may not be a good idea to use exceptions for error handling within exception handling code
private ubyte* get_uleb128(ubyte* addr, ref size_t res)
{
res = 0;
size_t bitsize = 0;
// read as long as high bit is set
while(*addr & 0x80) {
res |= (*addr & 0x7f) << bitsize;
bitsize += 7;
addr += 1;
if(bitsize >= size_t.sizeof*8)
throw new Exception("tried to read uleb128 that exceeded size of size_t");
}
// read last
if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
throw new Exception("tried to read uleb128 that exceeded size of size_t");
res |= (*addr) << bitsize;
return addr + 1;
}
private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res)
{
res = 0;
size_t bitsize = 0;
// read as long as high bit is set
while(*addr & 0x80) {
res |= (*addr & 0x7f) << bitsize;
bitsize += 7;
addr += 1;
if(bitsize >= size_t.sizeof*8)
throw new Exception("tried to read sleb128 that exceeded size of size_t");
}
// read last
if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
throw new Exception("tried to read sleb128 that exceeded size of size_t");
res |= (*addr) << bitsize;
// take care of sign
if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40))
res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1);
return addr + 1;
}
// exception struct used by the runtime.
// _d_throw allocates a new instance and passes the address of its
// _Unwind_Exception member to the unwind call. The personality
// routine is then able to get the whole struct by looking at the data
// surrounding the unwind info.
struct _d_exception
{
Object exception_object;
_Unwind_Exception unwind_info;
}
// the 8-byte string identifying the type of exception
// the first 4 are for vendor, the second 4 for language
//TODO: This may be the wrong way around
char[8] _d_exception_class = "LLDCD1\0\0";
//
// x86 Linux specific implementation of personality function
// and helpers
//
version(X86_LINUX)
{
// the personality routine gets called by the unwind handler and is responsible for
// reading the EH tables and deciding what to do
extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context)
{
printf("eh_personality is running\n");
// check ver: the C++ Itanium ABI only allows ver == 1
if(ver != 1) {
printf("Fatal Phase1 #1\n");
return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
}
// check exceptionClass
//TODO: Treat foreign exceptions with more respect
if((cast(char*)&exception_class)[0..8] != _d_exception_class) {
printf("Fatal Phase1 #2: %s != %s\n", cast(char*)&exception_class, cast(char*) _d_exception_class);
return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
}
// find call site table, action table and classinfo table
// Note: callsite and action tables do not contain static-length
// data and will be parsed as needed
// Note: classinfo_table points past the end of the table
ubyte* callsite_table;
ubyte* action_table;
ClassInfo* classinfo_table;
_d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table);
/*
find landing pad and action table index belonging to ip by walking
the callsite_table
*/
ubyte* callsite_walker = callsite_table;
// get the instruction pointer
// will be used to find the right entry in the callsite_table
// -1 because it will point past the last instruction
ulong ip = _Unwind_GetIP(context) - 1;
// address block_start is relative to
ulong region_start = _Unwind_GetRegionStart(context);
// table entries
uint block_start_offset, block_size;
ulong landing_pad;
size_t action_offset;
while(true) {
// if we've gone through the list and found nothing...
if(callsite_walker >= action_table) {
printf("Continue unwind #3\n");
return _Unwind_Reason_Code.CONTINUE_UNWIND;
}
block_start_offset = *cast(uint*)callsite_walker;
block_size = *(cast(uint*)callsite_walker + 1);
landing_pad = *(cast(uint*)callsite_walker + 2);
if(landing_pad)
landing_pad += region_start;
callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset);
/*debug(EH_personality_verbose) */printf("%d %d %d\n", block_start_offset, block_size, landing_pad);
// since the list is sorted, as soon as we're past the ip
// there's no handler to be found
if(ip < region_start + block_start_offset) {
printf("Continue unwind #4\n");
return _Unwind_Reason_Code.CONTINUE_UNWIND;
}
// if we've found our block, exit
if(ip < region_start + block_start_offset + block_size)
break;
}
/*debug(EH_personality) */printf("Found correct landing pad and actionOffset %d\n", action_offset);
// now we need the exception's classinfo to find a handler
// the exception_info is actually a member of a larger _d_exception struct
// the runtime allocated. get that now
_d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof);
// if there's no action offset and no landing pad, continue unwinding
if(!action_offset && !landing_pad) {
printf("Continue unwind #5\n");
return _Unwind_Reason_Code.CONTINUE_UNWIND;
}
// if there's no action offset but a landing pad, this is a cleanup handler
else if(!action_offset && landing_pad) {
printf("Install cleanup handler #6\n");
return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
}
/*
walk action table chain, comparing classinfos using _d_isbaseof
*/
ubyte* action_walker = action_table + action_offset - 1;
ptrdiff_t ti_offset, next_action_offset;
while(true) {
action_walker = get_sleb128(action_walker, ti_offset);
// it is intentional that we not modify action_walker here
// next_action_offset is from current action_walker position
get_sleb128(action_walker, next_action_offset);
// negative are 'filters' which we don't use
assert(ti_offset >= 0 && "Filter actions are unsupported");
// zero means cleanup, which we require to be the last action
if(ti_offset == 0) {
assert(next_action_offset == 0 && "Cleanup action must be last in chain");
printf("Cleanup handler #7\n");
return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context);
}
// get classinfo for action and check if the one in the
// exception structure is a base
ClassInfo catch_ci = classinfo_table[-ti_offset];
/*debug(EH_personality) */printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr);
if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci)) {
printf("Install catch context #8\n");
return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context);
}
// we've walked through all actions and found nothing...
if(next_action_offset == 0) {
printf("Continue unwind #9\n");
return _Unwind_Reason_Code.CONTINUE_UNWIND;
} else
action_walker += next_action_offset;
}
/*printf("Assertion failure ;_;\n");
assert(false);*/
}
// These are the register numbers for SetGR that
// llvm's eh.exception and eh.selector intrinsics
// will pick up.
// Found by trial-and-error and probably platform dependent!
private int eh_exception_regno = 0;
private int eh_selector_regno = 2;
private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
{
debug(EH_personality) printf("Found catch clause!\n");
if(actions & _Unwind_Action.SEARCH_PHASE)
return _Unwind_Reason_Code.HANDLER_FOUND;
else if(actions & _Unwind_Action.HANDLER_PHASE)
{
debug(EH_personality) printf("Setting switch value to: %d!\n", switchval);
_Unwind_SetGR(context, eh_exception_regno, cast(ulong)cast(void*)(exception_struct.exception_object));
_Unwind_SetGR(context, eh_selector_regno, switchval);
_Unwind_SetIP(context, landing_pad);
return _Unwind_Reason_Code.INSTALL_CONTEXT;
}
assert(false);
}
private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ulong landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
{
// if we're merely in search phase, continue
if(actions & _Unwind_Action.SEARCH_PHASE)
return _Unwind_Reason_Code.CONTINUE_UNWIND;
debug(EH_personality) printf("Calling cleanup routine...\n");
_Unwind_SetGR(context, eh_exception_regno, cast(ulong)exception_struct);
_Unwind_SetGR(context, eh_selector_regno, 0);
_Unwind_SetIP(context, landing_pad);
return _Unwind_Reason_Code.INSTALL_CONTEXT;
}
private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci)
{
ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);
//TODO: Do proper DWARF reading here
assert(*data++ == 0xff);
assert(*data++ == 0x00);
size_t cioffset;
data = get_uleb128(data, cioffset);
ci = cast(ClassInfo*)(data + cioffset);
assert(*data++ == 0x03);
size_t callsitelength;
data = get_uleb128(data, callsitelength);
action = data + callsitelength;
callsite = data;
}
} // end of x86 Linux specific implementation
extern(C) void* malloc(size_t size);
extern(C) void _d_throw_exception(Object e)
{
if (e !is null)
{
// _d_exception* exc_struct = new _d_exception;
auto exc_struct = cast(_d_exception*)malloc(_d_exception.sizeof);
exc_struct.unwind_info.exception_class[] = _d_exception_class;
exc_struct.exception_object = e;
printf("Raising exception\n");
_Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info);
printf("_Unwind_RaiseException failed with reason code: %i\n", ret);
}
abort();
}
extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct)
{
_Unwind_Resume(&exception_struct.unwind_info);
}

View File

@@ -1,16 +0,0 @@
module internal.mem;
extern(C):
void* realloc(void*,size_t);
void free(void*);
void* _d_realloc(void* ptr, size_t n)
{
return realloc(ptr, n);
}
void _d_free(void* ptr)
{
free(ptr);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,69 +0,0 @@
/*
* Placed into Public Domain
* written by Walter Bright
* www.digitalmars.com
*
* This is a public domain version of qsort.d.
* All it does is call C's qsort(), but runs a little slower since
* it needs to synchronize a global variable.
*/
//debug=qsort;
import std.c.stdlib;
pragma(no_typeinfo)
struct Array
{
size_t length;
void *ptr;
}
private TypeInfo tiglobal;
extern (C) int cmp(void* p1, void* p2)
{
return tiglobal.compare(p1, p2);
}
extern (C) Array _adSort(Array a, TypeInfo ti)
{
synchronized
{
tiglobal = ti;
std.c.stdlib.qsort(a.ptr, a.length, cast(size_t)ti.tsize(), &cmp);
}
return a;
}
unittest
{
debug(qsort) printf("array.sort.unittest()\n");
int a[] = new int[10];
a[0] = 23;
a[1] = 1;
a[2] = 64;
a[3] = 5;
a[4] = 6;
a[5] = 5;
a[6] = 17;
a[7] = 3;
a[8] = 0;
a[9] = -1;
a.sort;
for (int i = 0; i < a.length - 1; i++)
{
//printf("i = %d", i);
//printf(" %d %d\n", a[i], a[i + 1]);
assert(a[i] <= a[i + 1]);
}
}

View File

@@ -1,428 +0,0 @@
/*
* Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, in both source and binary form, subject to the following
* restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
import std.c.stdio;
import std.c.string;
import std.string;
/******************************************************
* Support for switch statements switching on strings.
* Input:
* table[] sorted array of strings generated by compiler
* ca string to look up in table
* Output:
* result index of match in table[]
* -1 if not in table
*/
extern (C):
int _d_switch_string(char[][] table, char[] ca)
in
{
//printf("in _d_switch_string()\n");
assert(table.length >= 0);
assert(ca.length >= 0);
// Make sure table[] is sorted correctly
int j;
for (j = 1; j < table.length; j++)
{
int len1 = table[j - 1].length;
int len2 = table[j].length;
assert(len1 <= len2);
if (len1 == len2)
{
int ci;
ci = memcmp(table[j - 1].ptr, table[j].ptr, len1);
assert(ci < 0); // ci==0 means a duplicate
}
}
}
out (result)
{
int i;
int cj;
//printf("out _d_switch_string()\n");
if (result == -1)
{
// Not found
for (i = 0; i < table.length; i++)
{
if (table[i].length == ca.length)
{ cj = memcmp(table[i].ptr, ca.ptr, ca.length);
assert(cj != 0);
}
}
}
else
{
assert(0 <= result && result < table.length);
for (i = 0; 1; i++)
{
assert(i < table.length);
if (table[i].length == ca.length)
{
cj = memcmp(table[i].ptr, ca.ptr, ca.length);
if (cj == 0)
{
assert(i == result);
break;
}
}
}
}
}
body
{
//printf("body _d_switch_string(%.*s)\n", ca);
int low;
int high;
int mid;
int c;
char[] pca;
low = 0;
high = table.length;
version (none)
{
// Print table
printf("ca[] = '%s'\n", cast(char *)ca);
for (mid = 0; mid < high; mid++)
{
pca = table[mid];
printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
}
}
if (high &&
ca.length >= table[0].length &&
ca.length <= table[high - 1].length)
{
// Looking for 0 length string, which would only be at the beginning
if (ca.length == 0)
return 0;
char c1 = ca[0];
// Do binary search
while (low < high)
{
mid = (low + high) >> 1;
pca = table[mid];
c = ca.length - pca.length;
if (c == 0)
{
c = cast(ubyte)c1 - cast(ubyte)pca[0];
if (c == 0)
{
c = memcmp(ca.ptr, pca.ptr, ca.length);
if (c == 0)
{ //printf("found %d\n", mid);
return mid;
}
}
}
if (c < 0)
{
high = mid;
}
else
{
low = mid + 1;
}
}
}
//printf("not found\n");
return -1; // not found
}
unittest
{
switch (cast(char []) "c")
{
case "coo":
default:
break;
}
}
/**********************************
* Same thing, but for wide chars.
*/
int _d_switch_ustring(wchar[][] table, wchar[] ca)
in
{
//printf("in _d_switch_ustring()\n");
assert(table.length >= 0);
assert(ca.length >= 0);
// Make sure table[] is sorted correctly
int j;
for (j = 1; j < table.length; j++)
{
int len1 = table[j - 1].length;
int len2 = table[j].length;
assert(len1 <= len2);
if (len1 == len2)
{
int c;
c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof);
assert(c < 0); // c==0 means a duplicate
}
}
}
out (result)
{
int i;
int c;
//printf("out _d_switch_string()\n");
if (result == -1)
{
// Not found
for (i = 0; i < table.length; i++)
{
if (table[i].length == ca.length)
{ c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
assert(c != 0);
}
}
}
else
{
assert(0 <= result && result < table.length);
for (i = 0; 1; i++)
{
assert(i < table.length);
if (table[i].length == ca.length)
{
c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
if (c == 0)
{
assert(i == result);
break;
}
}
}
}
}
body
{
//printf("body _d_switch_ustring()\n");
int low;
int high;
int mid;
int c;
wchar[] pca;
low = 0;
high = table.length;
/*
// Print table
wprintf("ca[] = '%.*s'\n", ca);
for (mid = 0; mid < high; mid++)
{
pca = table[mid];
wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
}
*/
// Do binary search
while (low < high)
{
mid = (low + high) >> 1;
pca = table[mid];
c = ca.length - pca.length;
if (c == 0)
{
c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
if (c == 0)
{ //printf("found %d\n", mid);
return mid;
}
}
if (c < 0)
{
high = mid;
}
else
{
low = mid + 1;
}
}
//printf("not found\n");
return -1; // not found
}
unittest
{
switch (cast(wchar []) "c")
{
case "coo":
default:
break;
}
}
/**********************************
* Same thing, but for wide chars.
*/
int _d_switch_dstring(dchar[][] table, dchar[] ca)
in
{
//printf("in _d_switch_dstring()\n");
assert(table.length >= 0);
assert(ca.length >= 0);
// Make sure table[] is sorted correctly
int j;
for (j = 1; j < table.length; j++)
{
int len1 = table[j - 1].length;
int len2 = table[j].length;
assert(len1 <= len2);
if (len1 == len2)
{
int c;
c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof);
assert(c < 0); // c==0 means a duplicate
}
}
}
out (result)
{
int i;
int c;
//printf("out _d_switch_string()\n");
if (result == -1)
{
// Not found
for (i = 0; i < table.length; i++)
{
if (table[i].length == ca.length)
{ c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
assert(c != 0);
}
}
}
else
{
assert(0 <= result && result < table.length);
for (i = 0; 1; i++)
{
assert(i < table.length);
if (table[i].length == ca.length)
{
c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
if (c == 0)
{
assert(i == result);
break;
}
}
}
}
}
body
{
//printf("body _d_switch_ustring()\n");
int low;
int high;
int mid;
int c;
dchar[] pca;
low = 0;
high = table.length;
/*
// Print table
wprintf("ca[] = '%.*s'\n", ca);
for (mid = 0; mid < high; mid++)
{
pca = table[mid];
wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
}
*/
// Do binary search
while (low < high)
{
mid = (low + high) >> 1;
pca = table[mid];
c = ca.length - pca.length;
if (c == 0)
{
c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
if (c == 0)
{ //printf("found %d\n", mid);
return mid;
}
}
if (c < 0)
{
high = mid;
}
else
{
low = mid + 1;
}
}
//printf("not found\n");
return -1; // not found
}
unittest
{
switch (cast(dchar []) "c")
{
case "coo":
default:
break;
}
}
void _d_switch_error(string fn, int line)
{
throw new Exception(fn~toString(line)~": switch missing default");
}

View File

@@ -1,9 +0,0 @@
#!/bin/sh
export PATH=$PATH:/opt/llvm/bin
export FILE=$1; shift
export LDC_PATH=~/ldc
PARAM=$(for p_file in $($LDC_PATH/bin/ldc $FILE -I~/ldc/lphobos -c -v -of/dev/null |grep import \
|sed -e "s/import *//" -e "s/\t.*//" \
|sed -e "s/\./\//g" -e "s/$/\.d/"); do if [ -f $p_file ]; then echo $p_file; fi; done)
echo ldc $FILE $@ $PARAM
$LDC_PATH/bin/ldc $FILE $@ $PARAM

View File

@@ -1,5 +0,0 @@
[Environment]
DFLAGS=-I%@P%/../lphobos -I%@P%/../import -L-L%@P%/../lib
# -R%@P%/../lib

View File

@@ -1,140 +0,0 @@
module llvm.intrinsic;
// code generator intrinsics
/*
pragma(intrinsic, "llvm.returnaddress")
void* llvm_returnaddress(uint level);
*/
pragma(intrinsic, "llvm.frameaddress")
void* llvm_frameaddress(uint level);
/*
pragma(intrinsic, "llvm.stacksave")
void* llvm_stacksave();
pragma(intrinsic, "llvm.stackrestore")
void llvm_stackrestore(void* ptr);
pragma(intrinsic, "llvm.pcmarker")
void llvm_pcmarker(uint id);
pragma(intrinsic, "llvm.prefetch")
void llvm_prefetch(void* ptr, uint rw, uint locality);
*/
pragma(intrinsic, "llvm.readcyclecounter")
ulong readcyclecounter();
// standard C intrinsics
pragma(intrinsic, "llvm.memcpy.i32")
void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment);
pragma(intrinsic, "llvm.memcpy.i64")
void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment);
pragma(intrinsic, "llvm.memmove.i32")
void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment);
pragma(intrinsic, "llvm.memmove.i64")
void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment);
pragma(intrinsic, "llvm.memset.i32")
void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment);
pragma(intrinsic, "llvm.memset.i64")
void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment);
pragma(intrinsic, "llvm.sqrt.f32")
float llvm_sqrt(float val);
pragma(intrinsic, "llvm.sqrt.f64")
{
double llvm_sqrt(double val);
// real llvm_sqrt(real val);
}
pragma(intrinsic, "llvm.powi.f32")
float llvm_powi(float val, int power);
pragma(intrinsic, "llvm.powi.f64")
{
double llvm_powi(double val, int power);
// real llvm_powi(real val, int power);
}
// bit manipulation intrinsics
pragma(intrinsic, "llvm.bswap.i16.i16")
ushort llvm_bswap(ushort val);
pragma(intrinsic, "llvm.bswap.i32.i32")
uint llvm_bswap(uint val);
pragma(intrinsic, "llvm.bswap.i64.i64")
ulong llvm_bswap(ulong val);
/*
pragma(intrinsic, "llvm.ctpop.i8")
uint llvm_ctpop_i8(ubyte src);
pragma(intrinsic, "llvm.ctpop.i16")
uint llvm_ctpop_i16(ushort src);
pragma(intrinsic, "llvm.ctpop.i32")
uint llvm_ctpop_i32(uint src);
pragma(intrinsic, "llvm.ctpop.i64")
uint llvm_ctpop_i64(ulong src);
pragma(intrinsic, "llvm.ctlz.i8")
uint llvm_ctlz_i8(ubyte src);
pragma(intrinsic, "llvm.ctlz.i16")
uint llvm_ctlz_i16(ushort src);
pragma(intrinsic, "llvm.ctlz.i32")
uint llvm_ctlz_i32(uint src);
pragma(intrinsic, "llvm.ctlz.i64")
uint llvm_ctlz_i64(ulong src);
pragma(intrinsic, "llvm.cttz.i8")
uint llvm_cttz_i8(ubyte src);
pragma(intrinsic, "llvm.cttz.i16")
uint llvm_cttz_i16(ushort src);
pragma(intrinsic, "llvm.cttz.i32")
uint llvm_cttz_i32(uint src);
pragma(intrinsic, "llvm.cttz.i64")
uint llvm_cttz_i64(ulong src);
*/
// atomic operations and synchronization intrinsics
// TODO
/*
//declare i8 @llvm.atomic.lcs.i8.i8p.i8.i8( i8* <ptr>, i8 <cmp>, i8 <val> )
pragma(intrinsic, "llvm.atomic.lcs.i8.i8p.i8.i8")
ubyte llvm_atomic_lcs_i8(void* ptr, ubyte cmp, ubyte val);
declare i16 @llvm.atomic.lcs.i16.i16p.i16.i16( i16* <ptr>, i16 <cmp>, i16 <val> )
declare i32 @llvm.atomic.lcs.i32.i32p.i32.i32( i32* <ptr>, i32 <cmp>, i32 <val> )
declare i64 @llvm.atomic.lcs.i64.i64p.i64.i64( i64* <ptr>, i64 <cmp>, i64 <val> )
declare i8 @llvm.atomic.ls.i8.i8p.i8( i8* <ptr>, i8 <val> )
declare i16 @llvm.atomic.ls.i16.i16p.i16( i16* <ptr>, i16 <val> )
declare i32 @llvm.atomic.ls.i32.i32p.i32( i32* <ptr>, i32 <val> )
declare i64 @llvm.atomic.ls.i64.i64p.i64( i64* <ptr>, i64 <val> )
declare i8 @llvm.atomic.las.i8.i8p.i8( i8* <ptr>, i8 <delta> )
declare i16 @llvm.atomic.las.i16.i16p.i16( i16* <ptr>, i16 <delta> )
declare i32 @llvm.atomic.las.i32.i32p.i32( i32* <ptr>, i32 <delta> )
declare i64 @llvm.atomic.las.i64.i64p.i64( i64* <ptr>, i64 <delta> )
declare i8 @llvm.atomic.lss.i8.i8.i8( i8* <ptr>, i8 <delta> )
declare i16 @llvm.atomic.lss.i16.i16.i16( i16* <ptr>, i16 <delta> )
declare i32 @llvm.atomic.lss.i32.i32.i32( i32* <ptr>, i32 <delta> )
declare i64 @llvm.atomic.lss.i64.i64.i64( i64* <ptr>, i64 <delta> )
declare void @llvm.memory.barrier( i1 <ll>, i1 <ls>, i1 <sl>, i1 <ss> )
*/

View File

@@ -1,25 +0,0 @@
module llvm.va_list;
alias void* va_list;
/*
version(X86)
{
alias void* va_list;
}
else version(X86_64)
{
struct X86_64_va_list
{
uint gp_offset;
uint fp_offset;
void* overflow_arg_area;
void* reg_save_area;
}
alias X86_64_va_list va_list;
}
else
static assert("only x86 and x86-64 support va_list");
*/

View File

@@ -1,5 +0,0 @@
module llvmsupport;
import
llvm.intrinsic,
llvm.va_list;

View File

@@ -1,209 +0,0 @@
// Implementation is in internal\object.d
module object;
//alias bit bool;
alias bool bit;
alias typeof(int.sizeof) size_t;
alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
alias size_t hash_t;
alias char[] string;
alias wchar[] wstring;
alias dchar[] dstring;
extern (C)
{ int printf(char *, ...);
void trace_term();
}
class Object
{
void print();
char[] toString();
hash_t toHash();
int opCmp(Object o);
int opEquals(Object o);
final void notifyRegister(void delegate(Object) dg);
final void notifyUnRegister(void delegate(Object) dg);
static Object factory(char[] classname);
}
struct Interface
{
ClassInfo classinfo;
void *[] vtbl;
int offset; // offset to Interface 'this' from Object 'this'
}
class ClassInfo : Object
{
byte[] init; // class static initializer
char[] name; // class name
void *[] vtbl; // virtual function pointer table
Interface[] interfaces;
ClassInfo base;
void *destructor;
void (*classInvariant)(Object);
uint flags;
// 1: // IUnknown
// 2: // has no possible pointers into GC memory
// 4: // has offTi[] member
// 8: // has constructors
void *deallocator;
OffsetTypeInfo[] offTi;
void* defaultConstructor; // default Constructor
static ClassInfo find(char[] classname);
Object create();
}
struct OffsetTypeInfo
{
size_t offset;
TypeInfo ti;
}
class TypeInfo
{
hash_t getHash(void *p);
int equals(void *p1, void *p2);
int compare(void *p1, void *p2);
size_t tsize();
void swap(void *p1, void *p2);
TypeInfo next();
void[] init();
uint flags();
// 1: // has possible pointers into GC memory
OffsetTypeInfo[] offTi();
}
pragma(no_typeinfo)
class TypeInfo_Typedef : TypeInfo
{
TypeInfo base;
char[] name;
void[] m_init;
}
class TypeInfo_Enum : TypeInfo_Typedef
{
}
class TypeInfo_Pointer : TypeInfo
{
TypeInfo m_next;
}
class TypeInfo_Array : TypeInfo
{
TypeInfo value;
}
class TypeInfo_StaticArray : TypeInfo
{
TypeInfo value;
size_t len;
}
class TypeInfo_AssociativeArray : TypeInfo
{
TypeInfo value;
TypeInfo key;
}
class TypeInfo_Function : TypeInfo
{
TypeInfo next;
}
class TypeInfo_Delegate : TypeInfo
{
TypeInfo next;
}
class TypeInfo_Class : TypeInfo
{
ClassInfo info;
}
class TypeInfo_Interface : TypeInfo
{
ClassInfo info;
}
class TypeInfo_Struct : TypeInfo
{
char[] name;
void[] m_init;
uint function(void*) xtoHash;
int function(void*,void*) xopEquals;
int function(void*,void*) xopCmp;
char[] function(void*) xtoString;
uint m_flags;
}
class TypeInfo_Tuple : TypeInfo
{
TypeInfo[] elements;
}
class TypeInfo_Const : TypeInfo
{
TypeInfo next;
}
class TypeInfo_Invariant : TypeInfo_Const
{
}
class ModuleInfo
{
char[] name;
ModuleInfo[] importedModules;
ClassInfo[] localClasses;
uint flags; // initialization state
void function() ctor;
void function() dtor;
void function() unitTest;
void* xgetMembers;
void function() ictor;
// Return collection of all modules in the program.
static int opApply(int delegate(ref ModuleInfo));
}
struct ModuleReference {
ModuleReference* next;
ModuleInfo mod;
}
extern(C) extern ModuleReference* _Dmodule_ref;
// Recoverable errors
class Exception : Object
{
string msg;
this(string msg);
override void print();
override string toString();
}
// Non-recoverable errors
class Error : Exception
{
Error next;
this(string msg);
this(string msg, Error next);
}

View File

@@ -1,43 +0,0 @@
module phobos;
import
std.array,
std.base64,
std.ctype,
std.format,
std.intrinsic,
std.math,
std.moduleinit,
std.outofmemory,
std.stdarg,
std.stdint,
std.stdio,
std.string,
std.thread,
std.traits,
std.uni,
std.utf,
std.c.fenv,
std.c.locale,
std.c.math,
std.c.process,
std.c.stdarg,
std.c.stddef,
std.c.stdio,
std.c.stdlib,
std.c.string,
std.c.time,
std.file,
std.date,
std.socket,
std.zlib,
std.cstream;
version(linux) {
import
std.c.linux.linux,
std.c.linux.linuxextern,
std.c.linux.pthread,
std.c.linux.socket;
}

View File

@@ -1,38 +0,0 @@
module std.array;
private import std.c.stdio;
class ArrayBoundsError : Error
{
private:
uint linnum;
char[] filename;
public:
this(char[] filename, uint linnum)
{
this.linnum = linnum;
this.filename = filename;
char[] buffer = new char[19 + filename.length + linnum.sizeof * 3 + 1];
int len;
len = sprintf(buffer.ptr, "ArrayBoundsError %.*s(%u)", filename, linnum);
super(buffer[0..len]);
}
}
/********************************************
* Called by the compiler generated module assert function.
* Builds an ArrayBoundsError exception and throws it.
*/
extern (C) static void _d_array_bounds(char[] filename, uint line)
{
//printf("_d_assert(%s, %d)\n", (char *)filename, line);
ArrayBoundsError a = new ArrayBoundsError(filename, line);
//printf("assertion %p created\n", a);
throw a;
}

View File

@@ -1,293 +0,0 @@
/**
* Encodes/decodes MIME base64 data.
*
* Macros:
* WIKI=Phobos/StdBase64
* References:
* <a href="http://en.wikipedia.org/wiki/Base64">Wikipedia Base64</a>$(BR)
* <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>$(BR)
*/
/* base64.d
* Modified from C. Miller's version, his copyright is below.
*/
/*
Copyright (C) 2004 Christopher E. Miller
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
module std.base64;
/**
*/
class Base64Exception: Exception
{
this(char[] msg)
{
super(msg);
}
}
/**
*/
class Base64CharException: Base64Exception
{
this(char[] msg)
{
super(msg);
}
}
const char[] array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* Returns the number of bytes needed to encode a string of length slen.
*/
uint encodeLength(uint slen)
{
uint result;
result = slen / 3;
if(slen % 3)
result++;
return result * 4;
}
/**
* Encodes str[] and places the result in buf[].
* Params:
* str = string to encode
* buf = destination buffer, must be large enough for the result.
* Returns:
* slice into buf[] representing encoded result
*/
char[] encode(char[] str, char[] buf)
in
{
assert(buf.length >= encodeLength(str.length));
}
body
{
if(!str.length)
return buf[0 .. 0];
uint stri;
uint strmax = str.length / 3;
uint strleft = str.length % 3;
uint x;
char* sp, bp;
bp = &buf[0];
sp = &str[0];
for(stri = 0; stri != strmax; stri++)
{
x = (sp[0] << 16) | (sp[1] << 8) | (sp[2]);
sp+= 3;
*bp++ = array[(x & 0b11111100_00000000_00000000) >> 18];
*bp++ = array[(x & 0b00000011_11110000_00000000) >> 12];
*bp++ = array[(x & 0b00000000_00001111_11000000) >> 6];
*bp++ = array[(x & 0b00000000_00000000_00111111)];
}
switch(strleft)
{
case 2:
x = (sp[0] << 16) | (sp[1] << 8);
sp += 2;
*bp++ = array[(x & 0b11111100_00000000_00000000) >> 18];
*bp++ = array[(x & 0b00000011_11110000_00000000) >> 12];
*bp++ = array[(x & 0b00000000_00001111_11000000) >> 6];
*bp++ = '=';
break;
case 1:
x = *sp++ << 16;
*bp++ = array[(x & 0b11111100_00000000_00000000) >> 18];
*bp++ = array[(x & 0b00000011_11110000_00000000) >> 12];
*bp++ = '=';
*bp++ = '=';
break;
case 0:
break;
default:
assert(0);
}
return buf[0 .. (bp - &buf[0])];
}
/**
* Encodes str[] and returns the result.
*/
char[] encode(char[] str)
{
return encode(str, new char[encodeLength(str.length)]);
}
unittest
{
assert(encode("f") == "Zg==");
assert(encode("fo") == "Zm8=");
assert(encode("foo") == "Zm9v");
assert(encode("foos") == "Zm9vcw==");
assert(encode("all your base64 are belong to foo") == "YWxsIHlvdXIgYmFzZTY0IGFyZSBiZWxvbmcgdG8gZm9v");
}
/**
* Returns the number of bytes needed to decode an encoded string of this
* length.
*/
uint decodeLength(uint elen)
{
return elen / 4 * 3;
}
/**
* Decodes str[] and places the result in buf[].
* Params:
* str = string to encode
* buf = destination buffer, must be large enough for the result.
* Returns:
* slice into buf[] representing encoded result
* Errors:
* Throws Base64Exception on invalid base64 encoding in estr[].
* Throws Base64CharException on invalid base64 character in estr[].
*/
char[] decode(char[] estr, char[] buf)
in
{
assert(buf.length + 2 >= decodeLength(estr.length)); //account for '=' padding
}
body
{
void badc(char ch)
{
throw new Base64CharException("Invalid base64 character '" ~ (&ch)[0 .. 1] ~ "'");
}
uint arrayIndex(char ch)
out(result)
{
assert(ch == array[result]);
}
body
{
if(ch >= 'A' && ch <= 'Z')
return ch - 'A';
if(ch >= 'a' && ch <= 'z')
return 'Z' - 'A' + 1 + ch - 'a';
if(ch >= '0' && ch <= '9')
return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + ch - '0';
if(ch == '+')
return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1;
if(ch == '/')
return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1 + 1;
badc(ch);
assert(0);
}
if(!estr.length)
return buf[0 .. 0];
if(estr.length % 4)
throw new Base64Exception("Invalid encoded base64 string");
uint estri;
uint estrmax = estr.length / 4;
uint x;
char* sp, bp;
char ch;
sp = &estr[0];
bp = &buf[0];
for(estri = 0; estri != estrmax; estri++)
{
x = arrayIndex(sp[0]) << 18 | arrayIndex(sp[1]) << 12;
sp += 2;
ch = *sp++;
if(ch == '=')
{
if(*sp++ != '=')
badc('=');
*bp++ = cast(char) (x >> 16);
break;
}
x |= arrayIndex(ch) << 6;
ch = *sp++;
if(ch == '=')
{
*bp++ = cast(char) (x >> 16);
*bp++ = cast(char) ((x >> 8) & 0xFF);
break;
}
x |= arrayIndex(ch);
*bp++ = cast(char) (x >> 16);
*bp++ = cast(char) ((x >> 8) & 0xFF);
*bp++ = cast(char) (x & 0xFF);
}
return buf[0 .. (bp - &buf[0])];
}
/**
* Decodes estr[] and returns the result.
* Errors:
* Throws Base64Exception on invalid base64 encoding in estr[].
* Throws Base64CharException on invalid base64 character in estr[].
*/
char[] decode(char[] estr)
{
return decode(estr, new char[decodeLength(estr.length)]);
}
unittest
{
assert(decode(encode("f")) == "f");
assert(decode(encode("fo")) == "fo");
assert(decode(encode("foo")) == "foo");
assert(decode(encode("foos")) == "foos");
assert(decode(encode("all your base64 are belong to foo")) == "all your base64 are belong to foo");
assert(decode(encode("testing some more")) == "testing some more");
assert(decode(encode("asdf jkl;")) == "asdf jkl;");
assert(decode(encode("base64 stuff")) == "base64 stuff");
assert(decode(encode("\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!")) == "\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!");
}

View File

@@ -1,955 +0,0 @@
/***********************
* Macros:
* WIKI = StdBitarray
*/
module std.bitarray;
//debug = bitarray; // uncomment to turn on debugging printf's
private import std.intrinsic;
/**
* An array of bits.
*/
struct BitArray
{
size_t len;
uint* ptr;
size_t dim()
{
return (len + 31) / 32;
}
size_t length()
{
return len;
}
void length(size_t newlen)
{
if (newlen != len)
{
size_t olddim = dim();
size_t newdim = (newlen + 31) / 32;
if (newdim != olddim)
{
// Create a fake array so we can use D's realloc machinery
uint[] b = ptr[0 .. olddim];
b.length = newdim; // realloc
ptr = b.ptr;
if (newdim & 31)
{ // Set any pad bits to 0
ptr[newdim - 1] &= ~(~0 << (newdim & 31));
}
}
len = newlen;
}
}
/**********************************************
* Support for [$(I index)] operation for BitArray.
*/
bool opIndex(size_t i)
in
{
assert(i < len);
}
body
{
return cast(bool)bt(ptr, i);
}
/** ditto */
bool opIndexAssign(bool b, size_t i)
in
{
assert(i < len);
}
body
{
if (b)
bts(ptr, i);
else
btr(ptr, i);
return b;
}
/**********************************************
* Support for array.dup property for BitArray.
*/
BitArray dup()
{
BitArray ba;
uint[] b = ptr[0 .. dim].dup;
ba.len = len;
ba.ptr = b.ptr;
return ba;
}
unittest
{
BitArray a;
BitArray b;
int i;
debug(bitarray) printf("BitArray.dup.unittest\n");
a.length = 3;
a[0] = 1; a[1] = 0; a[2] = 1;
b = a.dup;
assert(b.length == 3);
for (i = 0; i < 3; i++)
{ debug(bitarray) printf("b[%d] = %d\n", i, b[i]);
assert(b[i] == (((i ^ 1) & 1) ? true : false));
}
}
/**********************************************
* Support for foreach loops for BitArray.
*/
int opApply(int delegate(inout bool) dg)
{
int result;
for (size_t i = 0; i < len; i++)
{ bool b = opIndex(i);
result = dg(b);
(*this)[i] = b;
if (result)
break;
}
return result;
}
/** ditto */
int opApply(int delegate(inout size_t, inout bool) dg)
{
int result;
for (size_t i = 0; i < len; i++)
{ bool b = opIndex(i);
result = dg(i, b);
(*this)[i] = b;
if (result)
break;
}
return result;
}
unittest
{
debug(bitarray) printf("BitArray.opApply unittest\n");
static bool[] ba = [1,0,1];
BitArray a; a.init(ba);
int i;
foreach (b;a)
{
switch (i)
{ case 0: assert(b == true); break;
case 1: assert(b == false); break;
case 2: assert(b == true); break;
default: assert(0);
}
i++;
}
foreach (j,b;a)
{
switch (j)
{ case 0: assert(b == true); break;
case 1: assert(b == false); break;
case 2: assert(b == true); break;
default: assert(0);
}
}
}
/**********************************************
* Support for array.reverse property for BitArray.
*/
BitArray reverse()
out (result)
{
assert(result == *this);
}
body
{
if (len >= 2)
{
bool t;
size_t lo, hi;
lo = 0;
hi = len - 1;
for (; lo < hi; lo++, hi--)
{
t = (*this)[lo];
(*this)[lo] = (*this)[hi];
(*this)[hi] = t;
}
}
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.reverse.unittest\n");
BitArray b;
static bool[5] data = [1,0,1,1,0];
int i;
b.init(data);
b.reverse;
for (i = 0; i < data.length; i++)
{
assert(b[i] == data[4 - i]);
}
}
/**********************************************
* Support for array.sort property for BitArray.
*/
BitArray sort()
out (result)
{
assert(result == *this);
}
body
{
if (len >= 2)
{
size_t lo, hi;
lo = 0;
hi = len - 1;
while (1)
{
while (1)
{
if (lo >= hi)
goto Ldone;
if ((*this)[lo] == true)
break;
lo++;
}
while (1)
{
if (lo >= hi)
goto Ldone;
if ((*this)[hi] == false)
break;
hi--;
}
(*this)[lo] = false;
(*this)[hi] = true;
lo++;
hi--;
}
Ldone:
;
}
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.sort.unittest\n");
static uint x = 0b1100011000;
static BitArray ba = { 10, &x };
ba.sort;
for (size_t i = 0; i < 6; i++)
assert(ba[i] == false);
for (size_t i = 6; i < 10; i++)
assert(ba[i] == true);
}
/***************************************
* Support for operators == and != for bit arrays.
*/
int opEquals(BitArray a2)
{ size_t i;
if (this.length != a2.length)
return 0; // not equal
uint *p1 = cast(uint*)this.ptr;
uint *p2 = cast(uint*)a2.ptr;
size_t n = this.length / (8 * uint.sizeof);
for (i = 0; i < n; i++)
{
if (p1[i] != p2[i])
return 0; // not equal
}
uint mask;
n = this.length & ((8 * uint.sizeof) - 1);
mask = (1 << n) - 1;
//printf("i = %d, n = %d, mask = %x, %x, %x\n", i, n, mask, p1[i], p2[i]);
return (mask == 0) || (p1[i] & mask) == (p2[i] & mask);
}
unittest
{
debug(bitarray) printf("BitArray.opEquals unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1];
static bool[] bc = [1,0,1,0,1,0,1];
static bool[] bd = [1,0,1,1,1];
static bool[] be = [1,0,1,0,1];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c; c.init(bc);
BitArray d; d.init(bd);
BitArray e; e.init(be);
assert(a != b);
assert(a != c);
assert(a != d);
assert(a == e);
}
/***************************************
* Implement comparison operators.
*/
int opCmp(BitArray a2)
{
size_t len;
size_t i;
len = this.length;
if (a2.length < len)
len = a2.length;
uint* p1 = cast(uint*)this.ptr;
uint* p2 = cast(uint*)a2.ptr;
size_t n = len / (8 * uint.sizeof);
for (i = 0; i < n; i++)
{
if (p1[i] != p2[i])
break; // not equal
}
/*
for (uint j = i * 8; j < len; j++)
{ ubyte mask = cast(ubyte)(1 << j);
int c;
c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask);
if (c)
return c;
}
*/
uint mask = 1;
for (size_t j = i * (8 * uint.sizeof); j < len; j++)
{ int c;
c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask);
if (c)
return c;
mask <<= 1;
}
ptrdiff_t c = cast(ptrdiff_t)this.len - cast(ptrdiff_t)a2.length;
if (c < 0)
return -1;
else if (c > 0)
return 1;
return 0;
}
unittest
{
debug(bitarray) printf("BitArray.opCmp unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1];
static bool[] bc = [1,0,1,0,1,0,1];
static bool[] bd = [1,0,1,1,1];
static bool[] be = [1,0,1,0,1];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c; c.init(bc);
BitArray d; d.init(bd);
BitArray e; e.init(be);
assert(a > b);
assert(a >= b);
assert(a < c);
assert(a <= c);
assert(a < d);
assert(a <= d);
assert(a == e);
assert(a <= e);
assert(a >= e);
}
/***************************************
* Set BitArray to contents of ba[]
*/
void init(bool[] ba)
{
length = ba.length;
foreach (i, b; ba)
{
(*this)[i] = b;
}
}
/***************************************
* Map BitArray onto v[], with numbits being the number of bits
* in the array. Does not copy the data.
*
* This is the inverse of opCast.
*/
void init(void[] v, size_t numbits)
in
{
assert(numbits <= v.length * 8);
assert((v.length & 3) == 0);
}
body
{
ptr = cast(uint*)v.ptr;
len = numbits;
}
unittest
{
debug(bitarray) printf("BitArray.init unittest\n");
static bool[] ba = [1,0,1,0,1];
BitArray a; a.init(ba);
BitArray b;
void[] v;
v = cast(void[])a;
b.init(v, a.length);
assert(b[0] == 1);
assert(b[1] == 0);
assert(b[2] == 1);
assert(b[3] == 0);
assert(b[4] == 1);
a[0] = 0;
assert(b[0] == 0);
assert(a == b);
}
/***************************************
* Convert to void[].
*/
void[] opCast()
{
return cast(void[])ptr[0 .. dim];
}
unittest
{
debug(bitarray) printf("BitArray.opCast unittest\n");
static bool[] ba = [1,0,1,0,1];
BitArray a; a.init(ba);
void[] v = cast(void[])a;
assert(v.length == a.dim * uint.sizeof);
}
/***************************************
* Support for unary operator ~ for bit arrays.
*/
BitArray opCom()
{
auto dim = this.dim();
BitArray result;
result.length = len;
for (size_t i = 0; i < dim; i++)
result.ptr[i] = ~this.ptr[i];
if (len & 31)
result.ptr[dim - 1] &= ~(~0 << (len & 31));
return result;
}
unittest
{
debug(bitarray) printf("BitArray.opCom unittest\n");
static bool[] ba = [1,0,1,0,1];
BitArray a; a.init(ba);
BitArray b = ~a;
assert(b[0] == 0);
assert(b[1] == 1);
assert(b[2] == 0);
assert(b[3] == 1);
assert(b[4] == 0);
}
/***************************************
* Support for binary operator & for bit arrays.
*/
BitArray opAnd(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
BitArray result;
result.length = len;
for (size_t i = 0; i < dim; i++)
result.ptr[i] = this.ptr[i] & e2.ptr[i];
return result;
}
unittest
{
debug(bitarray) printf("BitArray.opAnd unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c = a & b;
assert(c[0] == 1);
assert(c[1] == 0);
assert(c[2] == 1);
assert(c[3] == 0);
assert(c[4] == 0);
}
/***************************************
* Support for binary operator | for bit arrays.
*/
BitArray opOr(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
BitArray result;
result.length = len;
for (size_t i = 0; i < dim; i++)
result.ptr[i] = this.ptr[i] | e2.ptr[i];
return result;
}
unittest
{
debug(bitarray) printf("BitArray.opOr unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c = a | b;
assert(c[0] == 1);
assert(c[1] == 0);
assert(c[2] == 1);
assert(c[3] == 1);
assert(c[4] == 1);
}
/***************************************
* Support for binary operator ^ for bit arrays.
*/
BitArray opXor(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
BitArray result;
result.length = len;
for (size_t i = 0; i < dim; i++)
result.ptr[i] = this.ptr[i] ^ e2.ptr[i];
return result;
}
unittest
{
debug(bitarray) printf("BitArray.opXor unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c = a ^ b;
assert(c[0] == 0);
assert(c[1] == 0);
assert(c[2] == 0);
assert(c[3] == 1);
assert(c[4] == 1);
}
/***************************************
* Support for binary operator - for bit arrays.
*
* $(I a - b) for BitArrays means the same thing as $(I a &amp; ~b).
*/
BitArray opSub(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
BitArray result;
result.length = len;
for (size_t i = 0; i < dim; i++)
result.ptr[i] = this.ptr[i] & ~e2.ptr[i];
return result;
}
unittest
{
debug(bitarray) printf("BitArray.opSub unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c = a - b;
assert(c[0] == 0);
assert(c[1] == 0);
assert(c[2] == 0);
assert(c[3] == 0);
assert(c[4] == 1);
}
/***************************************
* Support for operator &= bit arrays.
*/
BitArray opAndAssign(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
for (size_t i = 0; i < dim; i++)
ptr[i] &= e2.ptr[i];
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.opAndAssign unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
a &= b;
assert(a[0] == 1);
assert(a[1] == 0);
assert(a[2] == 1);
assert(a[3] == 0);
assert(a[4] == 0);
}
/***************************************
* Support for operator |= for bit arrays.
*/
BitArray opOrAssign(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
for (size_t i = 0; i < dim; i++)
ptr[i] |= e2.ptr[i];
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.opOrAssign unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
a |= b;
assert(a[0] == 1);
assert(a[1] == 0);
assert(a[2] == 1);
assert(a[3] == 1);
assert(a[4] == 1);
}
/***************************************
* Support for operator ^= for bit arrays.
*/
BitArray opXorAssign(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
for (size_t i = 0; i < dim; i++)
ptr[i] ^= e2.ptr[i];
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.opXorAssign unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
a ^= b;
assert(a[0] == 0);
assert(a[1] == 0);
assert(a[2] == 0);
assert(a[3] == 1);
assert(a[4] == 1);
}
/***************************************
* Support for operator -= for bit arrays.
*
* $(I a -= b) for BitArrays means the same thing as $(I a &amp;= ~b).
*/
BitArray opSubAssign(BitArray e2)
in
{
assert(len == e2.length);
}
body
{
auto dim = this.dim();
for (size_t i = 0; i < dim; i++)
ptr[i] &= ~e2.ptr[i];
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.opSubAssign unittest\n");
static bool[] ba = [1,0,1,0,1];
static bool[] bb = [1,0,1,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
a -= b;
assert(a[0] == 0);
assert(a[1] == 0);
assert(a[2] == 0);
assert(a[3] == 0);
assert(a[4] == 1);
}
/***************************************
* Support for operator ~= for bit arrays.
*/
BitArray opCatAssign(bool b)
{
length = len + 1;
(*this)[len - 1] = b;
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.opCatAssign unittest\n");
static bool[] ba = [1,0,1,0,1];
BitArray a; a.init(ba);
BitArray b;
b = (a ~= true);
assert(a[0] == 1);
assert(a[1] == 0);
assert(a[2] == 1);
assert(a[3] == 0);
assert(a[4] == 1);
assert(a[5] == 1);
assert(b == a);
}
/***************************************
* ditto
*/
BitArray opCatAssign(BitArray b)
{
auto istart = len;
length = len + b.length;
for (auto i = istart; i < len; i++)
(*this)[i] = b[i - istart];
return *this;
}
unittest
{
debug(bitarray) printf("BitArray.opCatAssign unittest\n");
static bool[] ba = [1,0];
static bool[] bb = [0,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c;
c = (a ~= b);
assert(a.length == 5);
assert(a[0] == 1);
assert(a[1] == 0);
assert(a[2] == 0);
assert(a[3] == 1);
assert(a[4] == 0);
assert(c == a);
}
/***************************************
* Support for binary operator ~ for bit arrays.
*/
BitArray opCat(bool b)
{
BitArray r;
r = this.dup;
r.length = len + 1;
r[len] = b;
return r;
}
/** ditto */
BitArray opCat_r(bool b)
{
BitArray r;
r.length = len + 1;
r[0] = b;
for (size_t i = 0; i < len; i++)
r[1 + i] = (*this)[i];
return r;
}
/** ditto */
BitArray opCat(BitArray b)
{
BitArray r;
r = this.dup();
r ~= b;
return r;
}
unittest
{
debug(bitarray) printf("BitArray.opCat unittest\n");
static bool[] ba = [1,0];
static bool[] bb = [0,1,0];
BitArray a; a.init(ba);
BitArray b; b.init(bb);
BitArray c;
c = (a ~ b);
assert(c.length == 5);
assert(c[0] == 1);
assert(c[1] == 0);
assert(c[2] == 0);
assert(c[3] == 1);
assert(c[4] == 0);
c = (a ~ true);
assert(c.length == 3);
assert(c[0] == 1);
assert(c[1] == 0);
assert(c[2] == 1);
c = (false ~ a);
assert(c.length == 3);
assert(c[0] == 0);
assert(c[1] == 1);
assert(c[2] == 0);
}
}

View File

@@ -1,112 +0,0 @@
/**
* C's &lt;fenv.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCFenv
*/
module std.c.fenv;
extern (C):
/// Entire floating point environment
struct fenv_t
{
version (Windows)
{
ushort status;
ushort control;
ushort round;
ushort reserved[2];
}
else version (linux)
{
ushort __control_word;
ushort __unused1;
ushort __status_word;
ushort __unused2;
ushort __tags;
ushort __unused3;
uint __eip;
ushort __cs_selector;
ushort __opcode;
uint __data_offset;
ushort __data_selector;
ushort __unused5;
}
else
{
static assert(0);
}
}
alias int fexcept_t; /// Floating point status flags
/// The various floating point exceptions
enum
{
FE_INVALID = 1, ///
FE_DENORMAL = 2, ///
FE_DIVBYZERO = 4, ///
FE_OVERFLOW = 8, ///
FE_UNDERFLOW = 0x10, ///
FE_INEXACT = 0x20, ///
FE_ALL_EXCEPT = 0x3F, /// Mask of all the exceptions
}
/// Rounding modes
enum
{
FE_TONEAREST = 0, ///
FE_UPWARD = 0x800, ///
FE_DOWNWARD = 0x400, ///
FE_TOWARDZERO = 0xC00, ///
}
version (Windows)
{
extern fenv_t _FE_DFL_ENV;
/// Default floating point environment
fenv_t* FE_DFL_ENV = &_FE_DFL_ENV;
}
else version (linux)
{
/// Default floating point environment
fenv_t* FE_DFL_ENV = cast(fenv_t*)(-1);
}
else
{
static assert(0);
}
/// Floating point precision
enum
{
FE_FLTPREC = 0, ///
FE_DBLPREC = 0x200, ///
FE_LDBLPREC = 0x300, ///
}
int fetestexcept(int excepts); ///
int feraiseexcept(int excepts); ///
int feclearexcept(int excepts); ///
//int fegetexcept(fexcept_t *flagp,int excepts); ///
//int fesetexcept(fexcept_t *flagp,int excepts); ///
int fegetround(); ///
int fesetround(int round); ///
int fegetprec(); ///
int fesetprec(int prec); ///
int fegetenv(fenv_t *envp); ///
int fesetenv(fenv_t *envp); ///
//void feprocentry(fenv_t *envp); ///
//void feprocexit(const fenv_t *envp); ///
int fegetexceptflag(fexcept_t *flagp,int excepts); ///
int fesetexceptflag(fexcept_t *flagp,int excepts); ///
int feholdexcept(fenv_t *envp); ///
int feupdateenv(fenv_t *envp); ///

View File

@@ -1,478 +0,0 @@
/* Written by Walter Bright, Christopher E. Miller, and many others.
* www.digitalmars.com
* Placed into public domain.
* Linux(R) is the registered trademark of Linus Torvalds in the U.S. and other
* countries.
*/
module std.c.linux.linux;
public import std.c.linux.linuxextern;
public import std.c.linux.pthread;
private import std.c.stdio;
alias int pid_t;
alias int off_t;
alias uint mode_t;
alias uint uid_t;
alias uint gid_t;
static if (size_t.sizeof == 4)
alias int ssize_t;
else
alias long ssize_t;
enum : int
{
SIGHUP = 1,
SIGINT = 2,
SIGQUIT = 3,
SIGILL = 4,
SIGTRAP = 5,
SIGABRT = 6,
SIGIOT = 6,
SIGBUS = 7,
SIGFPE = 8,
SIGKILL = 9,
SIGUSR1 = 10,
SIGSEGV = 11,
SIGUSR2 = 12,
SIGPIPE = 13,
SIGALRM = 14,
SIGTERM = 15,
SIGSTKFLT = 16,
SIGCHLD = 17,
SIGCONT = 18,
SIGSTOP = 19,
SIGTSTP = 20,
SIGTTIN = 21,
SIGTTOU = 22,
SIGURG = 23,
SIGXCPU = 24,
SIGXFSZ = 25,
SIGVTALRM = 26,
SIGPROF = 27,
SIGWINCH = 28,
SIGPOLL = 29,
SIGIO = 29,
SIGPWR = 30,
SIGSYS = 31,
SIGUNUSED = 31,
}
enum
{
O_RDONLY = 0,
O_WRONLY = 1,
O_RDWR = 2,
O_CREAT = 0100,
O_EXCL = 0200,
O_TRUNC = 01000,
O_APPEND = 02000,
}
struct struct_stat // distinguish it from the stat() function
{
ulong st_dev; /// device
ushort __pad1;
uint st_ino; /// file serial number
uint st_mode; /// file mode
uint st_nlink; /// link count
uint st_uid; /// user ID of file's owner
uint st_gid; /// user ID of group's owner
ulong st_rdev; /// if device then device number
ushort __pad2;
int st_size; /// file size in bytes
int st_blksize; /// optimal I/O block size
int st_blocks; /// number of allocated 512 byte blocks
int st_atime;
uint st_atimensec;
int st_mtime;
uint st_mtimensec;
int st_ctime;
uint st_ctimensec;
uint __unused4;
uint __unused5;
}
static assert(struct_stat.sizeof == 88);
enum : int
{
S_IFIFO = 0010000,
S_IFCHR = 0020000,
S_IFDIR = 0040000,
S_IFBLK = 0060000,
S_IFREG = 0100000,
S_IFLNK = 0120000,
S_IFSOCK = 0140000,
S_IFMT = 0170000,
S_IREAD = 0000400,
S_IWRITE = 0000200,
S_IEXEC = 0000100,
}
extern (C)
{
int access(char*, int);
int open(char*, int, ...);
int read(int, void*, int);
int write(int, void*, int);
int close(int);
int lseek(int, int, int);
int fstat(int, struct_stat*);
int lstat(char*, struct_stat*);
int stat(char*, struct_stat*);
int chdir(char*);
int mkdir(char*, int);
int rmdir(char*);
char* getcwd(char*, int);
int chmod(char*, mode_t);
int fork();
int dup(int);
int dup2(int, int);
int pipe(int[2]);
pid_t wait(int*);
int waitpid(pid_t, int*, int);
uint alarm(uint);
char* basename(char*);
//wint_t btowc(int);
int chown(char*, uid_t, gid_t);
int chroot(char*);
size_t confstr(int, char*, size_t);
int creat(char*, mode_t);
char* ctermid(char*);
int dirfd(DIR*);
char* dirname(char*);
int fattach(int, char*);
int fchmod(int, mode_t);
int fdatasync(int);
int ffs(int);
int fmtmsg(int, char*, int, char*, char*, char*);
int fpathconf(int, int);
int fseeko(FILE*, off_t, int);
off_t ftello(FILE*);
extern char** environ;
}
struct timeval
{
int tv_sec;
int tv_usec;
}
struct struct_timezone
{
int tz_minuteswest;
int tz_dstime;
}
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
int tm_gmtoff;
int tm_zone;
}
extern (C)
{
int gettimeofday(timeval*, struct_timezone*);
__time_t time(__time_t*);
char* asctime(tm*);
char* ctime(__time_t*);
tm* gmtime(__time_t*);
tm* localtime(__time_t*);
__time_t mktime(tm*);
char* asctime_r(tm* t, char* buf);
char* ctime_r(__time_t* timep, char* buf);
tm* gmtime_r(__time_t* timep, tm* result);
tm* localtime_r(__time_t* timep, tm* result);
}
/**************************************************************/
// Memory mapping from <sys/mman.h> and <bits/mman.h>
enum
{
PROT_NONE = 0,
PROT_READ = 1,
PROT_WRITE = 2,
PROT_EXEC = 4,
}
// Memory mapping sharing types
enum
{ MAP_SHARED = 1,
MAP_PRIVATE = 2,
MAP_TYPE = 0x0F,
MAP_FIXED = 0x10,
MAP_FILE = 0,
MAP_ANONYMOUS = 0x20,
MAP_ANON = 0x20,
MAP_GROWSDOWN = 0x100,
MAP_DENYWRITE = 0x800,
MAP_EXECUTABLE = 0x1000,
MAP_LOCKED = 0x2000,
MAP_NORESERVE = 0x4000,
MAP_POPULATE = 0x8000,
MAP_NONBLOCK = 0x10000,
}
// Values for msync()
enum
{ MS_ASYNC = 1,
MS_INVALIDATE = 2,
MS_SYNC = 4,
}
// Values for mlockall()
enum
{
MCL_CURRENT = 1,
MCL_FUTURE = 2,
}
// Values for mremap()
enum
{
MREMAP_MAYMOVE = 1,
}
// Values for madvise
enum
{ MADV_NORMAL = 0,
MADV_RANDOM = 1,
MADV_SEQUENTIAL = 2,
MADV_WILLNEED = 3,
MADV_DONTNEED = 4,
}
extern (C)
{
void* mmap(void*, size_t, int, int, int, off_t);
const void* MAP_FAILED = cast(void*)-1;
int munmap(void*, size_t);
int mprotect(void*, size_t, int);
int msync(void*, size_t, int);
int madvise(void*, size_t, int);
int mlock(void*, size_t);
int munlock(void*, size_t);
int mlockall(int);
int munlockall();
void* mremap(void*, size_t, size_t, int);
int mincore(void*, size_t, ubyte*);
int remap_file_pages(void*, size_t, int, size_t, int);
int shm_open(char*, int, int);
int shm_unlink(char*);
}
extern(C)
{
enum
{
DT_UNKNOWN = 0,
DT_FIFO = 1,
DT_CHR = 2,
DT_DIR = 4,
DT_BLK = 6,
DT_REG = 8,
DT_LNK = 10,
DT_SOCK = 12,
DT_WHT = 14,
}
struct dirent
{
int d_ino;
off_t d_off;
ushort d_reclen;
ubyte d_type;
char[256] d_name;
}
struct DIR
{
// Managed by OS.
}
DIR* opendir(char* name);
int closedir(DIR* dir);
dirent* readdir(DIR* dir);
void rewinddir(DIR* dir);
off_t telldir(DIR* dir);
void seekdir(DIR* dir, off_t offset);
}
extern(C)
{
private import std.intrinsic;
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
int fcntl(int s, int f, ...);
enum
{
EINTR = 4,
EINPROGRESS = 115,
}
const uint FD_SETSIZE = 1024;
//const uint NFDBITS = 8 * int.sizeof; // DMD 0.110: 8 * (int).sizeof is not an expression
const int NFDBITS = 32;
struct fd_set
{
int[FD_SETSIZE / NFDBITS] fds_bits;
alias fds_bits __fds_bits;
}
int FDELT(int d)
{
return d / NFDBITS;
}
int FDMASK(int d)
{
return 1 << (d % NFDBITS);
}
// Removes.
void FD_CLR(int fd, fd_set* set)
{
btr(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS));
}
// Tests.
int FD_ISSET(int fd, fd_set* set)
{
return bt(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS));
}
// Adds.
void FD_SET(int fd, fd_set* set)
{
bts(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS));
}
// Resets to zero.
void FD_ZERO(fd_set* set)
{
set.fds_bits[] = 0;
}
}
extern (C)
{
/* From <dlfcn.h>
* See http://www.opengroup.org/onlinepubs/007908799/xsh/dlsym.html
*/
const int RTLD_NOW = 0x00002; // Correct for Red Hat 8
void* dlopen(char* file, int mode);
int dlclose(void* handle);
void* dlsym(void* handle, char* name);
char* dlerror();
}
extern (C)
{
/* from <pwd.h>
*/
struct passwd
{
char *pw_name;
char *pw_passwd;
uid_t pw_uid;
gid_t pw_gid;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
}
const size_t _SIGSET_NWORDS = 1024 / (8 * uint.sizeof);
struct sigset_t
{
uint[_SIGSET_NWORDS] __val;
}
int getpwnam_r(char*, passwd*, void*, size_t, passwd**);
passwd* getpwnam(char*);
passwd* getpwuid(uid_t);
int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**);
int kill(pid_t, int);
int sem_close(sem_t*);
int sigemptyset(sigset_t*);
int sigfillset(sigset_t*);
int sigismember(sigset_t*, int);
int sigsuspend(sigset_t*);
}
extern (C)
{
/* from semaphore.h
*/
struct sem_t
{
_pthread_fastlock __sem_lock;
int __sem_value;
void* __sem_waiting;
}
int sem_init(sem_t*, int, uint);
int sem_wait(sem_t*);
int sem_trywait(sem_t*);
int sem_post(sem_t*);
int sem_getvalue(sem_t*, int*);
int sem_destroy(sem_t*);
}
extern (C)
{
/* from utime.h
*/
struct utimbuf
{
__time_t actime;
__time_t modtime;
}
int utime(char* filename, utimbuf* buf);
}

View File

@@ -1,25 +0,0 @@
/* Written by Walter Bright.
* www.digitalmars.com
* Placed into public domain.
* Linux(R) is the registered trademark of Linus Torvalds in the U.S. and other
* countries.
*/
/* These are all the globals defined by the linux C runtime library.
* Put them separate so they'll be externed - do not link in linuxextern.o
*/
module std.c.linux.linuxextern;
extern extern (C)
{
void* __libc_stack_end;
int __data_start;
int _end;
int timezone;
void *_deh_beg;
void *_deh_end;
}

View File

@@ -1,257 +0,0 @@
/* Written by Walter Bright, Christopher E. Miller, and many others.
* www.digitalmars.com
* Placed into public domain.
*/
module std.c.linux.pthread;
extern (C)
{
/* pthread declarations taken from pthread headers and
http://svn.dsource.org/projects/bindings/trunk/pthreads.d
*/
/* from bits/types.h
*/
typedef int __time_t;
/* from time.h
*/
struct timespec
{
__time_t tv_sec; /* seconds */
int tv_nsec; /* nanosecs. */
}
/* from bits/pthreadtypes.h
*/
alias uint pthread_t;
alias uint pthread_key_t;
alias int pthread_once_t;
alias int clockid_t;
alias int pthread_spinlock_t; // volatile
struct _pthread_descr_struct
{
/* Not defined in the headers ???
Just needed here to typedef
the _pthread_descr pointer
*/
}
typedef _pthread_descr_struct* _pthread_descr;
struct _pthread_fastlock
{
int __status;
int __spinlock;
}
typedef long __pthread_cond_align_t;
struct pthread_cond_t
{
_pthread_fastlock __c_lock;
_pthread_descr __c_waiting;
char[48
- _pthread_fastlock.sizeof
- _pthread_descr.sizeof
- __pthread_cond_align_t.sizeof
] __padding;
__pthread_cond_align_t __align;
}
struct pthread_condattr_t
{
int __dummy;
}
struct pthread_mutex_t
{
int __m_reserved;
int __m_count;
_pthread_descr __m_owner;
int __m_kind;
_pthread_fastlock __m_lock;
}
struct pthread_mutexattr_t
{
int __mutexkind;
}
/* from pthread.h
*/
struct _pthread_cleanup_buffer
{
void function(void*) __routine;
void* __arg;
int __canceltype;
_pthread_cleanup_buffer* __prev;
}
struct __sched_param // bits/sched.h
{
int __sched_priority;
}
struct pthread_attr_t
{
int __detachstate;
int __schedpolicy;
__sched_param schedparam;
int __inheritshed;
int __scope;
size_t __guardsize;
int __stackaddr_set;
void* __stackaddr;
size_t __stacksize;
}
struct pthread_barrier_t
{
_pthread_fastlock __ba_lock;
int __ba_required;
int __ba_present;
_pthread_descr __ba_waiting;
}
struct pthread_barrierattr_t
{
int __pshared;
}
struct pthread_rwlockattr_t
{
int __lockkind;
int __pshared;
}
struct pthread_rwlock_t
{
_pthread_fastlock __rw_lock;
int __rw_readers;
_pthread_descr __rw_writer;
_pthread_descr __rw_read_waiting;
_pthread_descr __rw_write_waiting;
int __rw_kind;
int __rw_pshared;
}
int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*);
int pthread_mutex_destroy(pthread_mutex_t*);
int pthread_mutex_trylock(pthread_mutex_t*);
int pthread_mutex_lock(pthread_mutex_t*);
int pthread_mutex_unlock(pthread_mutex_t*);
int pthread_mutexattr_init(pthread_mutexattr_t*);
int pthread_mutexattr_destroy(pthread_mutexattr_t*);
int pthread_cond_init(pthread_cond_t*, pthread_condattr_t*);
int pthread_cond_destroy(pthread_cond_t*);
int pthread_cond_signal(pthread_cond_t*);
int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, timespec*);
int pthread_attr_init(pthread_attr_t*);
int pthread_attr_destroy(pthread_attr_t*);
int pthread_attr_setdetachstate(pthread_attr_t*, int);
int pthread_attr_getdetachstate(pthread_attr_t*, int*);
int pthread_attr_setinheritsched(pthread_attr_t*, int);
int pthread_attr_getinheritsched(pthread_attr_t*, int*);
int pthread_attr_setschedparam(pthread_attr_t*, __sched_param*);
int pthread_attr_getschedparam(pthread_attr_t*, __sched_param*);
int pthread_attr_setschedpolicy(pthread_attr_t*, int);
int pthread_attr_getschedpolicy(pthread_attr_t*, int*);
int pthread_attr_setscope(pthread_attr_t*, int);
int pthread_attr_getscope(pthread_attr_t*, int*);
int pthread_attr_setguardsize(pthread_attr_t*, size_t);
int pthread_attr_getguardsize(pthread_attr_t*, size_t*);
int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
int pthread_attr_getstack(pthread_attr_t*, void**, size_t*);
int pthread_attr_setstackaddr(pthread_attr_t*, void*);
int pthread_attr_getstackaddr(pthread_attr_t*, void**);
int pthread_attr_setstacksize(pthread_attr_t*, size_t);
int pthread_attr_getstacksize(pthread_attr_t*, size_t*);
int pthread_barrierattr_init(pthread_barrierattr_t*);
int pthread_barrierattr_getpshared(pthread_barrierattr_t*, int*);
int pthread_barrierattr_destroy(pthread_barrierattr_t*);
int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
int pthread_barrier_init(pthread_barrier_t*, pthread_barrierattr_t*, uint);
int pthread_barrier_destroy(pthread_barrier_t*);
int pthread_barrier_wait(pthread_barrier_t*);
int pthread_condattr_init(pthread_condattr_t*);
int pthread_condattr_destroy(pthread_condattr_t*);
int pthread_condattr_getpshared(pthread_condattr_t*, int*);
int pthread_condattr_setpshared(pthread_condattr_t*, int);
int pthread_detach(pthread_t);
void pthread_exit(void*);
int pthread_getattr_np(pthread_t, pthread_attr_t*);
int pthread_getconcurrency();
int pthread_getcpuclockid(pthread_t, clockid_t*);
int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*);
int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
int pthread_mutex_timedlock(pthread_mutex_t*, timespec*);
int pthread_yield();
int pthread_rwlock_init(pthread_rwlock_t*, pthread_rwlockattr_t*);
int pthread_rwlock_destroy(pthread_rwlock_t*);
int pthread_rwlock_rdlock(pthread_rwlock_t*);
int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
int pthread_rwlock_timedrdlock(pthread_rwlock_t*, timespec*);
int pthread_rwlock_wrlock(pthread_rwlock_t*);
int pthread_rwlock_trywrlock(pthread_rwlock_t*);
int pthread_rwlock_timedwrlock(pthread_rwlock_t*, timespec*);
int pthread_rwlock_unlock(pthread_rwlock_t*);
int pthread_rwlockattr_init(pthread_rwlockattr_t*);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
int pthread_rwlockattr_getkind_np(pthread_rwlockattr_t*, int*);
int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t*, int);
int pthread_spin_init(pthread_spinlock_t*, int);
int pthread_spin_destroy(pthread_spinlock_t*);
int pthread_spin_lock(pthread_spinlock_t*);
int pthread_spin_trylock(pthread_spinlock_t*);
int pthread_spin_unlock(pthread_spinlock_t*);
int pthread_cancel(pthread_t);
void pthread_testcancel();
int pthread_once(pthread_once_t*, void function());
int pthread_join(pthread_t, void**);
int pthread_create(pthread_t*, pthread_attr_t*, void*function(void*), void*);
pthread_t pthread_self();
int pthread_equal(pthread_t, pthread_t);
int pthread_atfork(void function(), void function(), void function());
void pthread_kill_other_threads_np();
int pthread_setschedparam(pthread_t, int, __sched_param*);
int pthread_getschedparam(pthread_t, int*, __sched_param*);
int pthread_cond_broadcast(pthread_cond_t*);
int pthread_key_create(pthread_key_t*, void function(void*));
int pthread_key_delete(pthread_key_t);
int pthread_setconcurrency(int);
int pthread_setspecific(pthread_key_t, void*);
void* pthread_getspecific(pthread_key_t);
int pthread_setcanceltype(int, int*);
int pthread_setcancelstate(int, int*);
void _pthread_cleanup_push(_pthread_cleanup_buffer*, void function(void*), void*);
void _pthread_cleanup_push_defer(_pthread_cleanup_buffer*, void function(void*), void*);
void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
void _pthread_cleanup_pop_restore(_pthread_cleanup_buffer*, int);
}

View File

@@ -1,396 +0,0 @@
/*
Written by Christopher E. Miller
Placed into public domain.
*/
module std.c.linux.socket;
private import std.stdint;
extern(C):
alias int socklen_t;
const int F_GETFL = 3;
const int F_SETFL = 4;
const int O_NONBLOCK = 0x800;
int socket(int af, int type, int protocol);
int bind(int s, sockaddr* name, int namelen);
int connect(int s, sockaddr* name, int namelen);
int listen(int s, int backlog);
int accept(int s, sockaddr* addr, int* addrlen);
int shutdown(int s, int how);
int getpeername(int s, sockaddr* name, int* namelen);
int getsockname(int s, sockaddr* name, int* namelen);
int send(int s, void* buf, int len, int flags);
int sendto(int s, void* buf, int len, int flags, sockaddr* to, int tolen);
int recv(int s, void* buf, int len, int flags);
int recvfrom(int s, void* buf, int len, int flags, sockaddr* from, int* fromlen);
int getsockopt(int s, int level, int optname, void* optval, int* optlen);
int setsockopt(int s, int level, int optname, void* optval, int optlen);
uint inet_addr(char* cp);
char* inet_ntoa(in_addr ina);
hostent* gethostbyname(char* name);
int gethostbyname_r(char* name, hostent* ret, void* buf, size_t buflen, hostent** result, int* h_errnop);
int gethostbyname2_r(char* name, int af, hostent* ret, void* buf, size_t buflen, hostent** result, int* h_errnop);
hostent* gethostbyaddr(void* addr, int len, int type);
protoent* getprotobyname(char* name);
protoent* getprotobynumber(int number);
servent* getservbyname(char* name, char* proto);
servent* getservbyport(int port, char* proto);
int gethostname(char* name, int namelen);
int getaddrinfo(char* nodename, char* servname, addrinfo* hints, addrinfo** res);
void freeaddrinfo(addrinfo* ai);
int getnameinfo(sockaddr* sa, socklen_t salen, char* node, socklen_t nodelen, char* service, socklen_t servicelen, int flags);
enum: int
{
AF_UNSPEC = 0,
AF_UNIX = 1,
AF_INET = 2,
AF_IPX = 4,
AF_APPLETALK = 5,
AF_INET6 = 10,
// ...
PF_UNSPEC = AF_UNSPEC,
PF_UNIX = AF_UNIX,
PF_INET = AF_INET,
PF_IPX = AF_IPX,
PF_APPLETALK = AF_APPLETALK,
PF_INET6 = AF_INET6,
}
version(X86)
version=SOL_SOCKET_IS_1;
else version(X86_64)
version=SOL_SOCKET_IS_1;
else version(PPC)
version=SOL_SOCKET_IS_1;
else version(PPC64)
version=SOL_SOCKET_IS_1;
else
static assert(0, "Unsupported architecture");
version(SOL_SOCKET_IS_1)
{
enum: int
{
SOL_SOCKET = 1,
}
}
else
{
// Different values on other platforms.
static assert(0);
}
enum: int
{
SO_DEBUG = 1,
SO_BROADCAST = 6,
SO_REUSEADDR = 2,
SO_LINGER = 13,
SO_DONTLINGER = ~SO_LINGER,
SO_OOBINLINE = 10,
SO_SNDBUF = 7,
SO_RCVBUF = 8,
SO_ACCEPTCONN = 30,
SO_DONTROUTE = 5,
SO_TYPE = 3,
TCP_NODELAY = 1,
IP_MULTICAST_LOOP = 34,
IP_ADD_MEMBERSHIP = 35,
IP_DROP_MEMBERSHIP = 36,
// ...
IPV6_ADDRFORM = 1,
IPV6_PKTINFO = 2,
IPV6_HOPOPTS = 3,
IPV6_DSTOPTS = 4,
IPV6_RTHDR = 5,
IPV6_PKTOPTIONS = 6,
IPV6_CHECKSUM = 7,
IPV6_HOPLIMIT = 8,
IPV6_NEXTHOP = 9,
IPV6_AUTHHDR = 10,
IPV6_UNICAST_HOPS = 16,
IPV6_MULTICAST_IF = 17,
IPV6_MULTICAST_HOPS = 18,
IPV6_MULTICAST_LOOP = 19,
IPV6_JOIN_GROUP = 20,
IPV6_LEAVE_GROUP = 21,
IPV6_ROUTER_ALERT = 22,
IPV6_MTU_DISCOVER = 23,
IPV6_MTU = 24,
IPV6_RECVERR = 25,
IPV6_V6ONLY = 26,
IPV6_JOIN_ANYCAST = 27,
IPV6_LEAVE_ANYCAST = 28,
IPV6_IPSEC_POLICY = 34,
IPV6_XFRM_POLICY = 35,
}
struct linger
{
int32_t l_onoff;
int32_t l_linger;
}
struct protoent
{
char* p_name;
char** p_aliases;
int32_t p_proto;
}
struct servent
{
char* s_name;
char** s_aliases;
int32_t s_port;
char* s_proto;
}
version(BigEndian)
{
uint16_t htons(uint16_t x)
{
return x;
}
uint32_t htonl(uint32_t x)
{
return x;
}
}
else version(LittleEndian)
{
private import std.intrinsic;
uint16_t htons(uint16_t x)
{
return cast(uint16_t)((x >> 8) | (x << 8));
}
uint32_t htonl(uint32_t x)
{
return bswap(x);
}
}
else
{
static assert(0);
}
uint16_t ntohs(uint16_t x)
{
return htons(x);
}
uint32_t ntohl(uint32_t x)
{
return htonl(x);
}
enum: int
{
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
}
enum: int
{
IPPROTO_IP = 0,
IPPROTO_ICMP = 1,
IPPROTO_IGMP = 2,
IPPROTO_GGP = 3,
IPPROTO_TCP = 6,
IPPROTO_PUP = 12,
IPPROTO_UDP = 17,
IPPROTO_IDP = 22,
IPPROTO_IPV6 = 41,
IPPROTO_ND = 77,
IPPROTO_RAW = 255,
IPPROTO_MAX = 256,
}
enum: int
{
MSG_OOB = 0x1,
MSG_PEEK = 0x2,
MSG_DONTROUTE = 0x4,
}
enum: int
{
SD_RECEIVE = 0,
SD_SEND = 1,
SD_BOTH = 2,
}
enum: uint
{
INADDR_ANY = 0,
INADDR_LOOPBACK = 0x7F000001,
INADDR_BROADCAST = 0xFFFFFFFF,
INADDR_NONE = 0xFFFFFFFF,
ADDR_ANY = INADDR_ANY,
}
enum: int
{
AI_PASSIVE = 0x1,
AI_CANONNAME = 0x2,
AI_NUMERICHOST = 0x4,
}
union in_addr
{
private union _S_un_t
{
private struct _S_un_b_t
{
uint8_t s_b1, s_b2, s_b3, s_b4;
}
_S_un_b_t S_un_b;
private struct _S_un_w_t
{
uint16_t s_w1, s_w2;
}
_S_un_w_t S_un_w;
uint32_t S_addr;
}
_S_un_t S_un;
uint32_t s_addr;
struct
{
uint8_t s_net, s_host;
union
{
uint16_t s_imp;
struct
{
uint8_t s_lh, s_impno;
}
}
}
}
union in6_addr
{
private union _in6_u_t
{
uint8_t[16] u6_addr8;
uint16_t[8] u6_addr16;
uint32_t[4] u6_addr32;
}
_in6_u_t in6_u;
uint8_t[16] s6_addr8;
uint16_t[8] s6_addr16;
uint32_t[4] s6_addr32;
}
const in6_addr IN6ADDR_ANY = { s6_addr8: 0 };
const in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
//alias IN6ADDR_ANY IN6ADDR_ANY_INIT;
//alias IN6ADDR_LOOPBACK IN6ADDR_LOOPBACK_INIT;
const uint INET_ADDRSTRLEN = 16;
const uint INET6_ADDRSTRLEN = 46;
struct sockaddr
{
int16_t sa_family;
ubyte[14] sa_data;
}
struct sockaddr_in
{
int16_t sin_family = AF_INET;
uint16_t sin_port;
in_addr sin_addr;
ubyte[8] sin_zero;
}
struct sockaddr_in6
{
int16_t sin6_family = AF_INET6;
uint16_t sin6_port;
uint32_t sin6_flowinfo;
in6_addr sin6_addr;
uint32_t sin6_scope_id;
}
struct addrinfo
{
int32_t ai_flags;
int32_t ai_family;
int32_t ai_socktype;
int32_t ai_protocol;
size_t ai_addrlen;
sockaddr* ai_addr;
char* ai_canonname;
addrinfo* ai_next;
}
struct hostent
{
char* h_name;
char** h_aliases;
int32_t h_addrtype;
int32_t h_length;
char** h_addr_list;
char* h_addr()
{
return h_addr_list[0];
}
}

View File

@@ -1,151 +0,0 @@
/**
* C's &lt;locale.h&gt;
* License: Public Domain
* Standards:
* ISO/IEC 9899:1999 7.11
* Macros:
* WIKI=Phobos/StdCLocale
*/
module std.c.locale;
extern(C):
/// Structure giving information about numeric and monetary notation.
struct lconv{
/// The decimal-point character used to format nonmonetary quantities.
char* decimal_point;
/** The character used to separate groups of digits before the
* decimal-point character in formatted nonmonetary quantities.
**/
char* thousands_sep;
/** A string whose elements indicate the size of each group of digits
* in formatted nonmonetary quantities.
**/
char* grouping;
/** The international currency symbol applicable to the current locale.
* The first three characters contain the alphabetic international
* currency symbol in accordance with those specified in ISO 4217.
* The fourth character (immediately preceding the null character)
* is the character used to separate the international currency symbol
* from the monetary quantity.
**/
char* int_curr_symbol;
/// The local currency symbol applicable to the current locale.
char* currency_symbol;
/// The decimal-point used to format monetary quantities.
char* mon_decimal_point;
/** The separator for groups of digits before the decimal-point in
* formatted monetary quantities.
**/
char* mon_thousands_sep;
/** A string whose elements indicate the size of each group of digits
* in formatted monetary quantities.
**/
char* mon_grouping;
/** The string used to indicate a nonnegative-valued formatted
* monetary quantity.
**/
char* positive_sign;
/** The string used to indicate a negative-valued formatted monetary
* quantity.
**/
char* negative_sign;
/** The number of fractional digits (those after the decimal-point) to
* be displayed in an internationally formatted monetary quantity.
**/
char int_frac_digits;
/** The number of fractional digits (those after the decimal-point) to
* be displayed in a locally formatted monetary quantity.
**/
char frac_digits;
/// 1 if currency_symbol precedes a positive value, 0 if succeeds.
char p_cs_precedes;
/// 1 if a space separates currency_symbol from a positive value.
char p_sep_by_space;
/// 1 if currency_symbol precedes a negative value, 0 if succeeds.
char n_cs_precedes;
/// 1 if a space separates currency_symbol from a negative value.
char n_sep_by_space;
/* Positive and negative sign positions:
0 Parentheses surround the quantity and currency_symbol.
1 The sign string precedes the quantity and currency_symbol.
2 The sign string follows the quantity and currency_symbol.
3 The sign string immediately precedes the currency_symbol.
4 The sign string immediately follows the currency_symbol. */
char p_sign_posn;
char n_sign_posn;
/// 1 if int_curr_symbol precedes a positive value, 0 if succeeds.
char int_p_cs_precedes;
/// 1 iff a space separates int_curr_symbol from a positive value.
char int_p_sep_by_space;
/// 1 if int_curr_symbol precedes a negative value, 0 if succeeds.
char int_n_cs_precedes;
/// 1 iff a space separates int_curr_symbol from a negative value.
char int_n_sep_by_space;
/* Positive and negative sign positions:
0 Parentheses surround the quantity and int_curr_symbol.
1 The sign string precedes the quantity and int_curr_symbol.
2 The sign string follows the quantity and int_curr_symbol.
3 The sign string immediately precedes the int_curr_symbol.
4 The sign string immediately follows the int_curr_symbol. */
char int_p_sign_posn;
char int_n_sign_posn;
}
/** Affects the behavior of C's character handling functions and C's multibyte
* and wide character functions.
**/
const LC_CTYPE = 0;
/** Affects the decimal-point character for C's formatted input/output functions
* and C's string conversion functions, as well as C's nonmonetary formatting
* information returned by the localeconv function.
**/
const LC_NUMERIC = 1;
/// Affects the behavior of the strftime and wcsftime functions.
const LC_TIME = 2;
/// Affects the behavior of the strcoll and strxfrm functions.
const LC_COLLATE = 3;
/** Affects the monetary formatting information returned by the localeconv
* function.
**/
const LC_MONETARY = 4;
/// The program's entire locale.
const LC_ALL = 6;
/** The setlocale function selects the appropriate portion of the program's
* locale as specified by the category and locale arguments.
**/
char* setlocale(int category, char* locale);
/** The localeconv function sets the components of an object with type
* lconv with values appropriate for the formatting of numeric quantities
* (monetary and otherwise) according to the rules of the current locale.
**/
lconv* localeconv();

View File

@@ -1,291 +0,0 @@
/**
* C's &lt;math.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCMath
*/
module std.c.math;
extern (C):
alias float float_t; ///
alias double double_t; ///
const double HUGE_VAL = double.infinity; ///
const float HUGE_VALF = float.infinity; /// ditto
const real HUGE_VALL = real.infinity; /// ditto
const float INFINITY = float.infinity; ///
const float NAN = float.nan; ///
enum
{
FP_NANS, // extension
FP_NANQ, // extension
FP_INFINITE, ///
FP_NAN = FP_NANQ, ///
FP_NORMAL = 3, ///
FP_SUBNORMAL = 4, ///
FP_ZERO = 5, ///
FP_EMPTY = 6, // extension
FP_UNSUPPORTED = 7, // extension
}
enum
{
FP_FAST_FMA = 0, ///
FP_FAST_FMAF = 0, ///
FP_FAST_FMAL = 0, ///
}
const int FP_ILOGB0 = int.min; ///
const int FP_ILOGBNAN = int.min; ///
const int MATH_ERRNO = 1; ///
const int MATH_ERREXCEPT = 2; ///
const int math_errhandling = MATH_ERRNO | MATH_ERREXCEPT; ///
double acos(double x); ///
float acosf(float x); /// ditto
real acosl(real x); /// ditto
double asin(double x); ///
float asinf(float x); /// ditto
real asinl(real x); /// ditto
double atan(double x); ///
float atanf(float x); /// ditto
real atanl(real x); /// ditto
double atan2(double y, double x); ///
float atan2f(float y, float x); /// ditto
real atan2l(real y, real x); /// ditto
double cos(double x); ///
float cosf(float x); /// ditto
real cosl(real x); /// ditto
double sin(double x); ///
float sinf(float x); /// ditto
real sinl(real x); /// ditto
double tan(double x); ///
float tanf(float x); /// ditto
real tanl(real x); /// ditto
double acosh(double x); ///
float acoshf(float x); /// ditto
real acoshl(real x); /// ditto
double asinh(double x); ///
float asinhf(float x); /// ditto
real asinhl(real x); /// ditto
double atanh(double x); ///
float atanhf(float x); /// ditto
real atanhl(real x); /// ditto
double cosh(double x); ///
float coshf(float x); /// ditto
real coshl(real x); /// ditto
double sinh(double x); ///
float sinhf(float x); /// ditto
real sinhl(real x); /// ditto
double tanh(double x); ///
float tanhf(float x); /// ditto
real tanhl(real x); /// ditto
double exp(double x); ///
float expf(float x); /// ditto
real expl(real x); /// ditto
double exp2(double x); ///
float exp2f(float x); /// ditto
real exp2l(real x); /// ditto
double expm1(double x); ///
float expm1f(float x); /// ditto
real expm1l(real x); /// ditto
double frexp(double value, int *exp); ///
float frexpf(float value, int *exp); /// ditto
real frexpl(real value, int *exp); /// ditto
int ilogb(double x); ///
int ilogbf(float x); /// ditto
int ilogbl(real x); /// ditto
double ldexp(double x, int exp); ///
float ldexpf(float x, int exp); /// ditto
real ldexpl(real x, int exp); /// ditto
double log(double x); ///
float logf(float x); /// ditto
real logl(real x); /// ditto
double log10(double x); ///
float log10f(float x); /// ditto
real log10l(real x); /// ditto
double log1p(double x); ///
float log1pf(float x); /// ditto
real log1pl(real x); /// ditto
double log2(double x); ///
float log2f(float x); /// ditto
real log2l(real x); /// ditto
double logb(double x); ///
float logbf(float x); /// ditto
real logbl(real x); /// ditto
double modf(double value, double *iptr); ///
float modff(float value, float *iptr); /// ditto
real modfl(real value, real *iptr); /// ditto
double scalbn(double x, int n); ///
float scalbnf(float x, int n); /// ditto
real scalbnl(real x, int n); /// ditto
double scalbln(double x, int n); ///
float scalblnf(float x, int n); /// ditto
real scalblnl(real x, int n); /// ditto
double cbrt(double x); ///
float cbrtf(float x); /// ditto
real cbrtl(real x); /// ditto
double fabs(double x); ///
float fabsf(float x); /// ditto
real fabsl(real x); /// ditto
double hypot(double x, double y); ///
float hypotf(float x, float y); /// ditto
real hypotl(real x, real y); /// ditto
double pow(double x, double y); ///
float powf(float x, float y); /// ditto
real powl(real x, real y); /// ditto
double sqrt(double x); ///
float sqrtf(float x); /// ditto
real sqrtl(real x); /// ditto
double erf(double x); ///
float erff(float x); /// ditto
real erfl(real x); /// ditto
double erfc(double x); ///
float erfcf(float x); /// ditto
real erfcl(real x); /// ditto
double lgamma(double x); ///
float lgammaf(float x); /// ditto
real lgammal(real x); /// ditto
double tgamma(double x); ///
float tgammaf(float x); /// ditto
real tgammal(real x); /// ditto
double ceil(double x); ///
float ceilf(float x); /// ditto
real ceill(real x); /// ditto
double floor(double x); ///
float floorf(float x); /// ditto
real floorl(real x); /// ditto
double nearbyint(double x); ///
float nearbyintf(float x); /// ditto
real nearbyintl(real x); /// ditto
double rint(double x); ///
float rintf(float x); /// ditto
real rintl(real x); /// ditto
int lrint(double x); ///
int lrintf(float x); /// ditto
int lrintl(real x); /// ditto
long llrint(double x); ///
long llrintf(float x); /// ditto
long llrintl(real x); /// ditto
double round(double x); ///
float roundf(float x); /// ditto
real roundl(real x); /// ditto
int lround(double x); ///
int lroundf(float x); /// ditto
int lroundl(real x); /// ditto
long llround(double x); ///
long llroundf(float x); /// ditto
long llroundl(real x); /// ditto
double trunc(double x); ///
float truncf(float x); /// ditto
real truncl(real x); /// ditto
double fmod(double x, double y); ///
float fmodf(float x, float y); /// ditto
real fmodl(real x, real y); /// ditto
double remainder(double x, double y); ///
float remainderf(float x, float y); /// ditto
real remainderl(real x, real y); /// ditto
double remquo(double x, double y, int *quo); ///
float remquof(float x, float y, int *quo); /// ditto
real remquol(real x, real y, int *quo); /// ditto
double copysign(double x, double y); ///
float copysignf(float x, float y); /// ditto
real copysignl(real x, real y); /// ditto
double nan(char *tagp); ///
float nanf(char *tagp); /// ditto
real nanl(char *tagp); /// ditto
double nextafter(double x, double y); ///
float nextafterf(float x, float y); /// ditto
real nextafterl(real x, real y); /// ditto
double nexttoward(double x, real y); ///
float nexttowardf(float x, real y); /// ditto
real nexttowardl(real x, real y); /// ditto
double fdim(double x, double y); ///
float fdimf(float x, float y); /// ditto
real fdiml(real x, real y); /// ditto
double fmax(double x, double y); ///
float fmaxf(float x, float y); /// ditto
real fmaxl(real x, real y); /// ditto
double fmin(double x, double y); ///
float fminf(float x, float y); /// ditto
real fminl(real x, real y); /// ditto
double fma(double x, double y, double z); ///
float fmaf(float x, float y, float z); /// ditto
real fmal(real x, real y, real z); /// ditto
///
int isgreater(real x, real y) { return !(x !> y); }
///
int isgreaterequal(real x, real y) { return !(x !>= y); }
///
int isless(real x, real y) { return !(x !< y); }
///
int islessequal(real x, real y) { return !(x !<= y); }
///
int islessgreater(real x, real y) { return !(x !<> y); }
///
int isunordered(real x, real y) { return (x !<>= y); }

View File

@@ -1,86 +0,0 @@
/**
* C's &lt;process.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCProcess
*/
module std.c.process;
private import std.c.stddef;
extern (C):
void exit(int);
void _c_exit();
void _cexit();
void _exit(int);
void abort();
void _dodtors();
int getpid();
int system(char *);
enum { _P_WAIT, _P_NOWAIT, _P_OVERLAY };
int execl(char *, char *,...);
int execle(char *, char *,...);
int execlp(char *, char *,...);
int execlpe(char *, char *,...);
int execv(char *, char **);
int execve(char *, char **, char **);
int execvp(char *, char **);
int execvpe(char *, char **, char **);
enum { WAIT_CHILD, WAIT_GRANDCHILD }
int cwait(int *,int,int);
int wait(int *);
version (Windows)
{
uint _beginthread(void function(void *),uint,void *);
extern (Windows) alias uint (*stdfp)(void *);
uint _beginthreadex(void* security, uint stack_size,
stdfp start_addr, void* arglist, uint initflag,
uint* thrdaddr);
void _endthread();
void _endthreadex(uint);
int spawnl(int, char *, char *,...);
int spawnle(int, char *, char *,...);
int spawnlp(int, char *, char *,...);
int spawnlpe(int, char *, char *,...);
int spawnv(int, char *, char **);
int spawnve(int, char *, char **, char **);
int spawnvp(int, char *, char **);
int spawnvpe(int, char *, char **, char **);
int _wsystem(wchar_t *);
int _wspawnl(int, wchar_t *, wchar_t *, ...);
int _wspawnle(int, wchar_t *, wchar_t *, ...);
int _wspawnlp(int, wchar_t *, wchar_t *, ...);
int _wspawnlpe(int, wchar_t *, wchar_t *, ...);
int _wspawnv(int, wchar_t *, wchar_t **);
int _wspawnve(int, wchar_t *, wchar_t **, wchar_t **);
int _wspawnvp(int, wchar_t *, wchar_t **);
int _wspawnvpe(int, wchar_t *, wchar_t **, wchar_t **);
int _wexecl(wchar_t *, wchar_t *, ...);
int _wexecle(wchar_t *, wchar_t *, ...);
int _wexeclp(wchar_t *, wchar_t *, ...);
int _wexeclpe(wchar_t *, wchar_t *, ...);
int _wexecv(wchar_t *, wchar_t **);
int _wexecve(wchar_t *, wchar_t **, wchar_t **);
int _wexecvp(wchar_t *, wchar_t **);
int _wexecvpe(wchar_t *, wchar_t **, wchar_t **);
}

View File

@@ -1,26 +0,0 @@
/**
* C's &lt;stdarg.h&gt;
* Authors: Hauke Duden, Walter Bright and Tomas Lindquist Olsen, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCStdarg
*/
/* This is for use with extern(C) variable argument lists. */
module std.c.stdarg;
public import llvm.va_list;
pragma(va_start)
void va_start(T)(va_list ap, ref T);
pragma(va_arg)
T va_arg(T)(va_list ap);
pragma(va_end)
void va_end(va_list args);
pragma(va_copy)
void va_copy(va_list dst, va_list src);

View File

@@ -1,23 +0,0 @@
/**
* C's &lt;stddef.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCStddef
*/
module std.c.stddef;
version (Win32)
{
alias wchar wchar_t;
}
else version (linux)
{
alias dchar wchar_t;
}
else
{
static assert(0);
}

View File

@@ -1,300 +0,0 @@
/**
* C's &lt;stdio.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCStdio
*/
module std.c.stdio;
import std.c.stddef;
private import std.c.stdarg;
extern (C):
version (Win32)
{
const int _NFILE = 60; ///
const int BUFSIZ = 0x4000; ///
const int EOF = -1; ///
const int FOPEN_MAX = 20; ///
const int FILENAME_MAX = 256; /// 255 plus NULL
const int TMP_MAX = 32767; ///
const int _SYS_OPEN = 20; ///
const int SYS_OPEN = _SYS_OPEN; ///
const wchar WEOF = 0xFFFF; ///
}
version (linux)
{
const int EOF = -1;
const int FOPEN_MAX = 16;
const int FILENAME_MAX = 4095;
const int TMP_MAX = 238328;
const int L_tmpnam = 20;
}
enum { SEEK_SET, SEEK_CUR, SEEK_END }
struct _iobuf
{
align (1):
version (Win32)
{
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
int __tmpnum;
}
version (linux)
{
char* _read_ptr;
char* _read_end;
char* _read_base;
char* _write_base;
char* _write_ptr;
char* _write_end;
char* _buf_base;
char* _buf_end;
char* _save_base;
char* _backup_base;
char* _save_end;
void* _markers;
_iobuf* _chain;
int _fileno;
int _blksize;
int _old_offset;
ushort _cur_column;
byte _vtable_offset;
char[1] _shortbuf;
void* _lock;
}
}
alias _iobuf FILE; ///
enum
{
_F_RDWR = 0x0003,
_F_READ = 0x0001,
_F_WRIT = 0x0002,
_F_BUF = 0x0004,
_F_LBUF = 0x0008,
_F_ERR = 0x0010,
_F_EOF = 0x0020,
_F_BIN = 0x0040,
_F_IN = 0x0080,
_F_OUT = 0x0100,
_F_TERM = 0x0200,
}
version (Win32)
{
extern FILE _iob[_NFILE];
extern void function() _fcloseallp;
extern ubyte __fhnd_info[_NFILE];
enum
{
FHND_APPEND = 0x04,
FHND_DEVICE = 0x08,
FHND_TEXT = 0x10,
FHND_BYTE = 0x20,
FHND_WCHAR = 0x40,
}
}
version (Win32)
{
enum
{
_IOREAD = 1,
_IOWRT = 2,
_IONBF = 4,
_IOMYBUF = 8,
_IOEOF = 0x10,
_IOERR = 0x20,
_IOLBF = 0x40,
_IOSTRG = 0x40,
_IORW = 0x80,
_IOFBF = 0,
_IOAPP = 0x200,
_IOTRAN = 0x100,
}
}
version (linux)
{
enum
{
_IOFBF = 0,
_IOLBF = 1,
_IONBF = 2,
}
}
version (Win32)
{
const FILE *stdin = &_iob[0]; ///
const FILE *stdout = &_iob[1]; ///
const FILE *stderr = &_iob[2]; ///
const FILE *stdaux = &_iob[3]; ///
const FILE *stdprn = &_iob[4]; ///
}
version (linux)
{
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
}
version (Win32)
{
const char[] _P_tmpdir = "\\";
const wchar[] _wP_tmpdir = "\\";
const int L_tmpnam = _P_tmpdir.length + 12;
}
alias int fpos_t; ///
char * tmpnam(char *); ///
FILE * fopen(char *,char *); ///
FILE * _fsopen(char *,char *,int ); ///
FILE * freopen(char *,char *,FILE *); ///
int fseek(FILE *,int,int); ///
int ftell(FILE *); ///
char * fgets(char *,int,FILE *); ///
int fgetc(FILE *); ///
int _fgetchar(); ///
int fflush(FILE *); ///
int fclose(FILE *); ///
int fputs(char *,FILE *); ///
char * gets(char *); ///
int fputc(int,FILE *); ///
int _fputchar(int); ///
int puts(char *); ///
int ungetc(int,FILE *); ///
size_t fread(void *,size_t,size_t,FILE *); ///
size_t fwrite(void *,size_t,size_t,FILE *); ///
//int printf(char *,...); ///
int fprintf(FILE *,char *,...); ///
int vfprintf(FILE *,char *,va_list); ///
int vprintf(char *,va_list); ///
int sprintf(char *,char *,...); ///
int vsprintf(char *,char *,va_list); ///
int scanf(char *,...); ///
int fscanf(FILE *,char *,...); ///
int sscanf(char *,char *,...); ///
void setbuf(FILE *,char *); ///
int setvbuf(FILE *,char *,int,size_t); ///
int remove(char *); ///
int rename(char *,char *); ///
void perror(char *); ///
int fgetpos(FILE *,fpos_t *); ///
int fsetpos(FILE *,fpos_t *); ///
FILE * tmpfile(); ///
int _rmtmp();
int _fillbuf(FILE *);
int _flushbu(int, FILE *);
int getw(FILE *FHdl); ///
int putw(int Word, FILE *FilePtr); ///
///
int getchar() { return getc(stdin); }
///
int putchar(int c) { return putc(c,stdout); }
///
int getc(FILE *fp) { return fgetc(fp); }
///
int putc(int c,FILE *fp) { return fputc(c,fp); }
version (Win32)
{
///
int ferror(FILE *fp) { return fp._flag&_IOERR; }
///
int feof(FILE *fp) { return fp._flag&_IOEOF; }
///
void clearerr(FILE *fp) { fp._flag &= ~(_IOERR|_IOEOF); }
///
void rewind(FILE *fp) { fseek(fp,0L,SEEK_SET); fp._flag&=~_IOERR; }
int _bufsize(FILE *fp) { return fp._bufsiz; }
///
int fileno(FILE *fp) { return fp._file; }
int _snprintf(char *,size_t,char *,...);
int _vsnprintf(char *,size_t,char *,va_list);
}
version (linux)
{
int ferror(FILE *fp);
int feof(FILE *fp);
void clearerr(FILE *fp);
void rewind(FILE *fp);
int _bufsize(FILE *fp);
int fileno(FILE *fp);
int snprintf(char *,size_t,char *,...);
int vsnprintf(char *,size_t,char *,va_list);
}
int unlink(char *); ///
FILE * fdopen(int, char *); ///
int fgetchar(); ///
int fputchar(int); ///
int fcloseall(); ///
int filesize(char *); ///
int flushall(); ///
int getch(); ///
int getche(); ///
int kbhit(); ///
char * tempnam (char *dir, char *pfx); ///
wchar_t * _wtmpnam(wchar_t *); ///
FILE * _wfopen(wchar_t *, wchar_t *);
FILE * _wfsopen(wchar_t *, wchar_t *, int);
FILE * _wfreopen(wchar_t *, wchar_t *, FILE *);
wchar_t * fgetws(wchar_t *, int, FILE *); ///
int fputws(wchar_t *, FILE *); ///
wchar_t * _getws(wchar_t *);
int _putws(wchar_t *);
int wprintf(wchar_t *, ...); ///
int fwprintf(FILE *, wchar_t *, ...); ///
int vwprintf(wchar_t *, va_list); ///
int vfwprintf(FILE *, wchar_t *, va_list); ///
int swprintf(wchar_t *, wchar_t *, ...); ///
int vswprintf(wchar_t *, wchar_t *, va_list); ///
int _snwprintf(wchar_t *, size_t, wchar_t *, ...);
int _vsnwprintf(wchar_t *, size_t, wchar_t *, va_list);
int wscanf(wchar_t *, ...); ///
int fwscanf(FILE *, wchar_t *, ...); ///
int swscanf(wchar_t *, wchar_t *, ...); ///
int _wremove(wchar_t *);
void _wperror(wchar_t *);
FILE * _wfdopen(int, wchar_t *);
wchar_t * _wtempnam(wchar_t *, wchar_t *);
wchar_t fgetwc(FILE *); ///
wchar_t _fgetwchar_t();
wchar_t fputwc(wchar_t, FILE *); ///
wchar_t _fputwchar_t(wchar_t);
wchar_t ungetwc(wchar_t, FILE *); ///
///
wchar_t getwchar_t() { return fgetwc(stdin); }
///
wchar_t putwchar_t(wchar_t c) { return fputwc(c,stdout); }
///
wchar_t getwc(FILE *fp) { return fgetwc(fp); }
///
wchar_t putwc(wchar_t c, FILE *fp) { return fputwc(c, fp); }
int fwide(FILE* fp, int mode); ///

View File

@@ -1,94 +0,0 @@
/**
* C's &lt;stdlib.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCStdlib
*/
module std.c.stdlib;
private import std.c.stddef;
extern (C):
enum
{
_MAX_PATH = 260,
_MAX_DRIVE = 3,
_MAX_DIR = 256,
_MAX_FNAME = 256,
_MAX_EXT = 256,
}
///
struct div_t { int quot,rem; }
///
struct ldiv_t { int quot,rem; }
///
struct lldiv_t { long quot,rem; }
div_t div(int,int); ///
ldiv_t ldiv(int,int); /// ditto
lldiv_t lldiv(long, long); /// ditto
const int EXIT_SUCCESS = 0; ///
const int EXIT_FAILURE = 1; /// ditto
int atexit(void (*)()); ///
void exit(int); /// ditto
void _exit(int); /// ditto
int system(char *);
pragma(alloca)
void *alloca(uint); ///
void *calloc(size_t, size_t); ///
void *malloc(size_t); /// ditto
void *realloc(void *, size_t); /// ditto
void free(void *); /// ditto
void *bsearch(void *,void *,size_t,size_t,
int function(void *,void *)); ///
void qsort(void *base, size_t nelems, size_t elemsize,
int (*compare)(void *elem1, void *elem2)); /// ditto
char* getenv(char*); ///
int setenv(char*, char*, int); /// extension to ISO C standard, not available on all platforms
void unsetenv(char*); /// extension to ISO C standard, not available on all platforms
int rand(); ///
void srand(uint); /// ditto
int random(int num); /// ditto
void randomize(); /// ditto
int* __errno_location();
int getErrno() { return *__errno_location(); }
int setErrno(int i) { return *__errno_location = i; }
//int getErrno(); /// ditto
//int setErrno(int); /// ditto
const int ERANGE = 34; // on both Windows and linux
double atof(char *); ///
int atoi(char *); /// ditto
int atol(char *); /// ditto
float strtof(char *,char **); /// ditto
double strtod(char *,char **); /// ditto
real strtold(char *,char **); /// ditto
long strtol(char *,char **,int); /// ditto
uint strtoul(char *,char **,int); /// ditto
long atoll(char *); /// ditto
long strtoll(char *,char **,int); /// ditto
ulong strtoull(char *,char **,int); /// ditto
char* itoa(int, char*, int); ///
char* ultoa(uint, char*, int); /// ditto
int mblen(char *s, size_t n); ///
int mbtowc(wchar_t *pwc, char *s, size_t n); /// ditto
int wctomb(char *s, wchar_t wc); /// ditto
size_t mbstowcs(wchar_t *pwcs, char *s, size_t n); /// ditto
size_t wcstombs(char *s, wchar_t *pwcs, size_t n); /// ditto

View File

@@ -1,40 +0,0 @@
/**
* C's &lt;string.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCString
*/
module std.c.string;
extern (C):
void* memcpy(void* s1, void* s2, size_t n); ///
void* memmove(void* s1, void* s2, size_t n); ///
char* strcpy(char* s1, char* s2); ///
char* strncpy(char* s1, char* s2, size_t n); ///
char* strncat(char* s1, char* s2, size_t n); ///
int strcoll(char* s1, char* s2); ///
int strncmp(char* s1, char* s2, size_t n); ///
size_t strxfrm(char* s1, char* s2, size_t n); ///
void* memchr(void* s, int c, size_t n); ///
char* strchr(char* s, int c); ///
size_t strcspn(char* s1, char* s2); ///
char* strpbrk(char* s1, char* s2); ///
char* strrchr(char* s, int c); ///
size_t strspn(char* s1, char* s2); ///
char* strstr(char* s1, char* s2); ///
char* strtok(char* s1, char* s2); ///
void* memset(void* s, int c, size_t n); ///
char* strerror(int errnum); ///
size_t strlen(char* s); ///
int strcmp(char* s1, char* s2); ///
char* strcat(char* s1, char* s2); ///
int memcmp(void* s1, void* s2, size_t n); ///
version (Windows)
{
int memicmp(char* s1, char* s2, size_t n); ///
}

View File

@@ -1,94 +0,0 @@
/**
* C's &lt;time.h&gt;
* Authors: Walter Bright, Digital Mars, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCTime
*/
module std.c.time;
private import std.c.stddef;
extern (C):
alias int clock_t;
version (Windows)
{ const clock_t CLOCKS_PER_SEC = 1000;
}
else version (linux)
{ const clock_t CLOCKS_PER_SEC = 1000000;
}
else version (darwin)
{
const clock_t CLOCKS_PER_SEC = 100;
}
else
{
static assert(0);
}
version (Windows)
{
const clock_t CLK_TCK = 1000;
}
else version (linux)
{
extern (C) int sysconf(int);
extern clock_t CLK_TCK;
/*static this()
{
CLK_TCK = cast(clock_t) sysconf(2);
}*/
}
else
{
static assert(0);
}
const uint TIMEOFFSET = 315558000;
alias int time_t;
extern int daylight;
extern int timezone;
extern int altzone;
extern char *tzname[2];
struct tm
{ int tm_sec,
tm_min,
tm_hour,
tm_mday,
tm_mon,
tm_year,
tm_wday,
tm_yday,
tm_isdst;
}
clock_t clock();
time_t time(time_t *);
time_t mktime(tm *);
char *asctime(tm *);
char *ctime(time_t *);
tm *localtime(time_t *);
tm *gmtime(time_t *);
size_t strftime(char *, size_t, char *, tm *);
char *_strdate(char *dstring);
char *_strtime(char *timestr);
double difftime(time_t t1, time_t t2);
void _tzset();
void tzset();
void sleep(time_t);
void usleep(uint);
void msleep(uint);
wchar_t *_wasctime(tm *);
wchar_t *_wctime(time_t *);
size_t wcsftime(wchar_t *, size_t, wchar_t *, tm *);
wchar_t *_wstrdate(wchar_t *);
wchar_t *_wstrtime(wchar_t *);

View File

@@ -1,246 +0,0 @@
module std.c.windows.com;
private import std.c.windows.windows;
private import std.string;
alias WCHAR OLECHAR;
alias OLECHAR *LPOLESTR;
alias OLECHAR *LPCOLESTR;
enum
{
rmm = 23, // OLE 2 version number info
rup = 639,
}
enum : int
{
S_OK = 0,
S_FALSE = 0x00000001,
NOERROR = 0,
E_NOTIMPL = cast(int)0x80004001,
E_NOINTERFACE = cast(int)0x80004002,
E_POINTER = cast(int)0x80004003,
E_ABORT = cast(int)0x80004004,
E_FAIL = cast(int)0x80004005,
E_HANDLE = cast(int)0x80070006,
CLASS_E_NOAGGREGATION = cast(int)0x80040110,
E_OUTOFMEMORY = cast(int)0x8007000E,
E_INVALIDARG = cast(int)0x80070057,
E_UNEXPECTED = cast(int)0x8000FFFF,
}
struct GUID { // size is 16
align(1):
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
}
enum
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_INPROC_SERVER16 = 0x8,
CLSCTX_REMOTE_SERVER = 0x10,
CLSCTX_INPROC_HANDLER16 = 0x20,
CLSCTX_INPROC_SERVERX86 = 0x40,
CLSCTX_INPROC_HANDLERX86 = 0x80,
CLSCTX_INPROC = (CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER),
CLSCTX_ALL = (CLSCTX_INPROC_SERVER| CLSCTX_INPROC_HANDLER| CLSCTX_LOCAL_SERVER),
CLSCTX_SERVER = (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER),
}
alias GUID IID;
alias GUID CLSID;
extern (C)
{
extern IID IID_IUnknown;
extern IID IID_IClassFactory;
extern IID IID_IMarshal;
extern IID IID_IMallocSpy;
extern IID IID_IStdMarshalInfo;
extern IID IID_IExternalConnection;
extern IID IID_IMultiQI;
extern IID IID_IEnumUnknown;
extern IID IID_IBindCtx;
extern IID IID_IEnumMoniker;
extern IID IID_IRunnableObject;
extern IID IID_IRunningObjectTable;
extern IID IID_IPersist;
extern IID IID_IPersistStream;
extern IID IID_IMoniker;
extern IID IID_IROTData;
extern IID IID_IEnumString;
extern IID IID_ISequentialStream;
extern IID IID_IStream;
extern IID IID_IEnumSTATSTG;
extern IID IID_IStorage;
extern IID IID_IPersistFile;
extern IID IID_IPersistStorage;
extern IID IID_ILockBytes;
extern IID IID_IEnumFORMATETC;
extern IID IID_IEnumSTATDATA;
extern IID IID_IRootStorage;
extern IID IID_IAdviseSink;
extern IID IID_IAdviseSink2;
extern IID IID_IDataObject;
extern IID IID_IDataAdviseHolder;
extern IID IID_IMessageFilter;
extern IID IID_IRpcChannelBuffer;
extern IID IID_IRpcProxyBuffer;
extern IID IID_IRpcStubBuffer;
extern IID IID_IPSFactoryBuffer;
extern IID IID_IPropertyStorage;
extern IID IID_IPropertySetStorage;
extern IID IID_IEnumSTATPROPSTG;
extern IID IID_IEnumSTATPROPSETSTG;
extern IID IID_IFillLockBytes;
extern IID IID_IProgressNotify;
extern IID IID_ILayoutStorage;
extern IID GUID_NULL;
extern IID IID_IRpcChannel;
extern IID IID_IRpcStub;
extern IID IID_IStubManager;
extern IID IID_IRpcProxy;
extern IID IID_IProxyManager;
extern IID IID_IPSFactory;
extern IID IID_IInternalMoniker;
extern IID IID_IDfReserved1;
extern IID IID_IDfReserved2;
extern IID IID_IDfReserved3;
extern IID IID_IStub;
extern IID IID_IProxy;
extern IID IID_IEnumGeneric;
extern IID IID_IEnumHolder;
extern IID IID_IEnumCallback;
extern IID IID_IOleManager;
extern IID IID_IOlePresObj;
extern IID IID_IDebug;
extern IID IID_IDebugStream;
extern IID IID_StdOle;
extern IID IID_ICreateTypeInfo;
extern IID IID_ICreateTypeInfo2;
extern IID IID_ICreateTypeLib;
extern IID IID_ICreateTypeLib2;
extern IID IID_IDispatch;
extern IID IID_IEnumVARIANT;
extern IID IID_ITypeComp;
extern IID IID_ITypeInfo;
extern IID IID_ITypeInfo2;
extern IID IID_ITypeLib;
extern IID IID_ITypeLib2;
extern IID IID_ITypeChangeEvents;
extern IID IID_IErrorInfo;
extern IID IID_ICreateErrorInfo;
extern IID IID_ISupportErrorInfo;
extern IID IID_IOleAdviseHolder;
extern IID IID_IOleCache;
extern IID IID_IOleCache2;
extern IID IID_IOleCacheControl;
extern IID IID_IParseDisplayName;
extern IID IID_IOleContainer;
extern IID IID_IOleClientSite;
extern IID IID_IOleObject;
extern IID IID_IOleWindow;
extern IID IID_IOleLink;
extern IID IID_IOleItemContainer;
extern IID IID_IOleInPlaceUIWindow;
extern IID IID_IOleInPlaceActiveObject;
extern IID IID_IOleInPlaceFrame;
extern IID IID_IOleInPlaceObject;
extern IID IID_IOleInPlaceSite;
extern IID IID_IContinue;
extern IID IID_IViewObject;
extern IID IID_IViewObject2;
extern IID IID_IDropSource;
extern IID IID_IDropTarget;
extern IID IID_IEnumOLEVERB;
}
extern (Windows)
{
export
{
DWORD CoBuildVersion();
int StringFromGUID2(GUID *rguid, LPOLESTR lpsz, int cbMax);
/* init/uninit */
HRESULT CoInitialize(LPVOID pvReserved);
void CoUninitialize();
DWORD CoGetCurrentProcess();
HRESULT CoCreateInstance(CLSID *rclsid, IUnknown UnkOuter,
DWORD dwClsContext, IID* riid, void* ppv);
//HINSTANCE CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree);
void CoFreeLibrary(HINSTANCE hInst);
void CoFreeAllLibraries();
void CoFreeUnusedLibraries();
}
interface IUnknown
{
HRESULT QueryInterface(IID* riid, void** pvObject);
ULONG AddRef();
ULONG Release();
}
interface IClassFactory : IUnknown
{
HRESULT CreateInstance(IUnknown UnkOuter, IID* riid, void** pvObject);
HRESULT LockServer(BOOL fLock);
}
class ComObject : IUnknown
{
extern (Windows):
HRESULT QueryInterface(IID* riid, void** ppv)
{
if (*riid == IID_IUnknown)
{
*ppv = cast(void*)cast(IUnknown)this;
AddRef();
return S_OK;
}
else
{ *ppv = null;
return E_NOINTERFACE;
}
}
ULONG AddRef()
{
return InterlockedIncrement(&count);
}
ULONG Release()
{
LONG lRef = InterlockedDecrement(&count);
if (lRef == 0)
{
// free object
// If we delete this object, then the postinvariant called upon
// return from Release() will fail.
// Just let the GC reap it.
//delete this;
return 0;
}
return cast(ULONG)lRef;
}
LONG count = 0; // object reference count
}
}

View File

@@ -1,49 +0,0 @@
/// Placed into public domain
/// Author: Walter Bright
module std.c.windows.stat;
extern (C):
// linux version is in std.c.linux.linux
version (Windows)
{
const S_IFMT = 0xF000;
const S_IFDIR = 0x4000;
const S_IFCHR = 0x2000;
const S_IFIFO = 0x1000;
const S_IFREG = 0x8000;
const S_IREAD = 0x0100;
const S_IWRITE = 0x0080;
const S_IEXEC = 0x0040;
const S_IFBLK = 0x6000;
const S_IFNAM = 0x5000;
int S_ISREG(int m) { return (m & S_IFMT) == S_IFREG; }
int S_ISBLK(int m) { return (m & S_IFMT) == S_IFBLK; }
int S_ISNAM(int m) { return (m & S_IFMT) == S_IFNAM; }
int S_ISDIR(int m) { return (m & S_IFMT) == S_IFDIR; }
int S_ISCHR(int m) { return (m & S_IFMT) == S_IFCHR; }
struct struct_stat
{
short st_dev;
ushort st_ino;
ushort st_mode;
short st_nlink;
ushort st_uid;
ushort st_gid;
short st_rdev;
short dummy;
int st_size;
int st_atime;
int st_mtime;
int st_ctime;
}
int stat(char *, struct_stat *);
int fstat(int, struct_stat *);
int _wstat(wchar *, struct_stat *);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,540 +0,0 @@
/*
Written by Christopher E. Miller
Placed into public domain.
*/
module std.c.windows.winsock;
private import std.stdint;
private import std.c.windows.windows;
extern(Windows):
alias UINT SOCKET;
alias int socklen_t;
const SOCKET INVALID_SOCKET = cast(SOCKET)~0;
const int SOCKET_ERROR = -1;
const int WSADESCRIPTION_LEN = 256;
const int WSASYS_STATUS_LEN = 128;
struct WSADATA
{
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN + 1];
char szSystemStatus[WSASYS_STATUS_LEN + 1];
USHORT iMaxSockets;
USHORT iMaxUdpDg;
char* lpVendorInfo;
}
alias WSADATA* LPWSADATA;
const int IOCPARM_MASK = 0x7F;
const int IOC_IN = cast(int)0x80000000;
const int FIONBIO = cast(int)(IOC_IN | ((UINT.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
int WSACleanup();
SOCKET socket(int af, int type, int protocol);
int ioctlsocket(SOCKET s, int cmd, uint* argp);
int bind(SOCKET s, sockaddr* name, int namelen);
int connect(SOCKET s, sockaddr* name, int namelen);
int listen(SOCKET s, int backlog);
SOCKET accept(SOCKET s, sockaddr* addr, int* addrlen);
int closesocket(SOCKET s);
int shutdown(SOCKET s, int how);
int getpeername(SOCKET s, sockaddr* name, int* namelen);
int getsockname(SOCKET s, sockaddr* name, int* namelen);
int send(SOCKET s, void* buf, int len, int flags);
int sendto(SOCKET s, void* buf, int len, int flags, sockaddr* to, int tolen);
int recv(SOCKET s, void* buf, int len, int flags);
int recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, int* fromlen);
int getsockopt(SOCKET s, int level, int optname, void* optval, int* optlen);
int setsockopt(SOCKET s, int level, int optname, void* optval, int optlen);
uint inet_addr(char* cp);
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
char* inet_ntoa(in_addr ina);
hostent* gethostbyname(char* name);
hostent* gethostbyaddr(void* addr, int len, int type);
protoent* getprotobyname(char* name);
protoent* getprotobynumber(int number);
servent* getservbyname(char* name, char* proto);
servent* getservbyport(int port, char* proto);
int gethostname(char* name, int namelen);
int getaddrinfo(char* nodename, char* servname, addrinfo* hints, addrinfo** res);
void freeaddrinfo(addrinfo* ai);
int getnameinfo(sockaddr* sa, socklen_t salen, char* host, DWORD hostlen, char* serv, DWORD servlen, int flags);
enum: int
{
WSAEWOULDBLOCK = 10035,
WSAEINTR = 10004,
WSAHOST_NOT_FOUND = 11001,
}
int WSAGetLastError();
enum: int
{
AF_UNSPEC = 0,
AF_UNIX = 1,
AF_INET = 2,
AF_IMPLINK = 3,
AF_PUP = 4,
AF_CHAOS = 5,
AF_NS = 6,
AF_IPX = AF_NS,
AF_ISO = 7,
AF_OSI = AF_ISO,
AF_ECMA = 8,
AF_DATAKIT = 9,
AF_CCITT = 10,
AF_SNA = 11,
AF_DECnet = 12,
AF_DLI = 13,
AF_LAT = 14,
AF_HYLINK = 15,
AF_APPLETALK = 16,
AF_NETBIOS = 17,
AF_VOICEVIEW = 18,
AF_FIREFOX = 19,
AF_UNKNOWN1 = 20,
AF_BAN = 21,
AF_ATM = 22,
AF_INET6 = 23,
AF_CLUSTER = 24,
AF_12844 = 25,
AF_IRDA = 26,
AF_NETDES = 28,
AF_MAX = 29,
PF_UNSPEC = AF_UNSPEC,
PF_UNIX = AF_UNIX,
PF_INET = AF_INET,
PF_IMPLINK = AF_IMPLINK,
PF_PUP = AF_PUP,
PF_CHAOS = AF_CHAOS,
PF_NS = AF_NS,
PF_IPX = AF_IPX,
PF_ISO = AF_ISO,
PF_OSI = AF_OSI,
PF_ECMA = AF_ECMA,
PF_DATAKIT = AF_DATAKIT,
PF_CCITT = AF_CCITT,
PF_SNA = AF_SNA,
PF_DECnet = AF_DECnet,
PF_DLI = AF_DLI,
PF_LAT = AF_LAT,
PF_HYLINK = AF_HYLINK,
PF_APPLETALK = AF_APPLETALK,
PF_VOICEVIEW = AF_VOICEVIEW,
PF_FIREFOX = AF_FIREFOX,
PF_UNKNOWN1 = AF_UNKNOWN1,
PF_BAN = AF_BAN,
PF_INET6 = AF_INET6,
PF_MAX = AF_MAX,
}
enum: int
{
SOL_SOCKET = 0xFFFF,
}
enum: int
{
SO_DEBUG = 0x0001,
SO_ACCEPTCONN = 0x0002,
SO_REUSEADDR = 0x0004,
SO_KEEPALIVE = 0x0008,
SO_DONTROUTE = 0x0010,
SO_BROADCAST = 0x0020,
SO_USELOOPBACK = 0x0040,
SO_LINGER = 0x0080,
SO_DONTLINGER = ~SO_LINGER,
SO_OOBINLINE = 0x0100,
SO_SNDBUF = 0x1001,
SO_RCVBUF = 0x1002,
SO_SNDLOWAT = 0x1003,
SO_RCVLOWAT = 0x1004,
SO_SNDTIMEO = 0x1005,
SO_RCVTIMEO = 0x1006,
SO_ERROR = 0x1007,
SO_TYPE = 0x1008,
SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR,
TCP_NODELAY = 1,
IP_MULTICAST_LOOP = 0x4,
IP_ADD_MEMBERSHIP = 0x5,
IP_DROP_MEMBERSHIP = 0x6,
IPV6_UNICAST_HOPS = 4,
IPV6_MULTICAST_IF = 9,
IPV6_MULTICAST_HOPS = 10,
IPV6_MULTICAST_LOOP = 11,
IPV6_ADD_MEMBERSHIP = 12,
IPV6_DROP_MEMBERSHIP = 13,
IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP,
IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP,
}
const uint FD_SETSIZE = 64;
struct fd_set
{
UINT fd_count;
SOCKET[FD_SETSIZE] fd_array;
}
// Removes.
void FD_CLR(SOCKET fd, fd_set* set)
{
uint c = set.fd_count;
SOCKET* start = set.fd_array.ptr;
SOCKET* stop = start + c;
for(; start != stop; start++)
{
if(*start == fd)
goto found;
}
return; //not found
found:
for(++start; start != stop; start++)
{
*(start - 1) = *start;
}
set.fd_count = c - 1;
}
// Tests.
int FD_ISSET(SOCKET fd, fd_set* set)
{
SOCKET* start = set.fd_array.ptr;
SOCKET* stop = start + set.fd_count;
for(; start != stop; start++)
{
if(*start == fd)
return true;
}
return false;
}
// Adds.
void FD_SET(SOCKET fd, fd_set* set)
{
uint c = set.fd_count;
set.fd_array.ptr[c] = fd;
set.fd_count = c + 1;
}
// Resets to zero.
void FD_ZERO(fd_set* set)
{
set.fd_count = 0;
}
struct linger
{
USHORT l_onoff;
USHORT l_linger;
}
struct protoent
{
char* p_name;
char** p_aliases;
SHORT p_proto;
}
struct servent
{
char* s_name;
char** s_aliases;
SHORT s_port;
char* s_proto;
}
/+
union in6_addr
{
private union _u_t
{
BYTE[16] Byte;
WORD[8] Word;
}
_u_t u;
}
struct in_addr6
{
BYTE[16] s6_addr;
}
+/
version(BigEndian)
{
uint16_t htons(uint16_t x)
{
return x;
}
uint32_t htonl(uint32_t x)
{
return x;
}
}
else version(LittleEndian)
{
private import std.intrinsic;
uint16_t htons(uint16_t x)
{
return cast(uint16_t)((x >> 8) | (x << 8));
}
uint32_t htonl(uint32_t x)
{
return bswap(x);
}
}
else
{
static assert(0);
}
uint16_t ntohs(uint16_t x)
{
return htons(x);
}
uint32_t ntohl(uint32_t x)
{
return htonl(x);
}
enum: int
{
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
}
enum: int
{
IPPROTO_IP = 0,
IPPROTO_ICMP = 1,
IPPROTO_IGMP = 2,
IPPROTO_GGP = 3,
IPPROTO_TCP = 6,
IPPROTO_PUP = 12,
IPPROTO_UDP = 17,
IPPROTO_IDP = 22,
IPPROTO_IPV6 = 41,
IPPROTO_ND = 77,
IPPROTO_RAW = 255,
IPPROTO_MAX = 256,
}
enum: int
{
MSG_OOB = 0x1,
MSG_PEEK = 0x2,
MSG_DONTROUTE = 0x4,
MSG_NOSIGNAL = 0x0, /// not supported on win32, would be 0x4000 if it was
}
enum: int
{
SD_RECEIVE = 0,
SD_SEND = 1,
SD_BOTH = 2,
}
enum: uint
{
INADDR_ANY = 0,
INADDR_LOOPBACK = 0x7F000001,
INADDR_BROADCAST = 0xFFFFFFFF,
INADDR_NONE = 0xFFFFFFFF,
ADDR_ANY = INADDR_ANY,
}
enum: int
{
AI_PASSIVE = 0x1,
AI_CANONNAME = 0x2,
AI_NUMERICHOST = 0x4,
}
struct timeval
{
int32_t tv_sec;
int32_t tv_usec;
}
union in_addr
{
private union _S_un_t
{
private struct _S_un_b_t
{
uint8_t s_b1, s_b2, s_b3, s_b4;
}
_S_un_b_t S_un_b;
private struct _S_un_w_t
{
uint16_t s_w1, s_w2;
}
_S_un_w_t S_un_w;
uint32_t S_addr;
}
_S_un_t S_un;
uint32_t s_addr;
struct
{
uint8_t s_net, s_host;
union
{
uint16_t s_imp;
struct
{
uint8_t s_lh, s_impno;
}
}
}
}
union in6_addr
{
private union _in6_u_t
{
uint8_t[16] u6_addr8;
uint16_t[8] u6_addr16;
uint32_t[4] u6_addr32;
}
_in6_u_t in6_u;
uint8_t[16] s6_addr8;
uint16_t[8] s6_addr16;
uint32_t[4] s6_addr32;
alias s6_addr8 s6_addr;
}
const in6_addr IN6ADDR_ANY = { s6_addr8: [0] };
const in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
//alias IN6ADDR_ANY IN6ADDR_ANY_INIT;
//alias IN6ADDR_LOOPBACK IN6ADDR_LOOPBACK_INIT;
const uint INET_ADDRSTRLEN = 16;
const uint INET6_ADDRSTRLEN = 46;
struct sockaddr
{
int16_t sa_family;
ubyte[14] sa_data;
}
struct sockaddr_in
{
int16_t sin_family = AF_INET;
uint16_t sin_port;
in_addr sin_addr;
ubyte[8] sin_zero;
}
struct sockaddr_in6
{
int16_t sin6_family = AF_INET6;
uint16_t sin6_port;
uint32_t sin6_flowinfo;
in6_addr sin6_addr;
uint32_t sin6_scope_id;
}
struct addrinfo
{
int32_t ai_flags;
int32_t ai_family;
int32_t ai_socktype;
int32_t ai_protocol;
size_t ai_addrlen;
char* ai_canonname;
sockaddr* ai_addr;
addrinfo* ai_next;
}
struct hostent
{
char* h_name;
char** h_aliases;
int16_t h_addrtype;
int16_t h_length;
char** h_addr_list;
char* h_addr()
{
return h_addr_list[0];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,228 +0,0 @@
/**
* The std.cstream module bridges std.c.stdio (or std.stdio) and std.stream.
* Both std.c.stdio and std.stream are publicly imported by std.cstream.
* Authors: Ben Hinkle
* License: Public Domain
* Macros:
* WIKI=Phobos/StdCstream
*/
module std.cstream;
import std.stream;
import std.c.stdio;
/**
* A Stream wrapper for a C file of type FILE*.
*/
class CFile : Stream {
FILE* cfile;
/**
* Create the stream wrapper for the given C file.
* Params:
* mode = a bitwise combination of $(B FileMode.In) for a readable file
* and $(B FileMode.Out) for a writeable file.
* seekable = indicates if the stream should be _seekable.
*/
this(FILE* cfile, FileMode mode, bool seekable = false) {
super();
this.file = cfile;
readable = cast(bool)(mode & FileMode.In);
writeable = cast(bool)(mode & FileMode.Out);
this.seekable = seekable;
}
/**
* Closes the stream.
*/
~this() { close(); }
/**
* Property to get or set the underlying file for this stream.
* Setting the file marks the stream as open.
*/
FILE* file() { return cfile; }
/**
* Ditto
*/
void file(FILE* cfile) {
this.cfile = cfile;
isopen = true;
}
/**
* Overrides of the $(B Stream) methods to call the underlying $(B FILE*)
* C functions.
*/
override void flush() { fflush(cfile); }
/**
* Ditto
*/
override void close() {
if (isopen)
fclose(cfile);
isopen = readable = writeable = seekable = false;
}
/**
* Ditto
*/
override bool eof() {
return cast(bool)(readEOF || feof(cfile));
}
/**
* Ditto
*/
override char getc() {
return cast(char)fgetc(cfile);
}
/**
* Ditto
*/
override char ungetc(char c) {
return cast(char)std.c.stdio.ungetc(c,cfile);
}
/**
* Ditto
*/
override size_t readBlock(void* buffer, size_t size) {
size_t n = fread(buffer,1,size,cfile);
readEOF = cast(bool)(n == 0);
return n;
}
/**
* Ditto
*/
override size_t writeBlock(void* buffer, size_t size) {
return fwrite(buffer,1,size,cfile);
}
/**
* Ditto
*/
override ulong seek(long offset, SeekPos rel) {
readEOF = false;
if (fseek(cfile,cast(int)offset,rel) != 0)
throw new SeekException("unable to move file pointer");
return ftell(cfile);
}
/**
* Ditto
*/
override void writeLine(char[] s) {
writeString(s);
writeString("\n");
}
/**
* Ditto
*/
override void writeLineW(wchar[] s) {
writeStringW(s);
writeStringW("\n");
}
// run a few tests
unittest {
FILE* f = fopen("stream.txt","w");
assert(f !is null);
CFile file = new CFile(f,FileMode.Out);
int i = 666;
// should be ok to write
assert(file.writeable);
file.writeLine("Testing stream.d:");
file.writeString("Hello, world!");
file.write(i);
// string#1 + string#2 + int should give exacly that
version (Win32)
assert(file.position() == 19 + 13 + 4);
version (linux)
assert(file.position() == 18 + 13 + 4);
file.close();
// no operations are allowed when file is closed
assert(!file.readable && !file.writeable && !file.seekable);
f = fopen("stream.txt","r");
file = new CFile(f,FileMode.In,true);
// should be ok to read
assert(file.readable);
char[] line = file.readLine();
char[] exp = "Testing stream.d:";
assert(line[0] == 'T');
assert(line.length == exp.length);
assert(!std.string.cmp(line, "Testing stream.d:"));
// jump over "Hello, "
file.seek(7, SeekPos.Current);
version (Win32)
assert(file.position() == 19 + 7);
version (linux)
assert(file.position() == 18 + 7);
assert(!std.string.cmp(file.readString(6), "world!"));
i = 0; file.read(i);
assert(i == 666);
// string#1 + string#2 + int should give exacly that
version (Win32)
assert(file.position() == 19 + 13 + 4);
version (linux)
assert(file.position() == 18 + 13 + 4);
// we must be at the end of file
file.close();
f = fopen("stream.txt","w+");
file = new CFile(f,FileMode.In|FileMode.Out,true);
file.writeLine("Testing stream.d:");
file.writeLine("Another line");
file.writeLine("");
file.writeLine("That was blank");
file.position = 0;
char[][] lines;
foreach(char[] line; file) {
lines ~= line.dup;
}
assert( lines.length == 5 );
assert( lines[0] == "Testing stream.d:");
assert( lines[1] == "Another line");
assert( lines[2] == "");
assert( lines[3] == "That was blank");
file.position = 0;
lines = new char[][5];
foreach(ulong n, char[] line; file) {
lines[cast(size_t)(n-1)] = line.dup;
}
assert( lines[0] == "Testing stream.d:");
assert( lines[1] == "Another line");
assert( lines[2] == "");
assert( lines[3] == "That was blank");
file.close();
remove("stream.txt");
}
}
/**
* CFile wrapper of std.c.stdio.stdin (not seekable).
*/
CFile din;
/**
* CFile wrapper of std.c.stdio.stdout (not seekable).
*/
CFile dout;
/**
* CFile wrapper of std.c.stdio.stderr (not seekable).
*/
CFile derr;
static this() {
// open standard I/O devices
din = new CFile(std.c.stdio.stdin,FileMode.In);
dout = new CFile(std.c.stdio.stdout,FileMode.Out);
derr = new CFile(std.c.stdio.stderr,FileMode.Out);
}

View File

@@ -1,154 +0,0 @@
/*
* Placed into the Public Domain.
* Digital Mars, www.digitalmars.com
* Written by Walter Bright
*/
/**
* Simple ASCII character classification functions.
* For Unicode classification, see $(LINK2 std_uni.html, std.uni).
* References:
* $(LINK2 http://www.digitalmars.com/d/ascii-table.html, ASCII Table),
* $(LINK2 http://en.wikipedia.org/wiki/Ascii, Wikipedia)
* Macros:
* WIKI=Phobos/StdCtype
*/
module std.ctype;
/**
* Returns !=0 if c is a letter in the range (0..9, a..z, A..Z).
*/
int isalnum(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG) : 0; }
/**
* Returns !=0 if c is an ascii upper or lower case letter.
*/
int isalpha(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP) : 0; }
/**
* Returns !=0 if c is a control character.
*/
int iscntrl(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_CTL) : 0; }
/**
* Returns !=0 if c is a digit.
*/
int isdigit(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_DIG) : 0; }
/**
* Returns !=0 if c is lower case ascii letter.
*/
int islower(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_LC) : 0; }
/**
* Returns !=0 if c is a punctuation character.
*/
int ispunct(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_PNC) : 0; }
/**
* Returns !=0 if c is a space, tab, vertical tab, form feed,
* carriage return, or linefeed.
*/
int isspace(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_SPC) : 0; }
/**
* Returns !=0 if c is an upper case ascii character.
*/
int isupper(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_UC) : 0; }
/**
* Returns !=0 if c is a hex digit (0..9, a..f, A..F).
*/
int isxdigit(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_HEX) : 0; }
/**
* Returns !=0 if c is a printing character except for the space character.
*/
int isgraph(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG|_PNC) : 0; }
/**
* Returns !=0 if c is a printing character including the space character.
*/
int isprint(dchar c) { return (c <= 0x7F) ? _ctype[c] & (_ALP|_DIG|_PNC|_BLK) : 0; }
/**
* Returns !=0 if c is in the ascii character set, i.e. in the range 0..0x7F.
*/
int isascii(dchar c) { return c <= 0x7F; }
/**
* If c is an upper case ascii character,
* return the lower case equivalent, otherwise return c.
*/
dchar tolower(dchar c)
out (result)
{
assert(!isupper(result));
}
body
{
return isupper(c) ? c + (cast(dchar)'a' - 'A') : c;
}
/**
* If c is a lower case ascii character,
* return the upper case equivalent, otherwise return c.
*/
dchar toupper(dchar c)
out (result)
{
assert(!islower(result));
}
body
{
return islower(c) ? c - (cast(dchar)'a' - 'A') : c;
}
private:
enum
{
_SPC = 8,
_CTL = 0x20,
_BLK = 0x40,
_HEX = 0x80,
_UC = 1,
_LC = 2,
_PNC = 0x10,
_DIG = 4,
_ALP = _UC|_LC,
}
ubyte _ctype[128] =
[
_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
_CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL,
_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
_SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,
_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,
_PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC,
_UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
_UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC,
_UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC,
_PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC,
_LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
_LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC,
_LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL
];
unittest
{
assert(isspace(' '));
assert(!isspace('z'));
assert(toupper('a') == 'A');
assert(tolower('Q') == 'q');
assert(!isxdigit('G'));
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,788 +0,0 @@
/*
* Copyright (C) 1999-2004 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
module std.dateparse;
private
{
import std.string;
import std.c.stdlib;
import std.date;
}
//debug=dateparse;
class DateParseError : Error
{
this(char[] s)
{
super("Invalid date string: " ~ s);
}
}
struct DateParse
{
void parse(char[] s, out Date date)
{
*this = DateParse.init;
//version (Win32)
buffer = (cast(char *)/*alloca*/malloc(s.length))[0 .. s.length];
//else
//buffer = new char[s.length];
debug(dateparse) printf("DateParse.parse('%.*s')\n",
cast(int) s.length, s.ptr);
if (!parseString(s))
{
goto Lerror;
}
/+
if (year == year.init)
year = 0;
else
+/
debug(dateparse)
printf("year = %d, month = %d, day = %d\n%02d:%02d:%02d.%03d\nweekday = %d, tzcorrection = %d\n",
year, month, day,
hours, minutes, seconds, ms,
weekday, tzcorrection);
if (
year == year.init ||
(month < 1 || month > 12) ||
(day < 1 || day > 31) ||
(hours < 0 || hours > 23) ||
(minutes < 0 || minutes > 59) ||
(seconds < 0 || seconds > 59) ||
(tzcorrection != int.min &&
((tzcorrection < -2300 || tzcorrection > 2300) ||
(tzcorrection % 10)))
)
{
Lerror:
throw new DateParseError(s);
}
if (ampm)
{ if (hours > 12)
goto Lerror;
if (hours < 12)
{
if (ampm == 2) // if P.M.
hours += 12;
}
else if (ampm == 1) // if 12am
{
hours = 0; // which is midnight
}
}
// if (tzcorrection != tzcorrection.init)
// tzcorrection /= 100;
if (year >= 0 && year <= 99)
year += 1900;
date.year = year;
date.month = month;
date.day = day;
date.hour = hours;
date.minute = minutes;
date.second = seconds;
date.ms = ms;
date.weekday = weekday;
date.tzcorrection = tzcorrection;
}
private:
int year = int.min; // our "nan" Date value
int month; // 1..12
int day; // 1..31
int hours; // 0..23
int minutes; // 0..59
int seconds; // 0..59
int ms; // 0..999
int weekday; // 1..7
int ampm; // 0: not specified
// 1: AM
// 2: PM
int tzcorrection = int.min; // -1200..1200 correction in hours
char[] s;
int si;
int number;
char[] buffer;
enum DP : byte
{
err,
weekday,
month,
number,
end,
colon,
minus,
slash,
ampm,
plus,
tz,
dst,
dsttz,
}
DP nextToken()
{ int nest;
uint c;
int bi;
DP result = DP.err;
//printf("DateParse::nextToken()\n");
for (;;)
{
assert(si <= s.length);
if (si == s.length)
{ result = DP.end;
goto Lret;
}
//printf("\ts[%d] = '%c'\n", si, s[si]);
switch (s[si])
{
case ':': result = DP.colon; goto ret_inc;
case '+': result = DP.plus; goto ret_inc;
case '-': result = DP.minus; goto ret_inc;
case '/': result = DP.slash; goto ret_inc;
case '.':
version(DATE_DOT_DELIM)
{
result = DP.slash;
goto ret_inc;
}
else
{
si++;
break;
}
ret_inc:
si++;
goto Lret;
case ' ':
case '\n':
case '\r':
case '\t':
case ',':
si++;
break;
case '(': // comment
nest = 1;
for (;;)
{
si++;
if (si == s.length)
goto Lret; // error
switch (s[si])
{
case '(':
nest++;
break;
case ')':
if (--nest == 0)
goto Lendofcomment;
break;
default:
break;
}
}
Lendofcomment:
si++;
break;
default:
number = 0;
for (;;)
{
if (si == s.length)
// c cannot be undefined here
break;
c = s[si];
if (!(c >= '0' && c <= '9'))
break;
result = DP.number;
number = number * 10 + (c - '0');
si++;
}
if (result == DP.number)
goto Lret;
bi = 0;
bufloop:
while (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
{
if (c < 'a') // if upper case
c += cast(uint)'a' - cast(uint)'A'; // to lower case
buffer[bi] = cast(char)c;
bi++;
do
{
si++;
if (si == s.length)
break bufloop;
c = s[si];
} while (c == '.'); // ignore embedded '.'s
}
result = classify(buffer[0 .. bi]);
goto Lret;
}
}
Lret:
//printf("-DateParse::nextToken()\n");
return result;
}
DP classify(char[] buf)
{
struct DateID
{
char[] name;
DP tok;
short value;
}
static DateID dateidtab[] =
[
{ "january", DP.month, 1},
{ "february", DP.month, 2},
{ "march", DP.month, 3},
{ "april", DP.month, 4},
{ "may", DP.month, 5},
{ "june", DP.month, 6},
{ "july", DP.month, 7},
{ "august", DP.month, 8},
{ "september", DP.month, 9},
{ "october", DP.month, 10},
{ "november", DP.month, 11},
{ "december", DP.month, 12},
{ "jan", DP.month, 1},
{ "feb", DP.month, 2},
{ "mar", DP.month, 3},
{ "apr", DP.month, 4},
{ "jun", DP.month, 6},
{ "jul", DP.month, 7},
{ "aug", DP.month, 8},
{ "sep", DP.month, 9},
{ "sept", DP.month, 9},
{ "oct", DP.month, 10},
{ "nov", DP.month, 11},
{ "dec", DP.month, 12},
{ "sunday", DP.weekday, 1},
{ "monday", DP.weekday, 2},
{ "tuesday", DP.weekday, 3},
{ "tues", DP.weekday, 3},
{ "wednesday", DP.weekday, 4},
{ "wednes", DP.weekday, 4},
{ "thursday", DP.weekday, 5},
{ "thur", DP.weekday, 5},
{ "thurs", DP.weekday, 5},
{ "friday", DP.weekday, 6},
{ "saturday", DP.weekday, 7},
{ "sun", DP.weekday, 1},
{ "mon", DP.weekday, 2},
{ "tue", DP.weekday, 3},
{ "wed", DP.weekday, 4},
{ "thu", DP.weekday, 5},
{ "fri", DP.weekday, 6},
{ "sat", DP.weekday, 7},
{ "am", DP.ampm, 1},
{ "pm", DP.ampm, 2},
{ "gmt", DP.tz, +000},
{ "ut", DP.tz, +000},
{ "utc", DP.tz, +000},
{ "wet", DP.tz, +000},
{ "z", DP.tz, +000},
{ "wat", DP.tz, +100},
{ "a", DP.tz, +100},
{ "at", DP.tz, +200},
{ "b", DP.tz, +200},
{ "c", DP.tz, +300},
{ "ast", DP.tz, +400},
{ "d", DP.tz, +400},
{ "est", DP.tz, +500},
{ "e", DP.tz, +500},
{ "cst", DP.tz, +600},
{ "f", DP.tz, +600},
{ "mst", DP.tz, +700},
{ "g", DP.tz, +700},
{ "pst", DP.tz, +800},
{ "h", DP.tz, +800},
{ "yst", DP.tz, +900},
{ "i", DP.tz, +900},
{ "ahst", DP.tz, +1000},
{ "cat", DP.tz, +1000},
{ "hst", DP.tz, +1000},
{ "k", DP.tz, +1000},
{ "nt", DP.tz, +1100},
{ "l", DP.tz, +1100},
{ "idlw", DP.tz, +1200},
{ "m", DP.tz, +1200},
{ "cet", DP.tz, -100},
{ "fwt", DP.tz, -100},
{ "met", DP.tz, -100},
{ "mewt", DP.tz, -100},
{ "swt", DP.tz, -100},
{ "n", DP.tz, -100},
{ "eet", DP.tz, -200},
{ "o", DP.tz, -200},
{ "bt", DP.tz, -300},
{ "p", DP.tz, -300},
{ "zp4", DP.tz, -400},
{ "q", DP.tz, -400},
{ "zp5", DP.tz, -500},
{ "r", DP.tz, -500},
{ "zp6", DP.tz, -600},
{ "s", DP.tz, -600},
{ "wast", DP.tz, -700},
{ "t", DP.tz, -700},
{ "cct", DP.tz, -800},
{ "u", DP.tz, -800},
{ "jst", DP.tz, -900},
{ "v", DP.tz, -900},
{ "east", DP.tz, -1000},
{ "gst", DP.tz, -1000},
{ "w", DP.tz, -1000},
{ "x", DP.tz, -1100},
{ "idle", DP.tz, -1200},
{ "nzst", DP.tz, -1200},
{ "nzt", DP.tz, -1200},
{ "y", DP.tz, -1200},
{ "bst", DP.dsttz, 000},
{ "adt", DP.dsttz, +400},
{ "edt", DP.dsttz, +500},
{ "cdt", DP.dsttz, +600},
{ "mdt", DP.dsttz, +700},
{ "pdt", DP.dsttz, +800},
{ "ydt", DP.dsttz, +900},
{ "hdt", DP.dsttz, +1000},
{ "mest", DP.dsttz, -100},
{ "mesz", DP.dsttz, -100},
{ "sst", DP.dsttz, -100},
{ "fst", DP.dsttz, -100},
{ "wadt", DP.dsttz, -700},
{ "eadt", DP.dsttz, -1000},
{ "nzdt", DP.dsttz, -1200},
{ "dst", DP.dst, 0},
];
//message(DTEXT("DateParse::classify('%s')\n"), buf);
// Do a linear search. Yes, it would be faster with a binary
// one.
for (uint i = 0; i < dateidtab.length; i++)
{
if (std.string.cmp(dateidtab[i].name, buf) == 0)
{
number = dateidtab[i].value;
return dateidtab[i].tok;
}
}
return DP.err;
}
int parseString(char[] s)
{
int n1;
int dp;
int sisave;
int result;
//message(DTEXT("DateParse::parseString('%ls')\n"), s);
this.s = s;
si = 0;
dp = nextToken();
for (;;)
{
//message(DTEXT("\tdp = %d\n"), dp);
switch (dp)
{
case DP.end:
result = 1;
Lret:
return result;
case DP.err:
case_error:
//message(DTEXT("\terror\n"));
default:
result = 0;
goto Lret;
case DP.minus:
break; // ignore spurious '-'
case DP.weekday:
weekday = number;
break;
case DP.month: // month day, [year]
month = number;
dp = nextToken();
if (dp == DP.number)
{
day = number;
sisave = si;
dp = nextToken();
if (dp == DP.number)
{
n1 = number;
dp = nextToken();
if (dp == DP.colon)
{ // back up, not a year
si = sisave;
}
else
{ year = n1;
continue;
}
break;
}
}
continue;
case DP.number:
n1 = number;
dp = nextToken();
switch (dp)
{
case DP.end:
year = n1;
break;
case DP.minus:
case DP.slash: // n1/ ? ? ?
dp = parseCalendarDate(n1);
if (dp == DP.err)
goto case_error;
break;
case DP.colon: // hh:mm [:ss] [am | pm]
dp = parseTimeOfDay(n1);
if (dp == DP.err)
goto case_error;
break;
case DP.ampm:
hours = n1;
minutes = 0;
seconds = 0;
ampm = number;
break;
case DP.month:
day = n1;
month = number;
dp = nextToken();
if (dp == DP.number)
{ // day month year
year = number;
dp = nextToken();
}
break;
default:
year = n1;
break;
}
continue;
}
dp = nextToken();
}
assert(0);
}
int parseCalendarDate(int n1)
{
int n2;
int n3;
int dp;
debug(dateparse) printf("DateParse.parseCalendarDate(%d)\n", n1);
dp = nextToken();
if (dp == DP.month) // day/month
{
day = n1;
month = number;
dp = nextToken();
if (dp == DP.number)
{ // day/month year
year = number;
dp = nextToken();
}
else if (dp == DP.minus || dp == DP.slash)
{ // day/month/year
dp = nextToken();
if (dp != DP.number)
goto case_error;
year = number;
dp = nextToken();
}
return dp;
}
if (dp != DP.number)
goto case_error;
n2 = number;
//message(DTEXT("\tn2 = %d\n"), n2);
dp = nextToken();
if (dp == DP.minus || dp == DP.slash)
{
dp = nextToken();
if (dp != DP.number)
goto case_error;
n3 = number;
//message(DTEXT("\tn3 = %d\n"), n3);
dp = nextToken();
// case1: year/month/day
// case2: month/day/year
int case1, case2;
case1 = (n1 > 12 ||
(n2 >= 1 && n2 <= 12) &&
(n3 >= 1 && n3 <= 31));
case2 = ((n1 >= 1 && n1 <= 12) &&
(n2 >= 1 && n2 <= 31) ||
n3 > 31);
if (case1 == case2)
goto case_error;
if (case1)
{
year = n1;
month = n2;
day = n3;
}
else
{
month = n1;
day = n2;
year = n3;
}
}
else
{ // must be month/day
month = n1;
day = n2;
}
return dp;
case_error:
return DP.err;
}
int parseTimeOfDay(int n1)
{
int dp;
int sign;
// 12am is midnight
// 12pm is noon
//message(DTEXT("DateParse::parseTimeOfDay(%d)\n"), n1);
hours = n1;
dp = nextToken();
if (dp != DP.number)
goto case_error;
minutes = number;
dp = nextToken();
if (dp == DP.colon)
{
dp = nextToken();
if (dp != DP.number)
goto case_error;
seconds = number;
dp = nextToken();
}
else
seconds = 0;
if (dp == DP.ampm)
{
ampm = number;
dp = nextToken();
}
else if (dp == DP.plus || dp == DP.minus)
{
Loffset:
sign = (dp == DP.minus) ? -1 : 1;
dp = nextToken();
if (dp != DP.number)
goto case_error;
tzcorrection = -sign * number;
dp = nextToken();
}
else if (dp == DP.tz)
{
tzcorrection = number;
dp = nextToken();
if (number == 0 && (dp == DP.plus || dp == DP.minus))
goto Loffset;
if (dp == DP.dst)
{ tzcorrection += 100;
dp = nextToken();
}
}
else if (dp == DP.dsttz)
{
tzcorrection = number;
dp = nextToken();
}
return dp;
case_error:
return DP.err;
}
}
unittest
{
DateParse dp;
Date d;
dp.parse("March 10, 1959 12:00 -800", d);
assert(d.year == 1959);
assert(d.month == 3);
assert(d.day == 10);
assert(d.hour == 12);
assert(d.minute == 0);
assert(d.second == 0);
assert(d.ms == 0);
assert(d.weekday == 0);
assert(d.tzcorrection == 800);
dp.parse("Tue Apr 02 02:04:57 GMT-0800 1996", d);
assert(d.year == 1996);
assert(d.month == 4);
assert(d.day == 2);
assert(d.hour == 2);
assert(d.minute == 4);
assert(d.second == 57);
assert(d.ms == 0);
assert(d.weekday == 3);
assert(d.tzcorrection == 800);
dp.parse("March 14, -1980 21:14:50", d);
assert(d.year == 1980);
assert(d.month == 3);
assert(d.day == 14);
assert(d.hour == 21);
assert(d.minute == 14);
assert(d.second == 50);
assert(d.ms == 0);
assert(d.weekday == 0);
assert(d.tzcorrection == int.min);
dp.parse("Tue Apr 02 02:04:57 1996", d);
assert(d.year == 1996);
assert(d.month == 4);
assert(d.day == 2);
assert(d.hour == 2);
assert(d.minute == 4);
assert(d.second == 57);
assert(d.ms == 0);
assert(d.weekday == 3);
assert(d.tzcorrection == int.min);
dp.parse("Tue, 02 Apr 1996 02:04:57 G.M.T.", d);
assert(d.year == 1996);
assert(d.month == 4);
assert(d.day == 2);
assert(d.hour == 2);
assert(d.minute == 4);
assert(d.second == 57);
assert(d.ms == 0);
assert(d.weekday == 3);
assert(d.tzcorrection == 0);
dp.parse("December 31, 3000", d);
assert(d.year == 3000);
assert(d.month == 12);
assert(d.day == 31);
assert(d.hour == 0);
assert(d.minute == 0);
assert(d.second == 0);
assert(d.ms == 0);
assert(d.weekday == 0);
assert(d.tzcorrection == int.min);
dp.parse("Wed, 31 Dec 1969 16:00:00 GMT", d);
assert(d.year == 1969);
assert(d.month == 12);
assert(d.day == 31);
assert(d.hour == 16);
assert(d.minute == 0);
assert(d.second == 0);
assert(d.ms == 0);
assert(d.weekday == 4);
assert(d.tzcorrection == 0);
dp.parse("1/1/1999 12:30 AM", d);
assert(d.year == 1999);
assert(d.month == 1);
assert(d.day == 1);
assert(d.hour == 0);
assert(d.minute == 30);
assert(d.second == 0);
assert(d.ms == 0);
assert(d.weekday == 0);
assert(d.tzcorrection == int.min);
dp.parse("Tue, 20 May 2003 15:38:58 +0530", d);
assert(d.year == 2003);
assert(d.month == 5);
assert(d.day == 20);
assert(d.hour == 15);
assert(d.minute == 38);
assert(d.second == 58);
assert(d.ms == 0);
assert(d.weekday == 3);
assert(d.tzcorrection == -530);
debug(dateparse) printf("year = %d, month = %d, day = %d\n%02d:%02d:%02d.%03d\nweekday = %d, tzcorrection = %d\n",
d.year, d.month, d.day,
d.hour, d.minute, d.second, d.ms,
d.weekday, d.tzcorrection);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,193 +0,0 @@
/*
* Copyright (C) 1999-2006 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
/**
* The garbage collector normally works behind the scenes without needing any
* specific interaction. These functions are for advanced applications that
* benefit from tuning the operation of the collector.
* Macros:
* WIKI=Phobos/StdGc
*/
module std.gc;
import gcstats;
/**
* Add p to list of roots. Roots are references to memory allocated by the
collector that are maintained in memory outside the collector pool. The garbage
collector will by default look for roots in the stacks of each thread, the
registers, and the default static data segment. If roots are held elsewhere,
use addRoot() or addRange() to tell the collector not to free the memory it
points to.
*/
void addRoot(void *p); // add p to list of roots
/**
* Remove p from list of roots.
*/
void removeRoot(void *p); // remove p from list of roots
/**
* Add range to scan for roots.
*/
void addRange(void *pbot, void *ptop); // add range to scan for roots
/**
* Remove range.
*/
void removeRange(void *pbot); // remove range
/**
* Mark a gc allocated block of memory as possibly containing pointers.
*/
void hasPointers(void* p);
/**
* Mark a gc allocated block of memory as definitely NOT containing pointers.
*/
void hasNoPointers(void* p);
/**
* Mark a gc allocated block of memory pointed to by p as being populated with
* an array of TypeInfo ti (as many as will fit).
*/
void setTypeInfo(TypeInfo ti, void* p);
/**
* Allocate nbytes of uninitialized data.
* The allocated memory will be scanned for pointers during
* a gc collection cycle, unless
* it is followed by a call to hasNoPointers().
*/
void[] malloc(size_t nbytes);
/**
* Resize allocated memory block pointed to by p to be at least nbytes long.
* It will try to resize the memory block in place.
* If nbytes is 0, the memory block is free'd.
* If p is null, the memory block is allocated using malloc.
* The returned array may not be at the same location as the original
* memory block.
* The allocated memory will be scanned for pointers during
* a gc collection cycle, unless
* it is followed by a call to hasNoPointers().
*/
void[] realloc(void* p, size_t nbytes);
/**
* Attempt to enlarge the memory block pointed to by p
* by at least minbytes beyond its current capacity,
* up to a maximum of maxbytes.
* Returns:
* 0 if could not extend p,
* total size of entire memory block if successful.
*/
size_t extend(void* p, size_t minbytes, size_t maxbytes);
/**
* Returns capacity (size of the memory block) that p
* points to the beginning of.
* If p does not point into the gc memory pool, or does
* not point to the beginning of an allocated memory block,
* 0 is returned.
*/
size_t capacity(void* p);
/**
* Set gc behavior to match that of 1.0.
*/
void setV1_0();
/***********************************
* Run a full garbage collection cycle.
*
* The collector normally runs synchronously with a storage allocation request
(i.e. it never happens when in code that does not allocate memory). In some
circumstances, for example when a particular task is finished, it is convenient
to explicitly run the collector and free up all memory used by that task. It
can also be helpful to run a collection before starting a new task that would
be annoying if it ran a collection in the middle of that task. Explicitly
running a collection can also be done in a separate very low priority thread,
so that if the program is idly waiting for input, memory can be cleaned up.
*/
void fullCollect();
/***********************************
* Run a generational garbage collection cycle.
* Takes less time than a fullcollect(), but isn't
* as effective.
*/
void genCollect();
void genCollectNoStack();
/**
* Minimizes physical memory usage
*/
void minimize();
/***************************************
* disable() temporarily disables garbage collection cycle, enable()
* then reenables them.
*
* This is used for brief time critical sections of code, so the amount of time
* it will take is predictable.
* If the collector runs out of memory while it is disabled, it will throw an
* std.outofmemory.OutOfMemoryException.
* The disable() function calls can be nested, but must be
* matched with corresponding enable() calls.
* By default collections are enabled.
*/
void disable();
/**
* ditto
*/
void enable();
void getStats(out GCStats stats);
/***************************************
* Get handle to the collector.
*/
void* getGCHandle();
/***************************************
* Set handle to the collector.
*/
void setGCHandle(void* p);
void endGCHandle();
extern (C)
{
void gc_init();
void gc_term();
}

View File

@@ -1,265 +0,0 @@
// written by Walter Bright
// www.digitalmars.com
// Placed into the public domain
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
NOTE: This file has been patched from the original GDC distribution to
work with the LDC compiler.
Modified by David Friedman, May 2006
Modified by Tomas Lindquist Olsen, August 2007
*/
/** These functions are built-in intrinsics to the compiler.
*
Intrinsic functions are functions built in to the compiler,
usually to take advantage of specific CPU features that
are inefficient to handle via external functions.
The compiler's optimizer and code generator are fully
integrated in with intrinsic functions, bringing to bear
their full power on them.
This can result in some surprising speedups.
* Macros:
* WIKI=Phobos/StdIntrinsic
*/
module std.intrinsic;
/**
* Scans the bits in v starting with bit 0, looking
* for the first set bit.
* Returns:
* The bit number of the first bit set.
* The return value is undefined if v is zero.
*/
version (LLVM)
int bsf(uint v)
{
uint m = 1;
uint i;
for (i = 0; i < 32; i++,m<<=1) {
if (v&m)
return i;
}
return i; // supposed to be undefined
}
else
int bsf(uint v);
/**
* Scans the bits in v from the most significant bit
* to the least significant bit, looking
* for the first set bit.
* Returns:
* The bit number of the first bit set.
* The return value is undefined if v is zero.
* Example:
* ---
* import std.intrinsic;
*
* int main()
* {
* uint v;
* int x;
*
* v = 0x21;
* x = bsf(v);
* printf("bsf(x%x) = %d\n", v, x);
* x = bsr(v);
* printf("bsr(x%x) = %d\n", v, x);
* return 0;
* }
* ---
* Output:
* bsf(x21) = 0<br>
* bsr(x21) = 5
*/
version (LLVM)
int bsr(uint v)
{
uint m = 0x80000000;
uint i;
for (i = 32; i ; i--,m>>>=1) {
if (v&m)
return i-1;
}
return i; // supposed to be undefined
}
else
int bsr(uint v);
/**
* Tests the bit.
*/
version (LLVM)
int bt(uint *p, uint bitnum)
{
return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
}
else
int bt(uint *p, uint bitnum);
/**
* Tests and complements the bit.
*/
version (LLVM)
int btc(uint *p, uint bitnum)
{
uint * q = p + (bitnum / (uint.sizeof*8));
uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
int result = *q & mask;
*q ^= mask;
return result ? -1 : 0;
}
else
int btc(uint *p, uint bitnum);
/**
* Tests and resets (sets to 0) the bit.
*/
version (LLVM)
int btr(uint *p, uint bitnum)
{
uint * q = p + (bitnum / (uint.sizeof*8));
uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
int result = *q & mask;
*q &= ~mask;
return result ? -1 : 0;
}
else
int btr(uint *p, uint bitnum);
/**
* Tests and sets the bit.
* Params:
* p = a non-NULL pointer to an array of uints.
* index = a bit number, starting with bit 0 of p[0],
* and progressing. It addresses bits like the expression:
---
p[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1)))
---
* Returns:
* A non-zero value if the bit was set, and a zero
* if it was clear.
*
* Example:
* ---
import std.intrinsic;
int main()
{
uint array[2];
array[0] = 2;
array[1] = 0x100;
printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("bts(array, 35) = %d\n", <b>bts</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("btr(array, 35) = %d\n", <b>btr</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("bt(array, 1) = %d\n", <b>bt</b>(array, 1));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
return 0;
}
* ---
* Output:
<pre>
btc(array, 35) = 0
array = [0]:x2, [1]:x108
btc(array, 35) = -1
array = [0]:x2, [1]:x100
bts(array, 35) = 0
array = [0]:x2, [1]:x108
btr(array, 35) = -1
array = [0]:x2, [1]:x100
bt(array, 1) = -1
array = [0]:x2, [1]:x100
</pre>
*/
version (LLVM)
int bts(uint *p, uint bitnum)
{
uint * q = p + (bitnum / (uint.sizeof*8));
uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
int result = *q & mask;
*q |= mask;
return result ? -1 : 0;
}
else
int bts(uint *p, uint bitnum);
/**
* Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes
byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3
becomes byte 0.
*/
version (LLVM)
pragma(intrinsic, "llvm.bswap.i32")
uint bswap(uint val);
else
uint bswap(uint v);
/**
* Reads I/O port at port_address.
*/
version (LLVM)
ubyte inp(uint p) { return 0; }
else
ubyte inp(uint port_address);
/**
* ditto
*/
version (LLVM)
ushort inpw(uint p) { return 0; }
else
ushort inpw(uint port_address);
/**
* ditto
*/
version (LLVM)
uint inpl(uint p) { return 0; }
else
uint inpl(uint port_address);
/**
* Writes and returns value to I/O port at port_address.
*/
version (LLVM)
ubyte outp(uint p, ubyte v) { return v; }
else
ubyte outp(uint port_address, ubyte value);
/**
* ditto
*/
version (LLVM)
ushort outpw(uint p, ushort v) { return v; }
else
ushort outpw(uint port_address, ushort value);
/**
* ditto
*/
version (LLVM)
uint outpl(uint p, uint v) { return v; }
else
uint outpl(uint port_address, uint value);

File diff suppressed because it is too large Load Diff

View File

@@ -1,504 +0,0 @@
/* md5.d - RSA Data Security, Inc., MD5 message-digest algorithm
* Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm.
*/
/**
* Computes MD5 digests of arbitrary data. MD5 digests are 16 byte quantities that are like a checksum or crc, but are more robust.
*
* There are two ways to do this. The first does it all in one function call to
* sum(). The second is for when the data is buffered.
*
* Bugs:
* MD5 digests have been demonstrated to not be unique.
*
* Author:
* The routines and algorithms are derived from the
* $(I RSA Data Security, Inc. MD5 Message-Digest Algorithm).
*
* References:
* $(LINK2 http://en.wikipedia.org/wiki/Md5, Wikipedia on MD5)
*
* Macros:
* WIKI = Phobos/StdMd5
*/
/++++++++++++++++++++++++++++++++
Example:
--------------------
// This code is derived from the
// RSA Data Security, Inc. MD5 Message-Digest Algorithm.
import std.md5;
private import std.stdio;
private import std.string;
private import std.c.stdio;
private import std.c.string;
int main(char[][] args)
{
foreach (char[] arg; args)
MDFile(arg);
return 0;
}
/* Digests a file and prints the result. */
void MDFile(char[] filename)
{
FILE* file;
MD5_CTX context;
int len;
ubyte[4 * 1024] buffer;
ubyte digest[16];
if ((file = fopen(std.string.toStringz(filename), "rb")) == null)
writefln("%s can't be opened", filename);
else
{
context.start();
while ((len = fread(buffer, 1, buffer.sizeof, file)) != 0)
context.update(buffer[0 .. len]);
context.finish(digest);
fclose(file);
writefln("MD5 (%s) = %s", filename, digestToString(digest));
}
}
--------------------
+/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, September 2004
*/
module std.md5;
//debug=md5; // uncomment to turn on debugging printf's
import std.string;
version(D_InlineAsm)
version(X86)
version = Asm86;
/***************************************
* Computes MD5 digest of array of data.
*/
void sum(ubyte[16] digest, void[] data)
{
MD5_CTX context;
context.start();
context.update(data);
context.finish(digest);
}
/******************
* Prints a message digest in hexadecimal to stdout.
*/
void printDigest(ubyte digest[16])
{
foreach (ubyte u; digest)
printf("%02x", u);
}
/****************************************
* Converts MD5 digest to a string.
*/
char[] digestToString(ubyte[16] digest)
{
char[] result = new char[32];
int i;
foreach (ubyte u; digest)
{
result[i] = std.string.hexdigits[u >> 4];
result[i + 1] = std.string.hexdigits[u & 15];
i += 2;
}
return result;
}
/**
* Holds context of MD5 computation.
*
* Used when data to be digested is buffered.
*/
struct MD5_CTX
{
uint state[4] = /* state (ABCD) */
/* magic initialization constants */
[0x67452301,0xefcdab89,0x98badcfe,0x10325476];
ulong count; /* number of bits, modulo 2^64 */
ubyte buffer[64]; /* input buffer */
static ubyte[64] PADDING =
[
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
];
/* F, G, H and I are basic MD5 functions.
*/
private static
{
uint F(uint x, uint y, uint z) { return (x & y) | (~x & z); }
uint G(uint x, uint y, uint z) { return (x & z) | (y & ~z); }
uint H(uint x, uint y, uint z) { return x ^ y ^ z; }
uint I(uint x, uint y, uint z) { return y ^ (x | ~z); }
}
/* ROTATE_LEFT rotates x left n bits.
*/
static uint ROTATE_LEFT(uint x, uint n)
{
version (Asm86)
{
version (GNU)
{
asm
{
naked ;
mov ECX, n ;
mov EAX, x ;
rol EAX, CL ;
ret ;
}
}
else
{
asm
{ naked ;
mov ECX,EAX ;
mov EAX,4[ESP] ;
rol EAX,CL ;
ret 4 ;
}
}
}
else
{
return (x << n) | (x >> (32-n));
}
}
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
static void FF(inout uint a, uint b, uint c, uint d, uint x, uint s, uint ac)
{
a += F (b, c, d) + x + cast(uint)(ac);
a = ROTATE_LEFT (a, s);
a += b;
}
static void GG(inout uint a, uint b, uint c, uint d, uint x, uint s, uint ac)
{
a += G (b, c, d) + x + cast(uint)(ac);
a = ROTATE_LEFT (a, s);
a += b;
}
static void HH(inout uint a, uint b, uint c, uint d, uint x, uint s, uint ac)
{
a += H (b, c, d) + x + cast(uint)(ac);
a = ROTATE_LEFT (a, s);
a += b;
}
static void II(inout uint a, uint b, uint c, uint d, uint x, uint s, uint ac)
{
a += I (b, c, d) + x + cast(uint)(ac);
a = ROTATE_LEFT (a, s);
a += b;
}
/**
* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void start()
{
*this = MD5_CTX.init;
}
/** MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void update(void[] input)
{
uint index, partLen;
size_t i;
size_t inputLen = input.length;
/* Compute number of bytes mod 64 */
index = (cast(uint)count >> 3) & (64 - 1);
/* Update number of bits */
count += inputLen * 8;
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen)
{
std.c.string.memcpy(&buffer[index], input.ptr, partLen);
transform (buffer.ptr);
for (i = partLen; i + 63 < inputLen; i += 64)
transform ((cast(ubyte[])input)[i .. i + 64].ptr);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
if (inputLen - i)
std.c.string.memcpy(&buffer[index], &input[i], inputLen-i);
}
/** MD5 finalization. Ends an MD5 message-digest operation, writing the
* the message to digest and zeroing the context.
*/
void finish(ubyte[16] digest) /* message digest */
{
ubyte bits[8];
uint index, padLen;
uint[2] cnt;
/* Save number of bits */
cnt[0] = cast(uint)count;
cnt[1] = cast(uint)(count >> 32);
Encode (bits.ptr, cnt.ptr, 8);
/* Pad out to 56 mod 64. */
index = (cast(uint)count >> 3) & (64 - 1);
padLen = (index < 56) ? (56 - index) : (120 - index);
update (PADDING[0 .. padLen]);
/* Append length (before padding) */
update (bits);
/* Store state in digest */
Encode (digest.ptr, state.ptr, 16);
/* Zeroize sensitive information. */
std.c.string.memset (this, 0, MD5_CTX.sizeof);
}
/* MD5 basic transformation. Transforms state based on block.
*/
/* Constants for MD5Transform routine. */
enum
{
S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22,
S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20,
S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23,
S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21,
}
private void transform (ubyte* /*[64]*/ block)
{
uint a = state[0],
b = state[1],
c = state[2],
d = state[3];
uint[16] x;
Decode (x.ptr, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
x[] = 0;
}
/* Encodes input (uint) into output (ubyte). Assumes len is
a multiple of 4.
*/
private static void Encode (ubyte *output, uint *input, uint len)
{
uint i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
uint u = input[i];
output[j] = cast(ubyte)(u);
output[j+1] = cast(ubyte)(u >> 8);
output[j+2] = cast(ubyte)(u >> 16);
output[j+3] = cast(ubyte)(u >> 24);
}
}
/* Decodes input (ubyte) into output (uint). Assumes len is
a multiple of 4.
*/
private static void Decode (uint *output, ubyte *input, uint len)
{
uint i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
version (LittleEndian)
{
output[i] = *cast(uint*)&input[j];
}
else
{
output[i] = (cast(uint)input[j]) | ((cast(uint)input[j+1]) << 8) |
((cast(uint)input[j+2]) << 16) | ((cast(uint)input[j+3]) << 24);
}
}
}
}
unittest
{
debug(md5) printf("std.md5.unittest\n");
ubyte[16] digest;
sum (digest, "");
assert(digest == cast(ubyte[])x"d41d8cd98f00b204e9800998ecf8427e");
sum (digest, "a");
assert(digest == cast(ubyte[])x"0cc175b9c0f1b6a831c399e269772661");
sum (digest, "abc");
assert(digest == cast(ubyte[])x"900150983cd24fb0d6963f7d28e17f72");
sum (digest, "message digest");
assert(digest == cast(ubyte[])x"f96b697d7cb7938d525a2f31aaf161d0");
sum (digest, "abcdefghijklmnopqrstuvwxyz");
assert(digest == cast(ubyte[])x"c3fcd3d76192e4007dfb496cca67e13b");
sum (digest, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
assert(digest == cast(ubyte[])x"d174ab98d277d9f5a5611c2c9f419d9f");
sum (digest,
"1234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890");
assert(digest == cast(ubyte[])x"57edf4a22be3c955ac49da2e2107b67a");
assert(digestToString(cast(ubyte[16])x"c3fcd3d76192e4007dfb496cca67e13b")
== "C3FCD3D76192E4007DFB496CCA67E13B");
}

View File

@@ -1,650 +0,0 @@
/* Copyright 2004-2005 by Digital Mars
* Written by Walter Bright and Matthew Wilson
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, in both source and binary form, subject to the following
* restrictions:
*
* - The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* - Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* - This notice may not be removed or altered from any source
* distribution.
*
*/
/**
* Read and write memory mapped files.
* Macros:
* WIKI=Phobos/StdMmfile
*/
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, September 2004
*/
module std.mmfile;
private import std.c.stdio;
private import std.c.stdlib;
private import std.string;
version(linux) version = Unix;
//debug = MMFILE;
version (Win32)
{
private import std.c.windows.windows;
private import std.utf;
private uint dwVersion;
static this()
{ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getversion.asp
dwVersion = GetVersion();
}
private const bool Have_MMFile = true; // private for now...
}
else version (Unix)
{
version (/*GNU_Unix_Have_MMap*/Unix)
{
version(linux) {
import std.c.linux.linux;
alias std.c.linux.linux unix;
} else {
private import std.c.unix.unix;
alias std.c.unix.unix unix;
}
version = unix_mm;
private const bool Have_MMFile = true;
}
else
{
private const bool Have_MMFile = false;
}
}
else
{
private const bool Have_MMFile = false;
// Can't simply fail because std.stream imports this module.
//static assert(0);
}
static if (Have_MMFile)
{
private import std.file;
private import std.path;
}
/**
* MmFile objects control the memory mapped file resource.
*/
class MmFile
{
/**
* The mode the memory mapped file is opened with.
*/
enum Mode
{ Read, /// read existing file
ReadWriteNew, /// delete existing file, write new file
ReadWrite, /// read/write existing file, create if not existing
ReadCopyOnWrite, /// read/write existing file, copy on write
}
/**
* Open memory mapped file filename for reading.
* File is closed when the object instance is deleted.
* Throws:
* std.file.FileException
*/
this(char[] filename)
{
this(filename, Mode.Read, 0, null);
}
/**
* Open memory mapped file filename in mode.
* File is closed when the object instance is deleted.
* Params:
* filename = name of the file.
* If null, an anonymous file mapping is created.
* mode = access mode defined above.
* size = the size of the file. If 0, it is taken to be the
* size of the existing file.
* address = the preferred address to map the file to,
* although the system is not required to honor it.
* If null, the system selects the most convenient address.
* window = preferred block size of the amount of data to map at one time
* with 0 meaning map the entire file. The window size must be a
* multiple of the memory allocation page size.
* Throws:
* std.file.FileException
*/
this(char[] filename, Mode mode, ulong size, void* address,
size_t window = 0)
{
this.filename = filename;
this.mMode = mode;
this.window = window;
this.address = address;
version (Win32)
{
void* p;
uint dwDesiredAccess2;
uint dwShareMode;
uint dwCreationDisposition;
uint flProtect;
if (dwVersion & 0x80000000 && (dwVersion & 0xFF) == 3)
{
throw new FileException(filename,
"Win32s does not implement mm files");
}
switch (mode)
{
case Mode.Read:
dwDesiredAccess2 = GENERIC_READ;
dwShareMode = FILE_SHARE_READ;
dwCreationDisposition = OPEN_EXISTING;
flProtect = PAGE_READONLY;
dwDesiredAccess = FILE_MAP_READ;
break;
case Mode.ReadWriteNew:
assert(size != 0);
dwDesiredAccess2 = GENERIC_READ | GENERIC_WRITE;
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
dwCreationDisposition = CREATE_ALWAYS;
flProtect = PAGE_READWRITE;
dwDesiredAccess = FILE_MAP_WRITE;
break;
case Mode.ReadWrite:
dwDesiredAccess2 = GENERIC_READ | GENERIC_WRITE;
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
dwCreationDisposition = OPEN_ALWAYS;
flProtect = PAGE_READWRITE;
dwDesiredAccess = FILE_MAP_WRITE;
break;
case Mode.ReadCopyOnWrite:
if (dwVersion & 0x80000000)
{
throw new FileException(filename,
"Win9x does not implement copy on write");
}
dwDesiredAccess2 = GENERIC_READ | GENERIC_WRITE;
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
dwCreationDisposition = OPEN_EXISTING;
flProtect = PAGE_WRITECOPY;
dwDesiredAccess = FILE_MAP_COPY;
break;
default:
assert(0);
}
if (filename)
{
if (useWfuncs)
{
auto namez = std.utf.toUTF16z(filename);
hFile = CreateFileW(namez,
dwDesiredAccess2,
dwShareMode,
null,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
cast(HANDLE)null);
}
else
{
auto namez = std.file.toMBSz(filename);
hFile = CreateFileA(namez,
dwDesiredAccess2,
dwShareMode,
null,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
cast(HANDLE)null);
}
if (hFile == INVALID_HANDLE_VALUE)
goto err1;
}
else
hFile = null;
int hi = cast(int)(size>>32);
hFileMap = CreateFileMappingA(hFile, null, flProtect, hi, cast(uint)size, null);
if (hFileMap == null) // mapping failed
goto err1;
if (size == 0)
{
uint sizehi;
uint sizelow = GetFileSize(hFile,&sizehi);
size = (cast(ulong)sizehi << 32) + sizelow;
}
this.size = size;
size_t initial_map = (window && 2*window<size)? 2*window : cast(size_t)size;
p = MapViewOfFileEx(hFileMap, dwDesiredAccess, 0, 0, initial_map, address);
if (!p) goto err1;
data = p[0 .. initial_map];
debug (MMFILE) printf("MmFile.this(): p = %p, size = %d\n", p, size);
return;
err1:
if (hFileMap != null)
CloseHandle(hFileMap);
hFileMap = null;
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
errNo();
}
else version (unix_mm)
{
char* namez = toStringz(filename);
void* p;
int oflag;
int fmode;
switch (mode)
{
case Mode.Read:
flags = MAP_SHARED;
prot = PROT_READ;
oflag = O_RDONLY;
fmode = 0;
break;
case Mode.ReadWriteNew:
assert(size != 0);
flags = MAP_SHARED;
prot = PROT_READ | PROT_WRITE;
oflag = O_CREAT | O_RDWR | O_TRUNC;
fmode = 0660;
break;
case Mode.ReadWrite:
flags = MAP_SHARED;
prot = PROT_READ | PROT_WRITE;
oflag = O_CREAT | O_RDWR;
fmode = 0660;
break;
case Mode.ReadCopyOnWrite:
flags = MAP_PRIVATE;
prot = PROT_READ | PROT_WRITE;
oflag = O_RDWR;
fmode = 0;
break;
default:
assert(0);
}
if (filename.length)
{
struct_stat statbuf;
fd = unix.open(namez, oflag, fmode);
if (fd == -1)
{
// printf("\topen error, errno = %d\n",getErrno());
errNo();
}
if (unix.fstat(fd, &statbuf))
{
//printf("\tfstat error, errno = %d\n",getErrno());
unix.close(fd);
errNo();
}
if (prot & PROT_WRITE && size > statbuf.st_size)
{
// Need to make the file size bytes big
unix.lseek(fd, cast(off_t)(size - 1), SEEK_SET);
char c = 0;
unix.write(fd, &c, 1);
}
else if (prot & PROT_READ && size == 0)
size = statbuf.st_size;
}
else
{
fd = -1;
flags |= MAP_ANONYMOUS;
}
this.size = size;
size_t initial_map = (window && 2*window<size)? 2*window : cast(size_t)size;
p = mmap(address, initial_map, prot, flags, fd, 0);
if (p == MAP_FAILED) {
if (fd != -1)
unix.close(fd);
errNo();
}
data = p[0 .. initial_map];
}
else static if (! Have_MMFile)
{
throw new FileException("This system does support memory mapped files");
}
else
{
static assert(0);
}
}
/**
* Flushes pending output and closes the memory mapped file.
*/
~this()
{
debug (MMFILE) printf("MmFile.~this()\n");
unmap();
version (Win32)
{
if (hFileMap != null && CloseHandle(hFileMap) != TRUE)
errNo();
hFileMap = null;
if (hFile != INVALID_HANDLE_VALUE && CloseHandle(hFile) != TRUE)
errNo();
hFile = INVALID_HANDLE_VALUE;
}
else version (unix_mm)
{
if (fd != -1 && unix.close(fd) == -1)
errNo();
fd = -1;
}
else static if (! Have_MMFile)
{
}
else
{
static assert(0);
}
data = null;
}
/* Flush any pending output.
*/
void flush()
{
debug (MMFILE) printf("MmFile.flush()\n");
version (Win32)
{
FlushViewOfFile(data.ptr, data.length);
}
else version (unix_mm)
{
int i;
i = msync(cast(void*)data, data.length, MS_SYNC); // sys/mman.h
if (i != 0)
errNo();
}
else static if (! Have_MMFile)
{
}
else
{
static assert(0);
}
}
/**
* Gives size in bytes of the memory mapped file.
*/
ulong length()
{
debug (MMFILE) printf("MmFile.length()\n");
return size;
}
/**
* Read-only property returning the file mode.
*/
Mode mode()
{
debug (MMFILE) printf("MmFile.mode()\n");
return mMode;
}
/**
* Returns entire file contents as an array.
*/
void[] opSlice()
{
debug (MMFILE) printf("MmFile.opSlice()\n");
return opSlice(0,size);
}
/**
* Returns slice of file contents as an array.
*/
void[] opSlice(ulong i1, ulong i2)
{
debug (MMFILE) printf("MmFile.opSlice(%lld, %lld)\n", i1, i2);
ensureMapped(i1,i2);
size_t off1 = cast(size_t)(i1-start);
size_t off2 = cast(size_t)(i2-start);
return data[off1 .. off2];
}
/**
* Returns byte at index i in file.
*/
ubyte opIndex(ulong i)
{
debug (MMFILE) printf("MmFile.opIndex(%lld)\n", i);
ensureMapped(i);
size_t off = cast(size_t)(i-start);
return (cast(ubyte[])data)[off];
}
/**
* Sets and returns byte at index i in file to value.
*/
ubyte opIndexAssign(ubyte value, ulong i)
{
debug (MMFILE) printf("MmFile.opIndex(%lld, %d)\n", i, value);
ensureMapped(i);
size_t off = cast(size_t)(i-start);
return (cast(ubyte[])data)[off] = value;
}
// return true if the given position is currently mapped
private int mapped(ulong i)
{
debug (MMFILE) printf("MmFile.mapped(%lld, %lld, %d)\n", i,start,
data.length);
return i >= start && i < start+data.length;
}
// unmap the current range
private void unmap()
{
debug (MMFILE) printf("MmFile.unmap()\n");
version(Windows) {
/* Note that under Windows 95, UnmapViewOfFile() seems to return
* random values, not TRUE or FALSE.
*/
if (data && UnmapViewOfFile(data.ptr) == FALSE &&
(dwVersion & 0x80000000) == 0)
errNo();
} else version (unix_mm) {
if (data && munmap(cast(void*)data, data.length) != 0)
errNo();
}
data = null;
}
// map range
private void map(ulong start, size_t len)
{
debug (MMFILE) printf("MmFile.map(%lld, %d)\n", start, len);
void* p;
if (start+len > size)
len = cast(size_t)(size-start);
version(Windows) {
uint hi = cast(uint)(start>>32);
p = MapViewOfFileEx(hFileMap, dwDesiredAccess, hi, cast(uint)start, len, address);
if (!p) errNo();
} else version (unix_mm) {
p = mmap(address, len, prot, flags, fd, cast(off_t)start);
if (p == MAP_FAILED) errNo();
}
data = p[0 .. len];
this.start = start;
}
// ensure a given position is mapped
private void ensureMapped(ulong i)
{
debug (MMFILE) printf("MmFile.ensureMapped(%lld)\n", i);
if (!mapped(i)) {
unmap();
if (window == 0) {
map(0,cast(size_t)size);
} else {
ulong block = i/window;
if (block == 0)
map(0,2*window);
else
map(window*(block-1),3*window);
}
}
}
// ensure a given range is mapped
private void ensureMapped(ulong i, ulong j)
{
debug (MMFILE) printf("MmFile.ensureMapped(%lld, %lld)\n", i, j);
if (!mapped(i) || !mapped(j-1)) {
unmap();
if (window == 0) {
map(0,cast(size_t)size);
} else {
ulong iblock = i/window;
ulong jblock = (j-1)/window;
if (iblock == 0) {
map(0,cast(size_t)(window*(jblock+2)));
} else {
map(window*(iblock-1),cast(size_t)(window*(jblock-iblock+3)));
}
}
}
}
private:
char[] filename;
void[] data;
ulong start;
size_t window;
ulong size;
Mode mMode;
void* address;
version (Win32)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hFileMap = null;
uint dwDesiredAccess;
}
else version (unix_mm)
{
int fd;
int prot;
int flags;
int fmode;
}
else static if (! Have_MMFile)
{
}
else
{
static assert(0);
}
// Report error, where errno gives the error number
void errNo()
{
version (Win32)
{
throw new FileException(filename, GetLastError());
}
else version (Unix)
{
throw new FileException(filename, getErrno());
}
else static if (! Have_MMFile)
{
throw new FileException(filename, "MMFile unsupported");
}
else
{
static assert(0);
}
}
}
unittest {
static if (Have_MMFile)
{
const size_t K = 1024;
size_t win = 64*K; // assume the page size is 64K
version(Win32) {
/+ these aren't defined in std.c.windows.windows so let's use the default
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
win = sysinfo.dwAllocationGranularity;
+/
} else version (Unix) {
// getpagesize() is not defined in the unix D headers so use the guess
}
MmFile mf = new MmFile("testing.txt",MmFile.Mode.ReadWriteNew,100*K,null,win);
ubyte[] str = cast(ubyte[])"1234567890";
ubyte[] data = cast(ubyte[])mf[0 .. 10];
data[] = str[];
assert( mf[0 .. 10] == str );
data = cast(ubyte[])mf[50 .. 60];
data[] = str[];
assert( mf[50 .. 60] == str );
ubyte[] data2 = cast(ubyte[])mf[20*K .. 60*K];
assert( data2.length == 40*K );
assert( data2[length-1] == 0 );
mf[100*K-1] = cast(ubyte)'b';
data2 = cast(ubyte[])mf[21*K .. 100*K];
assert( data2.length == 79*K );
assert( data2[length-1] == 'b' );
delete mf;
std.file.remove("testing.txt");
}
}

View File

@@ -1,176 +0,0 @@
// Modified for LDC
module std.moduleinit;
//debug = 1;
private
{
import object;
import std.c.stdio;
import std.c.stdlib;
}
enum
{ MIctorstart = 1, // we've started constructing it
MIctordone = 2, // finished construction
MIstandalone = 4, // module ctor does not depend on other module
// ctors being done first
}
// had to move the class to object.d, as its declaration is needed in the compiler code,
// otherwise the DMDFE Module::moduleinfo member is NULL
class ModuleCtorError : Exception
{
this(ModuleInfo m)
{
super("circular initialization dependency with module " ~ m.name);
}
}
// this gets initialized in _moduleCtor()
extern (C) ModuleInfo[] _moduleinfo_array;
// this method returns the linker constructed, null terminated, array of moduleinfos
extern (C) void** _d_get_moduleinfo_array();
ModuleInfo[] _moduleinfo_dtors;
uint _moduleinfo_dtors_i;
// Register termination function pointers
extern (C) int _fatexit(void *);
/*************************************
* Initialize the modules.
*/
extern (C) void _moduleCtor()
{
debug printf("_moduleCtor()\n");
int len = 0;
for (auto mr = _Dmodule_ref; mr; mr=mr.next)
len++;
_moduleinfo_array = new ModuleInfo[len];
len = 0;
for (auto mr = _Dmodule_ref; mr; mr=mr.next)
{ _moduleinfo_array[len] = mr.mod;
len++;
}
version (Win32)
{
// Ensure module destructors also get called on program termination
//_fatexit(&_STD_moduleDtor);
}
_moduleinfo_dtors = new ModuleInfo[len];
debug printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors);
_moduleCtor2(_moduleinfo_array, 0);
version (none)
{
foreach (m; _moduleinfo_array)
{
writefln("module %s, %d", m.name, m.localClasses.length);
foreach (c; m.localClasses)
{
writefln("\tclass %s", c.name);
}
}
}
}
void _moduleCtor2(ModuleInfo[] mi, int skip)
{
debug printf("_moduleCtor2(): %d modules\n", mi.length);
for (uint i = 0; i < mi.length; i++)
{
ModuleInfo m = mi[i];
debug printf("\tmodule[%d] = '%p'\n", i, m);
if (!m)
continue;
debug printf("\tmodule[%d] = '%.*s'\n", i, m.name.length, m.name.ptr);
if (m.flags & MIctordone)
continue;
debug printf("\tmodule[%d] = '%.*s', m = 0x%x\n", i, m.name.length, m.name.ptr, m);
if (m.ctor || m.dtor)
{
if (m.flags & MIctorstart)
{ if (skip || m.flags & MIstandalone)
continue;
debug printf("\tmodule[%d] = '%.*s', cyclic dependency!\n", i, m.name.length, m.name.ptr);
int x = 0; x /= x;
throw new ModuleCtorError(m);
}
m.flags |= MIctorstart;
_moduleCtor2(m.importedModules, 0);
if (m.ctor)
(*m.ctor)();
m.flags &= ~MIctorstart;
m.flags |= MIctordone;
// Now that construction is done, register the destructor
//printf("\tadding module dtor x%x\n", m);
assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length);
_moduleinfo_dtors[_moduleinfo_dtors_i++] = m;
}
else
{
m.flags |= MIctordone;
_moduleCtor2(m.importedModules, 1);
}
}
}
/**********************************
* Destruct the modules.
*/
// Starting the name with "_STD" means under linux a pointer to the
// function gets put in the .dtors segment.
extern (C) void _moduleDtor()
{
debug printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i);
for (uint i = _moduleinfo_dtors_i; i-- != 0;)
{
ModuleInfo m = _moduleinfo_dtors[i];
debug printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m);
if (m.dtor)
{
(*m.dtor)();
}
}
debug printf("_moduleDtor() done\n");
}
/**********************************
* Run unit tests.
*/
extern (C) void _moduleUnitTests()
{
debug printf("_moduleUnitTests() %i\n", _moduleinfo_array.length);
for (uint i = 0; i < _moduleinfo_array.length; i++)
{
ModuleInfo m = _moduleinfo_array[i];
if (!m)
continue;
debug printf("\tmodule[%d] = '%.*s'\n", i, m.name);
if (m.unitTest)
{
(*m.unitTest)();
}
}
}

View File

@@ -1,368 +0,0 @@
// outbuffer.d
/**
* Boilerplate:
* $(std_boilerplate.html)
* Macros:
* WIKI = Phobos/StdOutbuffer
* Copyright:
* Copyright (c) 2001-2005 by Digital Mars
* All Rights Reserved
* www.digitalmars.com
*/
// Written by Walter Bright
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, September 2004
*/
module std.outbuffer;
private
{
import std.string;
import std.gc;
import std.c.stdio;
import std.c.stdlib;
import std.c.stdarg;
}
/*********************************************
* OutBuffer provides a way to build up an array of bytes out
* of raw data. It is useful for things like preparing an
* array of bytes to write out to a file.
* OutBuffer's byte order is the format native to the computer.
* To control the byte order (endianness), use a class derived
* from OutBuffer.
*/
class OutBuffer
{
ubyte data[];
size_t offset;
invariant
{
//printf("this = %p, offset = %x, data.length = %u\n", this, offset, data.length);
assert(offset <= data.length);
assert(data.length <= std.gc.capacity(data.ptr));
}
this()
{
//printf("in OutBuffer constructor\n");
}
/*********************************
* Convert to array of bytes.
*/
ubyte[] toBytes() { return data[0 .. offset]; }
/***********************************
* Preallocate nbytes more to the size of the internal buffer.
*
* This is a
* speed optimization, a good guess at the maximum size of the resulting
* buffer will improve performance by eliminating reallocations and copying.
*/
void reserve(size_t nbytes)
in
{
assert(offset + nbytes >= offset);
}
out
{
assert(offset + nbytes <= data.length);
assert(data.length <= std.gc.capacity(data.ptr));
}
body
{
if (data.length < offset + nbytes)
{
//std.c.stdio.printf("OutBuffer.reserve: ptr = %p, length = %d, offset = %d, nbytes = %d, capacity = %d\n", data.ptr, data.length, offset, nbytes, std.gc.capacity(data.ptr));
data.length = (offset + nbytes) * 2;
//std.c.stdio.printf("OutBuffer.reserve: ptr = %p, length = %d, capacity = %d\n", data.ptr, data.length, std.gc.capacity(data.ptr));
std.gc.hasPointers(data.ptr);
}
}
/*************************************
* Append data to the internal buffer.
*/
void write(ubyte[] bytes)
{
reserve(bytes.length);
data[offset .. offset + bytes.length] = bytes;
offset += bytes.length;
}
void write(ubyte b) /// ditto
{
reserve(ubyte.sizeof);
this.data[offset] = b;
offset += ubyte.sizeof;
}
void write(byte b) { write(cast(ubyte)b); } /// ditto
void write(char c) { write(cast(ubyte)c); } /// ditto
void write(ushort w) /// ditto
{
reserve(ushort.sizeof);
*cast(ushort *)&data[offset] = w;
offset += ushort.sizeof;
}
void write(short s) { write(cast(ushort)s); } /// ditto
void write(wchar c) /// ditto
{
reserve(wchar.sizeof);
*cast(wchar *)&data[offset] = c;
offset += wchar.sizeof;
}
void write(uint w) /// ditto
{
reserve(uint.sizeof);
*cast(uint *)&data[offset] = w;
offset += uint.sizeof;
}
void write(int i) { write(cast(uint)i); } /// ditto
void write(ulong l) /// ditto
{
reserve(ulong.sizeof);
*cast(ulong *)&data[offset] = l;
offset += ulong.sizeof;
}
void write(long l) { write(cast(ulong)l); } /// ditto
void write(float f) /// ditto
{
reserve(float.sizeof);
*cast(float *)&data[offset] = f;
offset += float.sizeof;
}
void write(double f) /// ditto
{
reserve(double.sizeof);
*cast(double *)&data[offset] = f;
offset += double.sizeof;
}
void write(real f) /// ditto
{
reserve(real.sizeof);
*cast(real *)&data[offset] = f;
offset += real.sizeof;
}
void write(char[] s) /// ditto
{
write(cast(ubyte[])s);
}
void write(OutBuffer buf) /// ditto
{
write(buf.toBytes());
}
/****************************************
* Append nbytes of 0 to the internal buffer.
*/
void fill0(uint nbytes)
{
reserve(nbytes);
data[offset .. offset + nbytes] = 0;
offset += nbytes;
}
/**********************************
* 0-fill to align on power of 2 boundary.
*/
void alignSize(size_t alignsize)
in
{
assert(alignsize && (alignsize & (alignsize - 1)) == 0);
}
out
{
assert((offset & (alignsize - 1)) == 0);
}
body
{ size_t nbytes;
nbytes = offset & (alignsize - 1);
if (nbytes)
fill0(alignsize - nbytes);
}
/****************************************
* Optimize common special case alignSize(2)
*/
void align2()
{
if (offset & 1)
write(cast(byte)0);
}
/****************************************
* Optimize common special case alignSize(4)
*/
void align4()
{
if (offset & 3)
{ size_t nbytes = (4 - offset) & 3;
fill0(nbytes);
}
}
/**************************************
* Convert internal buffer to array of chars.
*/
char[] toString()
{
//printf("OutBuffer.toString()\n");
return cast(char[])data[0 .. offset];
}
/*****************************************
* Append output of C's vprintf() to internal buffer.
*/
void vprintf(char[] format, va_list args)
{
char[128] buffer;
char* p;
char* f;
uint psize;
int count;
va_list args_copy;
f = toStringz(format);
p = buffer.ptr;
psize = buffer.length;
for (;;)
{
va_copy(args_copy, args);
version(Win32)
{
count = _vsnprintf(p,psize,f,args_copy);
if (count != -1)
break;
psize *= 2;
p = cast(char *) /*alloca*/malloc(psize); // buffer too small, try again with larger size
}
else version(GNU) {
count = vsnprintf(p,psize,f,args_copy);
if (count == -1)
psize *= 2;
else if (count >= psize)
psize = count + 1;
else
break;
p = cast(char *) /*alloca*/std.gc.malloc(psize); // buffer too small, try again with larger size
}
else version(linux)
{
count = vsnprintf(p,psize,f,args_copy);
if (count == -1)
psize *= 2;
else if (count >= psize)
psize = count + 1;
else
break;
/+
if (p != buffer)
c.stdlib.free(p);
p = (char *) c.stdlib.malloc(psize); // buffer too small, try again with larger size
+/
p = cast(char *) /*alloca*/std.gc.malloc(psize); // buffer too small, try again with larger size
}
}
write(p[0 .. count]);
/+
version (linux)
{
if (p != buffer)
c.stdlib.free(p);
}
+/
}
/*****************************************
* Append output of C's printf() to internal buffer.
*/
void printf(char[] format, ...)
{
version (GNU)
{
vprintf(format, _argptr);
}
else
{
va_list ap;
ap = cast(va_list)&format;
ap += format.sizeof;
vprintf(format, ap);
}
}
/*****************************************
* At offset index into buffer, create nbytes of space by shifting upwards
* all data past index.
*/
void spread(size_t index, size_t nbytes)
in
{
assert(index <= offset);
}
body
{
reserve(nbytes);
// This is an overlapping copy - should use memmove()
for (size_t i = offset; i > index; )
{
--i;
data[i + nbytes] = data[i];
}
offset += nbytes;
}
}
unittest
{
//printf("Starting OutBuffer test\n");
OutBuffer buf = new OutBuffer();
//printf("buf = %p\n", buf);
//printf("buf.offset = %x\n", buf.offset);
assert(buf.offset == 0);
buf.write("hello");
buf.write(cast(byte)0x20);
buf.write("world");
buf.printf(" %d", 6);
//printf("buf = '%.*s'\n", buf.toString());
assert(cmp(buf.toString(), "hello world 6") == 0);
}

View File

@@ -1,45 +0,0 @@
/**
* Macros:
* WIKI=Phobos/StdOutOfMemory
* Copyright:
* Placed into public domain.
* www.digitalmars.com
*/
module std.outofmemory;
/******
* This exception is thrown when out of memory errors happen.
*/
class OutOfMemoryException : Exception
{
static char[] s = "Out of memory";
/**
* Default constructor
*/
this()
{
super(s);
}
char[] toString()
{
return s;
}
}
extern (C) void _d_OutOfMemory()
{
printf("Out of memory!\n");
*(cast(int*) 0) = 0;
throw cast(OutOfMemoryException)
cast(void *)
OutOfMemoryException.classinfo.init;
}
static this()
{
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,295 +0,0 @@
/*
* Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com
* Written by Matthew Wilson and Walter Bright
*
* Incorporating idea (for execvpe() on Linux) from Russ Lewis
*
* Updated: 21st August 2004
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, October 2004
*/
/**
* Macros:
* WIKI=Phobos/StdProcess
*/
module std.process;
private import std.c.stdlib;
private import std.c.string;
private import std.string;
private import std.c.process;
version(linux) version = Unix;
/**
* Execute command in a _command shell.
*
* Returns: exit status of command
*/
int system(char[] command)
{
return std.c.process.system(toStringz(command));
}
private void toAStringz(char[][] a, char**az)
{
foreach(char[] s; a)
{
*az++ = toStringz(s);
}
*az = null;
}
/* ========================================================== */
//version (Windows)
//{
// int spawnvp(int mode, char[] pathname, char[][] argv)
// {
// char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length));
//
// toAStringz(argv, argv_);
//
// return std.c.process.spawnvp(mode, toStringz(pathname), argv_);
// }
//}
// Incorporating idea (for spawnvp() on linux) from Dave Fladebo
alias std.c.process._P_WAIT P_WAIT;
alias std.c.process._P_NOWAIT P_NOWAIT;
int spawnvp(int mode, char[] pathname, char[][] argv)
{
char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length));
toAStringz(argv, argv_);
version(Unix)
{
return _spawnvp(mode, toStringz(pathname), argv_);
}
else
{
return std.c.process.spawnvp(mode, toStringz(pathname), argv_);
}
}
version(Unix)
{
version(linux) import std.c.linux.linux;
else import std.c.unix.unix;
int _spawnvp(int mode, char *pathname, char **argv)
{
int retval = 0;
pid_t pid = fork();
if(!pid)
{ // child
std.c.process.execvp(pathname, argv);
goto Lerror;
}
else if(pid > 0)
{ // parent
if(mode == _P_NOWAIT)
{
retval = pid; // caller waits
}
else
{
while(1)
{
int status;
pid_t wpid = waitpid(pid, &status, 0);
if(exited(status))
{
retval = exitstatus(status);
break;
}
else if(signaled(status))
{
retval = -termsig(status);
break;
}
else if(stopped(status)) // ptrace support
continue;
else
goto Lerror;
}
}
return retval;
}
Lerror:
retval = getErrno;
throw new Exception(
"Cannot spawn " ~ toString(pathname) ~ "; "
~ toString(strerror(retval))
~ " [errno " ~ toString(retval) ~ "]");
} // _spawnvp
private
{
bool stopped(int status) { return cast(bool)((status & 0xff) == 0x7f); }
bool signaled(int status) { return cast(bool)((cast(char)((status & 0x7f) + 1) >> 1) > 0); }
int termsig(int status) { return status & 0x7f; }
bool exited(int status) { return cast(bool)((status & 0x7f) == 0); }
int exitstatus(int status) { return (status & 0xff00) >> 8; }
} // private
} // version(linux)
/* ========================================================== */
/**
* Execute program specified by pathname, passing it the arguments (argv)
* and the environment (envp), returning the exit status.
* The 'p' versions of exec search the PATH environment variable
* setting for the program.
*/
int execv(char[] pathname, char[][] argv)
{
char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length));
toAStringz(argv, argv_);
return std.c.process.execv(toStringz(pathname), argv_);
}
/** ditto */
int execve(char[] pathname, char[][] argv, char[][] envp)
{
char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length));
char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length));
toAStringz(argv, argv_);
toAStringz(envp, envp_);
return std.c.process.execve(toStringz(pathname), argv_, envp_);
}
/** ditto */
int execvp(char[] pathname, char[][] argv)
{
char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length));
toAStringz(argv, argv_);
return std.c.process.execvp(toStringz(pathname), argv_);
}
/** ditto */
int execvpe(char[] pathname, char[][] argv, char[][] envp)
{
version (GNU_Need_execvpe)
{
// Is pathname rooted?
if(pathname[0] == '/')
{
// Yes, so just call execve()
return execve(pathname, argv, envp);
}
else
{
// No, so must traverse PATHs, looking for first match
char[][] envPaths = std.string.split(std.string.toString(std.c.stdlib.getenv("PATH")), ":");
int iRet = 0;
// Note: if any call to execve() succeeds, this process will cease
// execution, so there's no need to check the execve() result through
// the loop.
foreach(char[] pathDir; envPaths)
{
char[] composite = pathDir ~ "/" ~ pathname;
iRet = execve(composite, argv, envp);
}
if(0 != iRet)
{
iRet = execve(pathname, argv, envp);
}
return iRet;
}
}
else version(Windows)
{
char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length));
char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length));
toAStringz(argv, argv_);
toAStringz(envp, envp_);
return std.c.process.execvpe(toStringz(pathname), argv_, envp_);
}
else
{
throw new Exception("Not supported on this platform.");
} // version
}
/* ////////////////////////////////////////////////////////////////////////// */
version(MainTest)
{
int main(char[][] args)
{
if(args.length < 2)
{
printf("Must supply executable (and optional arguments)\n");
return 1;
}
else
{
char[][] dummy_env;
dummy_env ~= "VAL0=value";
dummy_env ~= "VAL1=value";
/+
foreach(char[] arg; args)
{
printf("%.*s\n", arg);
}
+/
// int i = execv(args[1], args[1 .. args.length]);
// int i = execvp(args[1], args[1 .. args.length]);
int i = execvpe(args[1], args[1 .. args.length], dummy_env);
printf("exec??() has returned! Error code: %d; errno: %d\n", i, /* std.c.stdlib.getErrno() */-1);
return 0;
}
}
}
/* ////////////////////////////////////////////////////////////////////////// */

View File

@@ -1,163 +0,0 @@
/**
* Macros:
* WIKI = Phobos/StdRandom
*/
// random.d
// www.digitalmars.com
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, September 2007
*/
module std.random;
// Segments of the code in this file Copyright (c) 1997 by Rick Booth
// From "Inner Loops" by Rick Booth, Addison-Wesley
version(linux) version = Unix;
version (Win32)
{
extern(Windows) int QueryPerformanceCounter(ulong *count);
}
else version (Unix)
{
version(linux) import std.c.linux.linux;
else private import std.c.unix.unix;
}
/* ===================== Random ========================= */
// BUG: not multithreaded
private uint seed; // starting seed
private uint index; // ith random number
/**
* The random number generator is seeded at program startup with a random value.
This ensures that each program generates a different sequence of random
numbers. To generate a repeatable sequence, use rand_seed() to start the
sequence. seed and index start it, and each successive value increments index.
This means that the $(I n)th random number of the sequence can be directly
generated
by passing index + $(I n) to rand_seed().
Note: This is more random, but slower, than C's rand() function.
To use C's rand() instead, import std.c.stdlib.
*/
void rand_seed(uint seed, uint index)
{
.seed = seed;
.index = index;
}
/**
* Get the next random number in sequence.
* BUGS: shares a global single state, not multithreaded
*/
uint rand()
{
static uint xormix1[20] =
[
0xbaa96887, 0x1e17d32c, 0x03bcdc3c, 0x0f33d1b2,
0x76a6491d, 0xc570d85d, 0xe382b1e3, 0x78db4362,
0x7439a9d4, 0x9cea8ac5, 0x89537c5c, 0x2588f55d,
0x415b5e1d, 0x216e3d95, 0x85c662e7, 0x5e8ab368,
0x3ea5cc8c, 0xd26a0f74, 0xf3a9222b, 0x48aad7e4
];
static uint xormix2[20] =
[
0x4b0f3b58, 0xe874f0c3, 0x6955c5a6, 0x55a7ca46,
0x4d9a9d86, 0xfe28a195, 0xb1ca7865, 0x6b235751,
0x9a997a61, 0xaa6e95c8, 0xaaa98ee1, 0x5af9154c,
0xfc8e2263, 0x390f5e8c, 0x58ffd802, 0xac0a5eba,
0xac4874f6, 0xa9df0913, 0x86be4c74, 0xed2c123b
];
uint hiword, loword, hihold, temp, itmpl, itmph, i;
loword = seed;
hiword = index++;
for (i = 0; i < 4; i++) // loop limit can be 2..20, we choose 4
{
hihold = hiword; // save hiword for later
temp = hihold ^ xormix1[i]; // mix up bits of hiword
itmpl = temp & 0xffff; // decompose to hi & lo
itmph = temp >> 16; // 16-bit words
temp = itmpl * itmpl + ~(itmph * itmph); // do a multiplicative mix
temp = (temp >> 16) | (temp << 16); // swap hi and lo halves
hiword = loword ^ ((temp ^ xormix2[i]) + itmpl * itmph); //loword mix
loword = hihold; // old hiword is loword
}
return hiword;
}
static this()
{
ulong s;
version(Win32)
{
QueryPerformanceCounter(&s);
}
else version(Unix)
{
// time.h
// sys/time.h
timeval tv;
if (gettimeofday(&tv, null))
{ // Some error happened - try time() instead
s = time(null);
}
else
{
s = cast(ulong)((cast(long)tv.tv_sec << 32) + tv.tv_usec);
}
}
else version(NoSystem)
{
// nothing
}
else
static assert(false);
rand_seed(cast(uint) s, cast(uint)(s >> 32));
}
unittest
{
static uint results[10] =
[
0x8c0188cb,
0xb161200c,
0xfc904ac5,
0x2702e049,
0x9705a923,
0x1c139d89,
0x346b6d1f,
0xf8c33e32,
0xdb9fef76,
0xa97fcb3f
];
int i;
uint seedsave = seed;
uint indexsave = index;
rand_seed(1234, 5678);
for (i = 0; i < 10; i++)
{ uint r = rand();
//printf("0x%x,\n", rand());
assert(r == results[i]);
}
seed = seedsave;
index = indexsave;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +0,0 @@
/*
* Placed in public domain.
* Written by Hauke Duden and Walter Bright
*/
/* This is for use with variable argument lists with extern(D) linkage. */
/* Modified for LDC (LLVM D Compiler) by Tomas Lindquist Olsen, 2007 */
module std.stdarg;
alias void* va_list;
T va_arg(T)(ref va_list vp)
{
size_t size = T.sizeof > size_t.sizeof ? size_t.sizeof : T.sizeof;
va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) & ~(size - 1));
vp = vptmp + T.sizeof;
return *cast(T*)vptmp;
}

View File

@@ -1,177 +0,0 @@
/**
*
D constrains integral types to specific sizes. But efficiency
of different sizes varies from machine to machine,
pointer sizes vary, and the maximum integer size varies.
<b>stdint</b> offers a portable way of trading off size
vs efficiency, in a manner compatible with the <tt>stdint.h</tt>
definitions in C.
The exact aliases are types of exactly the specified number of bits.
The at least aliases are at least the specified number of bits
large, and can be larger.
The fast aliases are the fastest integral type supported by the
processor that is at least as wide as the specified number of bits.
The aliases are:
<table border=1 cellspacing=0 cellpadding=5>
<th>Exact Alias
<th>Description
<th>At Least Alias
<th>Description
<th>Fast Alias
<th>Description
<tr>
<td>int8_t
<td>exactly 8 bits signed
<td>int_least8_t
<td>at least 8 bits signed
<td>int_fast8_t
<td>fast 8 bits signed
<tr>
<td>uint8_t
<td>exactly 8 bits unsigned
<td>uint_least8_t
<td>at least 8 bits unsigned
<td>uint_fast8_t
<td>fast 8 bits unsigned
<tr>
<td>int16_t
<td>exactly 16 bits signed
<td>int_least16_t
<td>at least 16 bits signed
<td>int_fast16_t
<td>fast 16 bits signed
<tr>
<td>uint16_t
<td>exactly 16 bits unsigned
<td>uint_least16_t
<td>at least 16 bits unsigned
<td>uint_fast16_t
<td>fast 16 bits unsigned
<tr>
<td>int32_t
<td>exactly 32 bits signed
<td>int_least32_t
<td>at least 32 bits signed
<td>int_fast32_t
<td>fast 32 bits signed
<tr>
<td>uint32_t
<td>exactly 32 bits unsigned
<td>uint_least32_t
<td>at least 32 bits unsigned
<td>uint_fast32_t
<td>fast 32 bits unsigned
<tr>
<td>int64_t
<td>exactly 64 bits signed
<td>int_least64_t
<td>at least 64 bits signed
<td>int_fast64_t
<td>fast 64 bits signed
<tr>
<td>uint64_t
<td>exactly 64 bits unsigned
<td>uint_least64_t
<td>at least 64 bits unsigned
<td>uint_fast64_t
<td>fast 64 bits unsigned
</table>
The ptr aliases are integral types guaranteed to be large enough
to hold a pointer without losing bits:
<table border=1 cellspacing=0 cellpadding=5>
<th>Alias
<th>Description
<tr>
<td>intptr_t
<td>signed integral type large enough to hold a pointer
<tr>
<td>uintptr_t
<td>unsigned integral type large enough to hold a pointer
</table>
The max aliases are the largest integral types:
<table border=1 cellspacing=0 cellpadding=5>
<th>Alias
<th>Description
<tr>
<td>intmax_t
<td>the largest signed integral type
<tr>
<td>uintmax_t
<td>the largest unsigned integral type
</table>
* Authors: Walter Bright, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI=Phobos/StdStdint
*/
/*
NOTE: This file has been patched from the original DMD distribution to
work with the LDC compiler.
Modified by Tomas Lindquist Olsen, August 2007
*/
module std.stdint;
/* Exact sizes */
alias byte int8_t;
alias ubyte uint8_t;
alias short int16_t;
alias ushort uint16_t;
alias int int32_t;
alias uint uint32_t;
alias long int64_t;
alias ulong uint64_t;
/* At least sizes */
alias byte int_least8_t;
alias ubyte uint_least8_t;
alias short int_least16_t;
alias ushort uint_least16_t;
alias int int_least32_t;
alias uint uint_least32_t;
alias long int_least64_t;
alias ulong uint_least64_t;
/* Fastest minimum width sizes */
alias byte int_fast8_t;
alias ubyte uint_fast8_t;
alias int int_fast16_t;
alias uint uint_fast16_t;
alias int int_fast32_t;
alias uint uint_fast32_t;
alias long int_fast64_t;
alias ulong uint_fast64_t;
/* Integer pointer holders */
version(LLVM64) {
alias long intptr_t;
alias ulong uintptr_t;
}
else {
alias int intptr_t;
alias uint uintptr_t;
}
/* Greatest width integer types */
alias long intmax_t;
alias ulong uintmax_t;

View File

@@ -1,548 +0,0 @@
// Written in the D programming language.
/* Written by Walter Bright and Andrei Alexandrescu
* www.digitalmars.com
* Placed in the Public Domain.
*/
/********************************
* Standard I/O functions that extend $(B std.c.stdio).
* $(B std.c.stdio) is automatically imported when importing
* $(B std.stdio).
* Macros:
* WIKI=Phobos/StdStdio
*/
module std.stdio;
public import std.c.stdio;
import std.format;
import std.utf;
import std.string;
import std.gc;
import std.c.stdlib;
import std.c.string;
import std.c.stddef;
version (DigitalMars)
{
version (Windows)
{
// Specific to the way Digital Mars C does stdio
version = DIGITAL_MARS_STDIO;
}
}
version (DIGITAL_MARS_STDIO)
{
}
else
{
// Specific to the way Gnu C does stdio
version = GCC_IO;
import std.c.linux.linux;
}
version (DIGITAL_MARS_STDIO)
{
extern (C)
{
/* **
* Digital Mars under-the-hood C I/O functions
*/
int _fputc_nlock(int, FILE*);
int _fputwc_nlock(int, FILE*);
int _fgetc_nlock(FILE*);
int _fgetwc_nlock(FILE*);
int __fp_lock(FILE*);
void __fp_unlock(FILE*);
}
alias _fputc_nlock FPUTC;
alias _fputwc_nlock FPUTWC;
alias _fgetc_nlock FGETC;
alias _fgetwc_nlock FGETWC;
alias __fp_lock FLOCK;
alias __fp_unlock FUNLOCK;
}
else version (GCC_IO)
{
/* **
* Gnu under-the-hood C I/O functions; see
* http://www.gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html#I_002fO-on-Streams
*/
extern (C)
{
int fputc_unlocked(int, FILE*);
int fputwc_unlocked(wchar_t, FILE*);
int fgetc_unlocked(FILE*);
int fgetwc_unlocked(FILE*);
void flockfile(FILE*);
void funlockfile(FILE*);
ssize_t getline(char**, size_t*, FILE*);
ssize_t getdelim (char**, size_t*, int, FILE*);
}
alias fputc_unlocked FPUTC;
alias fputwc_unlocked FPUTWC;
alias fgetc_unlocked FGETC;
alias fgetwc_unlocked FGETWC;
alias flockfile FLOCK;
alias funlockfile FUNLOCK;
}
else
{
static assert(0, "unsupported C I/O system");
}
/*********************
* Thrown if I/O errors happen.
*/
class StdioException : Exception
{
uint errno; // operating system error code
this(char[] msg)
{
super(msg);
}
this(uint errno)
{ char* s = strerror(errno);
super(std.string.toString(s).dup);
}
static void opCall(char[] msg)
{
throw new StdioException(msg);
}
static void opCall()
{
throw new StdioException(getErrno());
}
}
private
void writefx(FILE* fp, TypeInfo[] arguments, void* argptr, int newline=false)
{ int orientation;
orientation = fwide(fp, 0);
/* Do the file stream locking at the outermost level
* rather than character by character.
*/
FLOCK(fp);
scope(exit) FUNLOCK(fp);
if (orientation <= 0) // byte orientation or no orientation
{
void putc(dchar c)
{
if (c <= 0x7F)
{
FPUTC(c, fp);
}
else
{ char[4] buf;
char[] b;
b = std.utf.toUTF8(buf, c);
for (size_t i = 0; i < b.length; i++)
FPUTC(b[i], fp);
}
}
std.format.doFormat(&putc, arguments, argptr);
if (newline)
FPUTC('\n', fp);
}
else if (orientation > 0) // wide orientation
{
version (Windows)
{
void putcw(dchar c)
{
assert(isValidDchar(c));
if (c <= 0xFFFF)
{
FPUTWC(c, fp);
}
else
{ wchar[2] buf;
buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
FPUTWC(buf[0], fp);
FPUTWC(buf[1], fp);
}
}
}
else version (linux)
{
void putcw(dchar c)
{
FPUTWC(c, fp);
}
}
else
{
static assert(0);
}
std.format.doFormat(&putcw, arguments, argptr);
if (newline)
FPUTWC('\n', fp);
}
}
/***********************************
* Arguments are formatted per the
* $(LINK2 std_format.html#format-string, format strings)
* and written to $(B stdout).
*/
void writef(...)
{
writefx(stdout, _arguments, _argptr, 0);
}
/***********************************
* Same as $(B writef), but a newline is appended
* to the output.
*/
void writefln(...)
{
writefx(stdout, _arguments, _argptr, 1);
}
/***********************************
* Same as $(B writef), but output is sent to the
* stream fp instead of $(B stdout).
*/
void fwritef(FILE* fp, ...)
{
writefx(fp, _arguments, _argptr, 0);
}
/***********************************
* Same as $(B writefln), but output is sent to the
* stream fp instead of $(B stdout).
*/
void fwritefln(FILE* fp, ...)
{
writefx(fp, _arguments, _argptr, 1);
}
/**********************************
* Read line from stream fp.
* Returns:
* null for end of file,
* char[] for line read from fp, including terminating '\n'
* Params:
* fp = input stream
* Throws:
* $(B StdioException) on error
* Example:
* Reads $(B stdin) and writes it to $(B stdout).
---
import std.stdio;
int main()
{
char[] buf;
while ((buf = readln()) != null)
writef("%s", buf);
return 0;
}
---
*/
char[] readln(FILE* fp = stdin)
{
char[] buf;
readln(fp, buf);
return buf;
}
/**********************************
* Read line from stream fp and write it to buf[],
* including terminating '\n'.
*
* This is often faster than readln(FILE*) because the buffer
* is reused each call. Note that reusing the buffer means that
* the previous contents of it need to be copied if needed.
* Params:
* fp = input stream
* buf = buffer used to store the resulting line data. buf
* is resized as necessary.
* Returns:
* 0 for end of file, otherwise
* number of characters read
* Throws:
* $(B StdioException) on error
* Example:
* Reads $(B stdin) and writes it to $(B stdout).
---
import std.stdio;
int main()
{
char[] buf;
while (readln(stdin, buf))
writef("%s", buf);
return 0;
}
---
*/
size_t readln(FILE* fp, inout char[] buf)
{
version (DIGITAL_MARS_STDIO)
{
FLOCK(fp);
scope(exit) FUNLOCK(fp);
if (__fhnd_info[fp._file] & FHND_WCHAR)
{ /* Stream is in wide characters.
* Read them and convert to chars.
*/
static assert(wchar_t.sizeof == 2);
buf.length = 0;
int c2;
for (int c; (c = FGETWC(fp)) != -1; )
{
if ((c & ~0x7F) == 0)
{ buf ~= c;
if (c == '\n')
break;
}
else
{
if (c >= 0xD800 && c <= 0xDBFF)
{
if ((c2 = FGETWC(fp)) != -1 ||
c2 < 0xDC00 && c2 > 0xDFFF)
{
StdioException("unpaired UTF-16 surrogate");
}
c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
std.utf.encode(buf, c);
}
}
if (ferror(fp))
StdioException();
return buf.length;
}
auto sz = std.gc.capacity(buf.ptr);
//auto sz = buf.length;
buf = buf.ptr[0 .. sz];
if (fp._flag & _IONBF)
{
/* Use this for unbuffered I/O, when running
* across buffer boundaries, or for any but the common
* cases.
*/
L1:
char *p;
if (sz)
{
p = buf.ptr;
}
else
{
sz = 64;
p = cast(char*) std.gc.malloc(sz);
std.gc.hasNoPointers(p);
buf = p[0 .. sz];
}
size_t i = 0;
for (int c; (c = FGETC(fp)) != -1; )
{
if ((p[i] = c) != '\n')
{
i++;
if (i < sz)
continue;
buf = p[0 .. i] ~ readln(fp);
return buf.length;
}
else
{
buf = p[0 .. i + 1];
return i + 1;
}
}
if (ferror(fp))
StdioException();
buf = p[0 .. i];
return i;
}
else
{
int u = fp._cnt;
char* p = fp._ptr;
int i;
if (fp._flag & _IOTRAN)
{ /* Translated mode ignores \r and treats ^Z as end-of-file
*/
char c;
while (1)
{
if (i == u) // if end of buffer
goto L1; // give up
c = p[i];
i++;
if (c != '\r')
{
if (c == '\n')
break;
if (c != 0x1A)
continue;
goto L1;
}
else
{ if (i != u && p[i] == '\n')
break;
goto L1;
}
}
if (i > sz)
{
buf = cast(char[])std.gc.malloc(i);
std.gc.hasNoPointers(buf.ptr);
}
if (i - 1)
memcpy(buf.ptr, p, i - 1);
buf[i - 1] = '\n';
if (c == '\r')
i++;
}
else
{
while (1)
{
if (i == u) // if end of buffer
goto L1; // give up
auto c = p[i];
i++;
if (c == '\n')
break;
}
if (i > sz)
{
buf = cast(char[])std.gc.malloc(i);
std.gc.hasNoPointers(buf.ptr);
}
memcpy(buf.ptr, p, i);
}
fp._cnt -= i;
fp._ptr += i;
buf = buf[0 .. i];
return i;
}
}
else version (GCC_IO)
{
if (fwide(fp, 0) > 0)
{ /* Stream is in wide characters.
* Read them and convert to chars.
*/
FLOCK(fp);
scope(exit) FUNLOCK(fp);
version (Windows)
{
buf.length = 0;
int c2;
for (int c; (c = FGETWC(fp)) != -1; )
{
if ((c & ~0x7F) == 0)
{ buf ~= c;
if (c == '\n')
break;
}
else
{
if (c >= 0xD800 && c <= 0xDBFF)
{
if ((c2 = FGETWC(fp)) != -1 ||
c2 < 0xDC00 && c2 > 0xDFFF)
{
StdioException("unpaired UTF-16 surrogate");
}
c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
}
std.utf.encode(buf, c);
}
}
if (ferror(fp))
StdioException();
return buf.length;
}
else version (linux)
{
buf.length = 0;
for (int c; (c = FGETWC(fp)) != -1; )
{
if ((c & ~0x7F) == 0)
buf ~= c;
else
std.utf.encode(buf, cast(dchar)c);
if (c == '\n')
break;
}
if (ferror(fp))
StdioException();
return buf.length;
}
else
{
static assert(0);
}
}
char *lineptr = null;
size_t n = 0;
auto s = getdelim(&lineptr, &n, '\n', fp);
scope(exit) free(lineptr);
if (s < 0)
{
if (ferror(fp))
StdioException();
buf.length = 0; // end of file
return 0;
}
buf = buf.ptr[0 .. std.gc.capacity(buf.ptr)];
if (s <= buf.length)
{
buf.length = s;
buf[] = lineptr[0 .. s];
}
else
{
buf = lineptr[0 .. s].dup;
}
return s;
}
else
{
static assert(0);
}
}
/** ditto */
size_t readln(inout char[] buf)
{
return readln(stdin, buf);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,95 +0,0 @@
// Written in the D programming language
/**
* Information about the target operating system, environment, and CPU
* Authors: Walter Bright, www.digitalmars.com
* License: Public Domain
* Macros:
* WIKI = Phobos/StdSystem
*/
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, September 2007
*/
// Information about the target operating system, environment, and CPU
module std.system;
const
{
// Operating system family
enum Family
{
Win32 = 1, // Microsoft 32 bit Windows systems
linux, // all linux systems
Unix, // Unix-like
NoSystem // No operating system
}
version (Win32)
{
Family family = Family.Win32;
}
else version (linux)
{
Family family = Family.linux;
}
else version (Unix)
{
Family family = Family.Unix;
}
else version (NoSystem)
{
Family family = Family.NoSystem;
}
else
{
static assert(0);
}
// More specific operating system name
enum OS
{
Windows95 = 1,
Windows98,
WindowsME,
WindowsNT,
Windows2000,
WindowsXP,
RedHatLinux,
}
/// Byte order endianness
enum Endian
{
BigEndian, /// big endian byte order
LittleEndian /// little endian byte order
}
version(LittleEndian)
{
/// Native system endianness
Endian endian = Endian.LittleEndian;
}
else
{
Endian endian = Endian.BigEndian;
}
}
// The rest should get filled in dynamically at runtime
OS os = OS.WindowsXP;
// Operating system version as in
// os_major.os_minor
uint os_major = 4;
uint os_minor = 0;

File diff suppressed because it is too large Load Diff

View File

@@ -1,166 +0,0 @@
// Written in the D programming language.
/**
* Templates with which to extract information about
* types at compile time.
*
* Macros:
* WIKI = Phobos/StdTraits
* Copyright:
* Public Domain
*/
/*
* Authors:
* Walter Bright, Digital Mars, www.digitalmars.com
* Tomasz Stachowiak (isStaticArray, isExpressionTuple)
*/
module std.traits;
/***
* Get the type of the return value from a function,
* a pointer to function, or a delegate.
* Example:
* ---
* import std.traits;
* int foo();
* ReturnType!(foo) x; // x is declared as int
* ---
*/
template ReturnType(alias dg)
{
alias ReturnType!(typeof(dg)) ReturnType;
}
/** ditto */
template ReturnType(dg)
{
static if (is(dg R == return))
alias R ReturnType;
else
static assert(0, "argument has no return type");
}
/***
* Get the types of the paramters to a function,
* a pointer to function, or a delegate as a tuple.
* Example:
* ---
* import std.traits;
* int foo(int, long);
* void bar(ParameterTypeTuple!(foo)); // declares void bar(int, long);
* void abc(ParameterTypeTuple!(foo)[1]); // declares void abc(long);
* ---
*/
template ParameterTypeTuple(alias dg)
{
alias ParameterTypeTuple!(typeof(dg)) ParameterTypeTuple;
}
/** ditto */
template ParameterTypeTuple(dg)
{
static if (is(dg P == function))
alias P ParameterTypeTuple;
else static if (is(dg P == delegate))
alias ParameterTypeTuple!(P) ParameterTypeTuple;
else static if (is(dg P == P*))
alias ParameterTypeTuple!(P) ParameterTypeTuple;
else
static assert(0, "argument has no parameters");
}
/***
* Get the types of the fields of a struct or class.
* This consists of the fields that take up memory space,
* excluding the hidden fields like the virtual function
* table pointer.
*/
template FieldTypeTuple(S)
{
static if (is(S == struct) || is(S == class))
alias typeof(S.tupleof) FieldTypeTuple;
else
static assert(0, "argument is not struct or class");
}
/***
* Get a TypeTuple of the base class and base interfaces of
* this class or interface.
* Example:
* ---
* import std.traits, std.typetuple, std.stdio;
* interface I { }
* class A { }
* class B : A, I { }
*
* void main()
* {
* alias BaseTypeTuple!(B) TL;
* writefln(typeid(TL)); // prints: (A,I)
* }
* ---
*/
template BaseTypeTuple(A)
{
static if (is(A P == super))
alias P BaseTypeTuple;
else
static assert(0, "argument is not a class or interface");
}
unittest
{
interface I { }
class A { }
class B : A, I { }
alias BaseTypeTuple!(B) TL;
assert(TL.length == 2);
assert(is (TL[0] == A));
assert(is (TL[1] == I));
}
/**
* Detect whether type T is a static array.
*/
template isStaticArray(T)
{
static if (isArray!(T))
const bool isStaticArray = !is(T == typeof(T[0])[]);
else const bool isStaticArray = false;
}
static assert (isStaticArray!(int[51]));
static assert (isStaticArray!(int[][2]));
//static assert (isStaticArray!(char[][int][11]));
static assert (!isStaticArray!(int[]));
//static assert (!isStaticArray!(int[char]));
static assert (!isStaticArray!(int[1][]));
template isArray(T)
{
const bool isArray=false;
}
template isArray(T: T[])
{
const bool isArray=true;
}
/**
* Tells whether the tuple T is an expression tuple.
*/
template isExpressionTuple(T ...)
{
static if (is(void function(T)))
const bool isExpressionTuple = false;
else
const bool isExpressionTuple = true;
}

View File

@@ -1,630 +0,0 @@
// Written in the D programming language.
/*
* Placed into the Public Domain.
* Digital Mars, www.digitalmars.com
* Written by Walter Bright
*/
/**
* Simple Unicode character classification functions.
* For ASCII classification, see $(LINK2 std_ctype.html, std.ctype).
* Macros:
* WIKI=Phobos/StdUni
* References:
* $(LINK2 http://www.digitalmars.com/d/ascii-table.html, ASCII Table),
* $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia),
* $(LINK2 http://www.unicode.org, The Unicode Consortium)
* Trademarks:
* Unicode(tm) is a trademark of Unicode, Inc.
*/
module std.uni;
/**
* Returns !=0 if c is a Unicode lower case character.
*/
int isUniLower(dchar c)
{
if (c <= 0x7F)
return (c >= 'a' && c <= 'z');
return isUniAlpha(c) && c == toUniLower(c);
}
/**
* Returns !=0 if c is a Unicode upper case character.
*/
int isUniUpper(dchar c)
{
if (c <= 0x7F)
return (c >= 'A' && c <= 'Z');
return isUniAlpha(c) && c == toUniUpper(c);
}
/**
* If c is a Unicode upper case character, return the lower case
* equivalent, otherwise return c.
*/
dchar toUniLower(dchar c)
{
if (c >= 'A' && c <= 'Z')
{
c += 32;
}
else if (c >= 0x00C0)
{
if ((c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE))
{
c += 32;
}
else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178))
{
if (c == 0x0130)
c = 0x0069;
else if ((c & 1) == 0)
c += 1;
}
else if (c == 0x0178)
{
c = 0x00FF;
}
else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F))
{
if (c & 1)
c += 1;
}
else if (c >= 0x0200 && c <= 0x0217)
{
if ((c & 1) == 0)
c += 1;
}
else if ((c >= 0x0401 && c <= 0x040C) || (c>= 0x040E && c <= 0x040F))
{
c += 80;
}
else if (c >= 0x0410 && c <= 0x042F)
{
c += 32;
}
else if (c >= 0x0460 && c <= 0x047F)
{
if ((c & 1) == 0)
c += 1;
}
else if (c >= 0x0531 && c <= 0x0556)
{
c += 48;
}
else if (c >= 0x10A0 && c <= 0x10C5)
{
c += 48;
}
else if (c >= 0xFF21 && c <= 0xFF3A)
{
c += 32;
}
}
return c;
}
/**
* If c is a Unicode lower case character, return the upper case
* equivalent, otherwise return c.
*/
dchar toUniUpper(dchar c)
{
if (c >= 'a' && c <= 'z')
{
c -= 32;
}
else if (c >= 0x00E0)
{
if ((c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE))
{
c -= 32;
}
else if (c == 0x00FF)
{
c = 0x0178;
}
else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178))
{
if (c == 0x0131)
c = 0x0049;
else if (c & 1)
c -= 1;
}
else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F))
{
if ((c & 1) == 0)
c = c-1;
}
else if (c == 0x017F)
{
c = 0x0053;
}
else if (c >= 0x0200 && c <= 0x0217)
{
if (c & 1)
c = c-1;
}
else if (c >= 0x0430 && c<= 0x044F)
{
c -= 32;
}
else if ((c >= 0x0451 && c <= 0x045C) || (c >=0x045E && c<= 0x045F))
{
c -= 80;
}
else if (c >= 0x0460 && c <= 0x047F)
{
if (c & 1)
c -= 1;
}
else if (c >= 0x0561 && c < 0x0587)
{
c -= 48;
}
else if (c >= 0xFF41 && c <= 0xFF5A)
{
c -= 32;
}
}
return c;
}
/*******************************
* Return !=0 if u is a Unicode alpha character.
* (general Unicode category: Lu, Ll, Lt, Lm and Lo)
*
* Standards: Unicode 5.0.0
*/
int isUniAlpha(dchar u)
{
static dchar table[][2] =
[
[ 'A', 'Z' ],
[ 'a', 'z' ],
[ 0x00AA, 0x00AA ],
[ 0x00B5, 0x00B5 ],
[ 0x00BA, 0x00BA ],
[ 0x00C0, 0x00D6 ],
[ 0x00D8, 0x00F6 ],
[ 0x00F8, 0x02C1 ],
[ 0x02C6, 0x02D1 ],
[ 0x02E0, 0x02E4 ],
[ 0x02EE, 0x02EE ],
[ 0x037A, 0x037D ],
[ 0x0386, 0x0386 ],
[ 0x0388, 0x038A ],
[ 0x038C, 0x038C ],
[ 0x038E, 0x03A1 ],
[ 0x03A3, 0x03CE ],
[ 0x03D0, 0x03F5 ],
[ 0x03F7, 0x0481 ],
[ 0x048A, 0x0513 ],
[ 0x0531, 0x0556 ],
[ 0x0559, 0x0559 ],
[ 0x0561, 0x0587 ],
[ 0x05D0, 0x05EA ],
[ 0x05F0, 0x05F2 ],
[ 0x0621, 0x063A ],
[ 0x0640, 0x064A ],
[ 0x066E, 0x066F ],
[ 0x0671, 0x06D3 ],
[ 0x06D5, 0x06D5 ],
[ 0x06E5, 0x06E6 ],
[ 0x06EE, 0x06EF ],
[ 0x06FA, 0x06FC ],
[ 0x06FF, 0x06FF ],
[ 0x0710, 0x0710 ],
[ 0x0712, 0x072F ],
[ 0x074D, 0x076D ],
[ 0x0780, 0x07A5 ],
[ 0x07B1, 0x07B1 ],
[ 0x07CA, 0x07EA ],
[ 0x07F4, 0x07F5 ],
[ 0x07FA, 0x07FA ],
[ 0x0904, 0x0939 ],
[ 0x093D, 0x093D ],
[ 0x0950, 0x0950 ],
[ 0x0958, 0x0961 ],
[ 0x097B, 0x097F ],
[ 0x0985, 0x098C ],
[ 0x098F, 0x0990 ],
[ 0x0993, 0x09A8 ],
[ 0x09AA, 0x09B0 ],
[ 0x09B2, 0x09B2 ],
[ 0x09B6, 0x09B9 ],
[ 0x09BD, 0x09BD ],
[ 0x09CE, 0x09CE ],
[ 0x09DC, 0x09DD ],
[ 0x09DF, 0x09E1 ],
[ 0x09F0, 0x09F1 ],
[ 0x0A05, 0x0A0A ],
[ 0x0A0F, 0x0A10 ],
[ 0x0A13, 0x0A28 ],
[ 0x0A2A, 0x0A30 ],
[ 0x0A32, 0x0A33 ],
[ 0x0A35, 0x0A36 ],
[ 0x0A38, 0x0A39 ],
[ 0x0A59, 0x0A5C ],
[ 0x0A5E, 0x0A5E ],
[ 0x0A72, 0x0A74 ],
[ 0x0A85, 0x0A8D ],
[ 0x0A8F, 0x0A91 ],
[ 0x0A93, 0x0AA8 ],
[ 0x0AAA, 0x0AB0 ],
[ 0x0AB2, 0x0AB3 ],
[ 0x0AB5, 0x0AB9 ],
[ 0x0ABD, 0x0ABD ],
[ 0x0AD0, 0x0AD0 ],
[ 0x0AE0, 0x0AE1 ],
[ 0x0B05, 0x0B0C ],
[ 0x0B0F, 0x0B10 ],
[ 0x0B13, 0x0B28 ],
[ 0x0B2A, 0x0B30 ],
[ 0x0B32, 0x0B33 ],
[ 0x0B35, 0x0B39 ],
[ 0x0B3D, 0x0B3D ],
[ 0x0B5C, 0x0B5D ],
[ 0x0B5F, 0x0B61 ],
[ 0x0B71, 0x0B71 ],
[ 0x0B83, 0x0B83 ],
[ 0x0B85, 0x0B8A ],
[ 0x0B8E, 0x0B90 ],
[ 0x0B92, 0x0B95 ],
[ 0x0B99, 0x0B9A ],
[ 0x0B9C, 0x0B9C ],
[ 0x0B9E, 0x0B9F ],
[ 0x0BA3, 0x0BA4 ],
[ 0x0BA8, 0x0BAA ],
[ 0x0BAE, 0x0BB9 ],
[ 0x0C05, 0x0C0C ],
[ 0x0C0E, 0x0C10 ],
[ 0x0C12, 0x0C28 ],
[ 0x0C2A, 0x0C33 ],
[ 0x0C35, 0x0C39 ],
[ 0x0C60, 0x0C61 ],
[ 0x0C85, 0x0C8C ],
[ 0x0C8E, 0x0C90 ],
[ 0x0C92, 0x0CA8 ],
[ 0x0CAA, 0x0CB3 ],
[ 0x0CB5, 0x0CB9 ],
[ 0x0CBD, 0x0CBD ],
[ 0x0CDE, 0x0CDE ],
[ 0x0CE0, 0x0CE1 ],
[ 0x0D05, 0x0D0C ],
[ 0x0D0E, 0x0D10 ],
[ 0x0D12, 0x0D28 ],
[ 0x0D2A, 0x0D39 ],
[ 0x0D60, 0x0D61 ],
[ 0x0D85, 0x0D96 ],
[ 0x0D9A, 0x0DB1 ],
[ 0x0DB3, 0x0DBB ],
[ 0x0DBD, 0x0DBD ],
[ 0x0DC0, 0x0DC6 ],
[ 0x0E01, 0x0E30 ],
[ 0x0E32, 0x0E33 ],
[ 0x0E40, 0x0E46 ],
[ 0x0E81, 0x0E82 ],
[ 0x0E84, 0x0E84 ],
[ 0x0E87, 0x0E88 ],
[ 0x0E8A, 0x0E8A ],
[ 0x0E8D, 0x0E8D ],
[ 0x0E94, 0x0E97 ],
[ 0x0E99, 0x0E9F ],
[ 0x0EA1, 0x0EA3 ],
[ 0x0EA5, 0x0EA5 ],
[ 0x0EA7, 0x0EA7 ],
[ 0x0EAA, 0x0EAB ],
[ 0x0EAD, 0x0EB0 ],
[ 0x0EB2, 0x0EB3 ],
[ 0x0EBD, 0x0EBD ],
[ 0x0EC0, 0x0EC4 ],
[ 0x0EC6, 0x0EC6 ],
[ 0x0EDC, 0x0EDD ],
[ 0x0F00, 0x0F00 ],
[ 0x0F40, 0x0F47 ],
[ 0x0F49, 0x0F6A ],
[ 0x0F88, 0x0F8B ],
[ 0x1000, 0x1021 ],
[ 0x1023, 0x1027 ],
[ 0x1029, 0x102A ],
[ 0x1050, 0x1055 ],
[ 0x10A0, 0x10C5 ],
[ 0x10D0, 0x10FA ],
[ 0x10FC, 0x10FC ],
[ 0x1100, 0x1159 ],
[ 0x115F, 0x11A2 ],
[ 0x11A8, 0x11F9 ],
[ 0x1200, 0x1248 ],
[ 0x124A, 0x124D ],
[ 0x1250, 0x1256 ],
[ 0x1258, 0x1258 ],
[ 0x125A, 0x125D ],
[ 0x1260, 0x1288 ],
[ 0x128A, 0x128D ],
[ 0x1290, 0x12B0 ],
[ 0x12B2, 0x12B5 ],
[ 0x12B8, 0x12BE ],
[ 0x12C0, 0x12C0 ],
[ 0x12C2, 0x12C5 ],
[ 0x12C8, 0x12D6 ],
[ 0x12D8, 0x1310 ],
[ 0x1312, 0x1315 ],
[ 0x1318, 0x135A ],
[ 0x1380, 0x138F ],
[ 0x13A0, 0x13F4 ],
[ 0x1401, 0x166C ],
[ 0x166F, 0x1676 ],
[ 0x1681, 0x169A ],
[ 0x16A0, 0x16EA ],
[ 0x1700, 0x170C ],
[ 0x170E, 0x1711 ],
[ 0x1720, 0x1731 ],
[ 0x1740, 0x1751 ],
[ 0x1760, 0x176C ],
[ 0x176E, 0x1770 ],
[ 0x1780, 0x17B3 ],
[ 0x17D7, 0x17D7 ],
[ 0x17DC, 0x17DC ],
[ 0x1820, 0x1877 ],
[ 0x1880, 0x18A8 ],
[ 0x1900, 0x191C ],
[ 0x1950, 0x196D ],
[ 0x1970, 0x1974 ],
[ 0x1980, 0x19A9 ],
[ 0x19C1, 0x19C7 ],
[ 0x1A00, 0x1A16 ],
[ 0x1B05, 0x1B33 ],
[ 0x1B45, 0x1B4B ],
[ 0x1D00, 0x1DBF ],
[ 0x1E00, 0x1E9B ],
[ 0x1EA0, 0x1EF9 ],
[ 0x1F00, 0x1F15 ],
[ 0x1F18, 0x1F1D ],
[ 0x1F20, 0x1F45 ],
[ 0x1F48, 0x1F4D ],
[ 0x1F50, 0x1F57 ],
[ 0x1F59, 0x1F59 ],
[ 0x1F5B, 0x1F5B ],
[ 0x1F5D, 0x1F5D ],
[ 0x1F5F, 0x1F7D ],
[ 0x1F80, 0x1FB4 ],
[ 0x1FB6, 0x1FBC ],
[ 0x1FBE, 0x1FBE ],
[ 0x1FC2, 0x1FC4 ],
[ 0x1FC6, 0x1FCC ],
[ 0x1FD0, 0x1FD3 ],
[ 0x1FD6, 0x1FDB ],
[ 0x1FE0, 0x1FEC ],
[ 0x1FF2, 0x1FF4 ],
[ 0x1FF6, 0x1FFC ],
[ 0x2071, 0x2071 ],
[ 0x207F, 0x207F ],
[ 0x2090, 0x2094 ],
[ 0x2102, 0x2102 ],
[ 0x2107, 0x2107 ],
[ 0x210A, 0x2113 ],
[ 0x2115, 0x2115 ],
[ 0x2119, 0x211D ],
[ 0x2124, 0x2124 ],
[ 0x2126, 0x2126 ],
[ 0x2128, 0x2128 ],
[ 0x212A, 0x212D ],
[ 0x212F, 0x2139 ],
[ 0x213C, 0x213F ],
[ 0x2145, 0x2149 ],
[ 0x214E, 0x214E ],
[ 0x2183, 0x2184 ],
[ 0x2C00, 0x2C2E ],
[ 0x2C30, 0x2C5E ],
[ 0x2C60, 0x2C6C ],
[ 0x2C74, 0x2C77 ],
[ 0x2C80, 0x2CE4 ],
[ 0x2D00, 0x2D25 ],
[ 0x2D30, 0x2D65 ],
[ 0x2D6F, 0x2D6F ],
[ 0x2D80, 0x2D96 ],
[ 0x2DA0, 0x2DA6 ],
[ 0x2DA8, 0x2DAE ],
[ 0x2DB0, 0x2DB6 ],
[ 0x2DB8, 0x2DBE ],
[ 0x2DC0, 0x2DC6 ],
[ 0x2DC8, 0x2DCE ],
[ 0x2DD0, 0x2DD6 ],
[ 0x2DD8, 0x2DDE ],
[ 0x3005, 0x3006 ],
[ 0x3031, 0x3035 ],
[ 0x303B, 0x303C ],
[ 0x3041, 0x3096 ],
[ 0x309D, 0x309F ],
[ 0x30A1, 0x30FA ],
[ 0x30FC, 0x30FF ],
[ 0x3105, 0x312C ],
[ 0x3131, 0x318E ],
[ 0x31A0, 0x31B7 ],
[ 0x31F0, 0x31FF ],
[ 0x3400, 0x4DB5 ],
[ 0x4E00, 0x9FBB ],
[ 0xA000, 0xA48C ],
[ 0xA717, 0xA71A ],
[ 0xA800, 0xA801 ],
[ 0xA803, 0xA805 ],
[ 0xA807, 0xA80A ],
[ 0xA80C, 0xA822 ],
[ 0xA840, 0xA873 ],
[ 0xAC00, 0xD7A3 ],
[ 0xF900, 0xFA2D ],
[ 0xFA30, 0xFA6A ],
[ 0xFA70, 0xFAD9 ],
[ 0xFB00, 0xFB06 ],
[ 0xFB13, 0xFB17 ],
[ 0xFB1D, 0xFB1D ],
[ 0xFB1F, 0xFB28 ],
[ 0xFB2A, 0xFB36 ],
[ 0xFB38, 0xFB3C ],
[ 0xFB3E, 0xFB3E ],
[ 0xFB40, 0xFB41 ],
[ 0xFB43, 0xFB44 ],
[ 0xFB46, 0xFBB1 ],
[ 0xFBD3, 0xFD3D ],
[ 0xFD50, 0xFD8F ],
[ 0xFD92, 0xFDC7 ],
[ 0xFDF0, 0xFDFB ],
[ 0xFE70, 0xFE74 ],
[ 0xFE76, 0xFEFC ],
[ 0xFF21, 0xFF3A ],
[ 0xFF41, 0xFF5A ],
[ 0xFF66, 0xFFBE ],
[ 0xFFC2, 0xFFC7 ],
[ 0xFFCA, 0xFFCF ],
[ 0xFFD2, 0xFFD7 ],
[ 0xFFDA, 0xFFDC ],
[ 0x10000, 0x1000B ],
[ 0x1000D, 0x10026 ],
[ 0x10028, 0x1003A ],
[ 0x1003C, 0x1003D ],
[ 0x1003F, 0x1004D ],
[ 0x10050, 0x1005D ],
[ 0x10080, 0x100FA ],
[ 0x10300, 0x1031E ],
[ 0x10330, 0x10340 ],
[ 0x10342, 0x10349 ],
[ 0x10380, 0x1039D ],
[ 0x103A0, 0x103C3 ],
[ 0x103C8, 0x103CF ],
[ 0x10400, 0x1049D ],
[ 0x10800, 0x10805 ],
[ 0x10808, 0x10808 ],
[ 0x1080A, 0x10835 ],
[ 0x10837, 0x10838 ],
[ 0x1083C, 0x1083C ],
[ 0x1083F, 0x1083F ],
[ 0x10900, 0x10915 ],
[ 0x10A00, 0x10A00 ],
[ 0x10A10, 0x10A13 ],
[ 0x10A15, 0x10A17 ],
[ 0x10A19, 0x10A33 ],
[ 0x12000, 0x1236E ],
[ 0x1D400, 0x1D454 ],
[ 0x1D456, 0x1D49C ],
[ 0x1D49E, 0x1D49F ],
[ 0x1D4A2, 0x1D4A2 ],
[ 0x1D4A5, 0x1D4A6 ],
[ 0x1D4A9, 0x1D4AC ],
[ 0x1D4AE, 0x1D4B9 ],
[ 0x1D4BB, 0x1D4BB ],
[ 0x1D4BD, 0x1D4C3 ],
[ 0x1D4C5, 0x1D505 ],
[ 0x1D507, 0x1D50A ],
[ 0x1D50D, 0x1D514 ],
[ 0x1D516, 0x1D51C ],
[ 0x1D51E, 0x1D539 ],
[ 0x1D53B, 0x1D53E ],
[ 0x1D540, 0x1D544 ],
[ 0x1D546, 0x1D546 ],
[ 0x1D54A, 0x1D550 ],
[ 0x1D552, 0x1D6A5 ],
[ 0x1D6A8, 0x1D6C0 ],
[ 0x1D6C2, 0x1D6DA ],
[ 0x1D6DC, 0x1D6FA ],
[ 0x1D6FC, 0x1D714 ],
[ 0x1D716, 0x1D734 ],
[ 0x1D736, 0x1D74E ],
[ 0x1D750, 0x1D76E ],
[ 0x1D770, 0x1D788 ],
[ 0x1D78A, 0x1D7A8 ],
[ 0x1D7AA, 0x1D7C2 ],
[ 0x1D7C4, 0x1D7CB ],
[ 0x20000, 0x2A6D6 ],
[ 0x2F800, 0x2FA1D ],
];
debug
{
for (int i = 0; i < table.length; i++)
{
assert(table[i][0] <= table[i][1]);
if (i < table.length - 1)
{
if (table[i][1] >= table[i + 1][0])
printf("table[%d][1] = x%x, table[%d][0] = x%x\n", i, table[i][1], i + 1, table[i + 1][0]);
assert(table[i][1] < table[i + 1][0]);
}
}
}
if (u < 0xAA)
{
if (u < 'A')
goto Lisnot;
if (u <= 'Z')
goto Lis;
if (u < 'a')
goto Lisnot;
if (u <= 'z')
goto Lis;
goto Lisnot;
}
// Binary search
uint mid;
uint low;
uint high;
low = 0;
high = table.length - 1;
while (cast(int)low <= cast(int)high)
{
mid = (low + high) >> 1;
if (u < table[mid][0])
high = mid - 1;
else if (u > table[mid][1])
low = mid + 1;
else
goto Lis;
}
Lisnot:
debug
{
for (int i = 0; i < table.length; i++)
{
assert(u < table[i][0] || u > table[i][1]);
}
}
return 0;
Lis:
debug
{
for (int i = 0; i < table.length; i++)
{
if (u >= table[i][0] && u <= table[i][1])
return 1;
}
assert(0); // should have been in table
}
return 1;
}
unittest
{
for (uint i = 0; i < 0x80; i++)
{
if (i >= 'A' && i <= 'Z')
assert(isUniAlpha(i));
else if (i >= 'a' && i <= 'z')
assert(isUniAlpha(i));
else
assert(!isUniAlpha(i));
}
}

View File

@@ -1,969 +0,0 @@
// utf.d
/*
* Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com
* Written by Walter Bright
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* o The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* o Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
* o This notice may not be removed or altered from any source
* distribution.
*/
/********************************************
* Encode and decode UTF-8, UTF-16 and UTF-32 strings.
*
* For Win32 systems, the C wchar_t type is UTF-16 and corresponds to the D
* wchar type.
* For linux systems, the C wchar_t type is UTF-32 and corresponds to
* the D utf.dchar type.
*
* UTF character support is restricted to (\u0000 &lt;= character &lt;= \U0010FFFF).
*
* See_Also:
* $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>
* $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>
* $(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)
* Macros:
* WIKI = Phobos/StdUtf
*/
module std.utf;
private import std.stdio;
//debug=utf; // uncomment to turn on debugging printf's
deprecated class UtfError : Error
{
size_t idx; // index in string of where error occurred
this(char[] s, size_t i)
{
idx = i;
super(s);
}
}
/**********************************
* Exception class that is thrown upon any errors.
*/
class UtfException : Exception
{
size_t idx; /// index in string of where error occurred
this(char[] s, size_t i)
{
idx = i;
super(s);
}
}
/*******************************
* Test if c is a valid UTF-32 character.
*
* \uFFFE and \uFFFF are considered valid by this function,
* as they are permitted for internal use by an application,
* but they are not allowed for interchange by the Unicode standard.
*
* Returns: true if it is, false if not.
*/
bool isValidDchar(dchar c)
{
/* Note: FFFE and FFFF are specifically permitted by the
* Unicode standard for application internal use, but are not
* allowed for interchange.
* (thanks to Arcane Jill)
*/
return c < 0xD800 ||
(c > 0xDFFF && c <= 0x10FFFF /*&& c != 0xFFFE && c != 0xFFFF*/);
}
unittest
{
debug(utf) printf("utf.isValidDchar.unittest\n");
assert(isValidDchar(cast(dchar)'a') == true);
assert(isValidDchar(cast(dchar)0x1FFFFF) == false);
}
ubyte[256] UTF8stride =
[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF,
];
/**
* stride() returns the length of a UTF-8 sequence starting at index i
* in string s.
* Returns:
* The number of bytes in the UTF-8 sequence or
* 0xFF meaning s[i] is not the start of of UTF-8 sequence.
*/
uint stride(char[] s, size_t i)
{
return UTF8stride[s[i]];
}
/**
* stride() returns the length of a UTF-16 sequence starting at index i
* in string s.
*/
uint stride(wchar[] s, size_t i)
{ uint u = s[i];
return 1 + (u >= 0xD800 && u <= 0xDBFF);
}
/**
* stride() returns the length of a UTF-32 sequence starting at index i
* in string s.
* Returns: The return value will always be 1.
*/
uint stride(dchar[] s, size_t i)
{
return 1;
}
/*******************************************
* Given an index i into an array of characters s[],
* and assuming that index i is at the start of a UTF character,
* determine the number of UCS characters up to that index i.
*/
size_t toUCSindex(char[] s, size_t i)
{
size_t n;
size_t j;
size_t stride;
for (j = 0; j < i; j += stride)
{
stride = UTF8stride[s[j]];
if (stride == 0xFF)
goto Lerr;
n++;
}
if (j > i)
{
Lerr:
throw new UtfException("1invalid UTF-8 sequence", j);
}
return n;
}
/** ditto */
size_t toUCSindex(wchar[] s, size_t i)
{
size_t n;
size_t j;
for (j = 0; j < i; )
{ uint u = s[j];
j += 1 + (u >= 0xD800 && u <= 0xDBFF);
n++;
}
if (j > i)
{
Lerr:
throw new UtfException("2invalid UTF-16 sequence", j);
}
return n;
}
/** ditto */
size_t toUCSindex(dchar[] s, size_t i)
{
return i;
}
/******************************************
* Given a UCS index n into an array of characters s[], return the UTF index.
*/
size_t toUTFindex(char[] s, size_t n)
{
size_t i;
while (n--)
{
uint j = UTF8stride[s[i]];
if (j == 0xFF)
throw new UtfException("3invalid UTF-8 sequence", i);
i += j;
}
return i;
}
/** ditto */
size_t toUTFindex(wchar[] s, size_t n)
{
size_t i;
while (n--)
{ wchar u = s[i];
i += 1 + (u >= 0xD800 && u <= 0xDBFF);
}
return i;
}
/** ditto */
size_t toUTFindex(dchar[] s, size_t n)
{
return n;
}
/* =================== Decode ======================= */
/***************
* Decodes and returns character starting at s[idx]. idx is advanced past the
* decoded character. If the character is not well formed, a UtfException is
* thrown and idx remains unchanged.
*/
dchar decode(char[] s, inout size_t idx)
in
{
assert(idx >= 0 && idx < s.length);
}
out (result)
{
assert(isValidDchar(result));
}
body
{
size_t len = s.length;
dchar V;
size_t i = idx;
char u = s[i];
if (u & 0x80)
{ uint n;
char u2;
/* The following encodings are valid, except for the 5 and 6 byte
* combinations:
* 0xxxxxxx
* 110xxxxx 10xxxxxx
* 1110xxxx 10xxxxxx 10xxxxxx
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
for (n = 1; ; n++)
{
if (n > 4)
goto Lerr; // only do the first 4 of 6 encodings
if (((u << n) & 0x80) == 0)
{
if (n == 1)
goto Lerr;
break;
}
}
// Pick off (7 - n) significant bits of B from first byte of octet
V = cast(dchar)(u & ((1 << (7 - n)) - 1));
if (i + (n - 1) >= len)
goto Lerr; // off end of string
/* The following combinations are overlong, and illegal:
* 1100000x (10xxxxxx)
* 11100000 100xxxxx (10xxxxxx)
* 11110000 1000xxxx (10xxxxxx 10xxxxxx)
* 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
* 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
*/
u2 = s[i + 1];
if ((u & 0xFE) == 0xC0 ||
(u == 0xE0 && (u2 & 0xE0) == 0x80) ||
(u == 0xF0 && (u2 & 0xF0) == 0x80) ||
(u == 0xF8 && (u2 & 0xF8) == 0x80) ||
(u == 0xFC && (u2 & 0xFC) == 0x80))
goto Lerr; // overlong combination
for (uint j = 1; j != n; j++)
{
u = s[i + j];
if ((u & 0xC0) != 0x80)
goto Lerr; // trailing bytes are 10xxxxxx
V = (V << 6) | (u & 0x3F);
}
if (!isValidDchar(V))
goto Lerr;
i += n;
}
else
{
V = cast(dchar) u;
i++;
}
idx = i;
return V;
Lerr:
//printf("\ndecode: idx = %d, i = %d, length = %d s = \n'%.*s'\n%x\n'%.*s'\n", idx, i, s.length, s, s[i], s[i .. length]);
throw new UtfException("4invalid UTF-8 sequence", i);
}
unittest
{ size_t i;
dchar c;
debug(utf) printf("utf.decode.unittest\n");
static char[] s1 = "abcd";
i = 0;
c = decode(s1, i);
assert(c == cast(dchar)'a');
assert(i == 1);
c = decode(s1, i);
assert(c == cast(dchar)'b');
assert(i == 2);
static char[] s2 = "\xC2\xA9";
i = 0;
c = decode(s2, i);
assert(c == cast(dchar)'\u00A9');
assert(i == 2);
static char[] s3 = "\xE2\x89\xA0";
i = 0;
c = decode(s3, i);
assert(c == cast(dchar)'\u2260');
assert(i == 3);
static char[][] s4 =
[ "\xE2\x89", // too short
"\xC0\x8A",
"\xE0\x80\x8A",
"\xF0\x80\x80\x8A",
"\xF8\x80\x80\x80\x8A",
"\xFC\x80\x80\x80\x80\x8A",
];
for (int j = 0; j < s4.length; j++)
{
try
{
i = 0;
c = decode(s4[j], i);
assert(0);
}
catch (UtfException u)
{
i = 23;
delete u;
}
assert(i == 23);
}
}
/** ditto */
dchar decode(wchar[] s, inout size_t idx)
in
{
assert(idx >= 0 && idx < s.length);
}
out (result)
{
assert(isValidDchar(result));
}
body
{
char[] msg;
dchar V;
size_t i = idx;
uint u = s[i];
if (u & ~0x7F)
{ if (u >= 0xD800 && u <= 0xDBFF)
{ uint u2;
if (i + 1 == s.length)
{ msg = "surrogate UTF-16 high value past end of string";
goto Lerr;
}
u2 = s[i + 1];
if (u2 < 0xDC00 || u2 > 0xDFFF)
{ msg = "surrogate UTF-16 low value out of range";
goto Lerr;
}
u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);
i += 2;
}
else if (u >= 0xDC00 && u <= 0xDFFF)
{ msg = "unpaired surrogate UTF-16 value";
goto Lerr;
}
else if (u == 0xFFFE || u == 0xFFFF)
{ msg = "illegal UTF-16 value";
goto Lerr;
}
else
i++;
}
else
{
i++;
}
idx = i;
return cast(dchar)u;
Lerr:
throw new UtfException(msg, i);
}
/** ditto */
dchar decode(dchar[] s, inout size_t idx)
in
{
assert(idx >= 0 && idx < s.length);
}
body
{
size_t i = idx;
dchar c = s[i];
if (!isValidDchar(c))
goto Lerr;
idx = i + 1;
return c;
Lerr:
throw new UtfException("5invalid UTF-32 value", i);
}
/* =================== Encode ======================= */
/*******************************
* Encodes character c and appends it to array s[].
*/
void encode(inout char[] s, dchar c)
in
{
assert(isValidDchar(c));
}
body
{
char[] r = s;
if (c <= 0x7F)
{
r ~= cast(char) c;
}
else
{
char[4] buf;
uint L;
if (c <= 0x7FF)
{
buf[0] = cast(char)(0xC0 | (c >> 6));
buf[1] = cast(char)(0x80 | (c & 0x3F));
L = 2;
}
else if (c <= 0xFFFF)
{
buf[0] = cast(char)(0xE0 | (c >> 12));
buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
buf[2] = cast(char)(0x80 | (c & 0x3F));
L = 3;
}
else if (c <= 0x10FFFF)
{
buf[0] = cast(char)(0xF0 | (c >> 18));
buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
buf[3] = cast(char)(0x80 | (c & 0x3F));
L = 4;
}
else
{
assert(0);
}
r ~= buf[0 .. L];
}
s = r;
}
unittest
{
debug(utf) printf("utf.encode.unittest\n");
char[] s = "abcd";
encode(s, cast(dchar)'a');
assert(s.length == 5);
assert(s == "abcda");
encode(s, cast(dchar)'\u00A9');
assert(s.length == 7);
assert(s == "abcda\xC2\xA9");
//assert(s == "abcda\u00A9"); // BUG: fix compiler
encode(s, cast(dchar)'\u2260');
assert(s.length == 10);
assert(s == "abcda\xC2\xA9\xE2\x89\xA0");
}
/** ditto */
void encode(inout wchar[] s, dchar c)
in
{
assert(isValidDchar(c));
}
body
{
wchar[] r = s;
if (c <= 0xFFFF)
{
r ~= cast(wchar) c;
}
else
{
wchar[2] buf;
buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
r ~= buf;
}
s = r;
}
/** ditto */
void encode(inout dchar[] s, dchar c)
in
{
assert(isValidDchar(c));
}
body
{
s ~= c;
}
/* =================== Validation ======================= */
/***********************************
* Checks to see if string is well formed or not. Throws a UtfException if it is
* not. Use to check all untrusted input for correctness.
*/
void validate(char[] s)
{
size_t len = s.length;
size_t i;
for (i = 0; i < len; )
{
decode(s, i);
}
}
/** ditto */
void validate(wchar[] s)
{
size_t len = s.length;
size_t i;
for (i = 0; i < len; )
{
decode(s, i);
}
}
/** ditto */
void validate(dchar[] s)
{
size_t len = s.length;
size_t i;
for (i = 0; i < len; )
{
decode(s, i);
}
}
/* =================== Conversion to UTF8 ======================= */
char[] toUTF8(char[4] buf, dchar c)
in
{
assert(isValidDchar(c));
}
body
{
if (c <= 0x7F)
{
buf[0] = cast(char) c;
return buf[0 .. 1];
}
else if (c <= 0x7FF)
{
buf[0] = cast(char)(0xC0 | (c >> 6));
buf[1] = cast(char)(0x80 | (c & 0x3F));
return buf[0 .. 2];
}
else if (c <= 0xFFFF)
{
buf[0] = cast(char)(0xE0 | (c >> 12));
buf[1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
buf[2] = cast(char)(0x80 | (c & 0x3F));
return buf[0 .. 3];
}
else if (c <= 0x10FFFF)
{
buf[0] = cast(char)(0xF0 | (c >> 18));
buf[1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
buf[2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
buf[3] = cast(char)(0x80 | (c & 0x3F));
return buf[0 .. 4];
}
assert(0);
}
/*******************
* Encodes string s into UTF-8 and returns the encoded string.
*/
char[] toUTF8(char[] s)
in
{
validate(s);
}
body
{
return s;
}
/** ditto */
char[] toUTF8(wchar[] s)
{
char[] r;
size_t i;
size_t slen = s.length;
r.length = slen;
for (i = 0; i < slen; i++)
{ wchar c = s[i];
if (c <= 0x7F)
r[i] = cast(char)c; // fast path for ascii
else
{
r.length = i;
foreach (dchar c; s[i .. slen])
{
encode(r, c);
}
break;
}
}
return r;
}
/** ditto */
char[] toUTF8(dchar[] s)
{
char[] r;
size_t i;
size_t slen = s.length;
r.length = slen;
for (i = 0; i < slen; i++)
{ dchar c = s[i];
if (c <= 0x7F)
r[i] = cast(char)c; // fast path for ascii
else
{
r.length = i;
foreach (dchar d; s[i .. slen])
{
encode(r, d);
}
break;
}
}
return r;
}
/* =================== Conversion to UTF16 ======================= */
wchar[] toUTF16(wchar[2] buf, dchar c)
in
{
assert(isValidDchar(c));
}
body
{
if (c <= 0xFFFF)
{
buf[0] = cast(wchar) c;
return buf[0 .. 1];
}
else
{
buf[0] = cast(wchar) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
buf[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00);
return buf[0 .. 2];
}
}
/****************
* Encodes string s into UTF-16 and returns the encoded string.
* toUTF16z() is suitable for calling the 'W' functions in the Win32 API that take
* an LPWSTR or LPCWSTR argument.
*/
wchar[] toUTF16(char[] s)
{
wchar[] r;
size_t slen = s.length;
r.length = slen;
r.length = 0;
for (size_t i = 0; i < slen; )
{
dchar c = s[i];
if (c <= 0x7F)
{
i++;
r ~= cast(wchar)c;
}
else
{
c = decode(s, i);
encode(r, c);
}
}
return r;
}
/** ditto */
wchar* toUTF16z(char[] s)
{
wchar[] r;
size_t slen = s.length;
r.length = slen + 1;
r.length = 0;
for (size_t i = 0; i < slen; )
{
dchar c = s[i];
if (c <= 0x7F)
{
i++;
r ~= cast(wchar)c;
}
else
{
c = decode(s, i);
encode(r, c);
}
}
r ~= "\000";
return r.ptr;
}
/** ditto */
wchar[] toUTF16(wchar[] s)
in
{
validate(s);
}
body
{
return s;
}
/** ditto */
wchar[] toUTF16(dchar[] s)
{
wchar[] r;
size_t slen = s.length;
r.length = slen;
r.length = 0;
for (size_t i = 0; i < slen; i++)
{
encode(r, s[i]);
}
return r;
}
/* =================== Conversion to UTF32 ======================= */
/*****
* Encodes string s into UTF-32 and returns the encoded string.
*/
dchar[] toUTF32(char[] s)
{
dchar[] r;
size_t slen = s.length;
size_t j = 0;
r.length = slen; // r[] will never be longer than s[]
for (size_t i = 0; i < slen; )
{
dchar c = s[i];
if (c >= 0x80)
c = decode(s, i);
else
i++; // c is ascii, no need for decode
r[j++] = c;
}
return r[0 .. j];
}
/** ditto */
dchar[] toUTF32(wchar[] s)
{
dchar[] r;
size_t slen = s.length;
size_t j = 0;
r.length = slen; // r[] will never be longer than s[]
for (size_t i = 0; i < slen; )
{
dchar c = s[i];
if (c >= 0x80)
c = decode(s, i);
else
i++; // c is ascii, no need for decode
r[j++] = c;
}
return r[0 .. j];
}
/** ditto */
dchar[] toUTF32(dchar[] s)
in
{
validate(s);
}
body
{
return s;
}
/* ================================ tests ================================== */
unittest
{
debug(utf) printf("utf.toUTF.unittest\n");
char[] c;
wchar[] w;
dchar[] d;
c = "hello";
w = toUTF16(c);
assert(w == "hello");
d = toUTF32(c);
assert(d == "hello");
c = toUTF8(w);
assert(c == "hello");
d = toUTF32(w);
assert(d == "hello");
c = toUTF8(d);
assert(c == "hello");
w = toUTF16(d);
assert(w == "hello");
c = "hel\u1234o";
w = toUTF16(c);
assert(w == "hel\u1234o");
d = toUTF32(c);
assert(d == "hel\u1234o");
c = toUTF8(w);
assert(c == "hel\u1234o");
d = toUTF32(w);
assert(d == "hel\u1234o");
c = toUTF8(d);
assert(c == "hel\u1234o");
w = toUTF16(d);
assert(w == "hel\u1234o");
c = "he\U0010AAAAllo";
w = toUTF16(c);
//foreach (wchar c; w) printf("c = x%x\n", c);
//foreach (wchar c; cast(wchar[])"he\U0010AAAAllo") printf("c = x%x\n", c);
assert(w == "he\U0010AAAAllo");
d = toUTF32(c);
assert(d == "he\U0010AAAAllo");
c = toUTF8(w);
assert(c == "he\U0010AAAAllo");
d = toUTF32(w);
assert(d == "he\U0010AAAAllo");
c = toUTF8(d);
assert(c == "he\U0010AAAAllo");
w = toUTF16(d);
assert(w == "he\U0010AAAAllo");
}

View File

@@ -1,520 +0,0 @@
/**
* Read/write data in the $(LINK2 http://www.info-_zip.org, zip archive) format.
* Makes use of the etc.c.zlib compression library.
*
* Bugs:
* $(UL
* $(LI Multi-disk zips not supported.)
* $(LI Only Zip version 20 formats are supported.)
* $(LI Only supports compression modes 0 (no compression) and 8 (deflate).)
* $(LI Does not support encryption.)
* )
*
* Macros:
* WIKI = Phobos/StdZip
*/
module std.zip;
private import std.zlib;
private import std.date;
private import std.intrinsic;
//debug=print;
/** Thrown on error.
*/
class ZipException : Exception
{
this(char[] msg)
{
super("ZipException: " ~ msg);
}
}
/**
* A member of the ZipArchive.
*/
class ArchiveMember
{
ushort madeVersion = 20; /// Read Only
ushort extractVersion = 20; /// Read Only
ushort flags; /// Read/Write: normally set to 0
ushort compressionMethod; /// Read/Write: 0 for compression, 8 for deflate
std.date.DosFileTime time; /// Read/Write: Last modified time of the member. It's in the DOS date/time format.
uint crc32; /// Read Only: cyclic redundancy check (CRC) value
uint compressedSize; /// Read Only: size of data of member in compressed form.
uint expandedSize; /// Read Only: size of data of member in expanded form.
ushort diskNumber; /// Read Only: should be 0.
ushort internalAttributes; /// Read/Write
uint externalAttributes; /// Read/Write
private uint offset;
/**
* Read/Write: Usually the file name of the archive member; it is used to
* index the archive directory for the member. Each member must have a unique
* name[]. Do not change without removing member from the directory first.
*/
char[] name;
ubyte[] extra; /// Read/Write: extra data for this member.
char[] comment; /// Read/Write: comment associated with this member.
ubyte[] compressedData; /// Read Only: data of member in compressed form.
ubyte[] expandedData; /// Read/Write: data of member in uncompressed form.
debug(print)
{
void print()
{
printf("name = '%.*s'\n", cast(int) name.length, name.ptr);
printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr);
printf("\tmadeVersion = x%04x\n", madeVersion);
printf("\textractVersion = x%04x\n", extractVersion);
printf("\tflags = x%04x\n", flags);
printf("\tcompressionMethod = %d\n", compressionMethod);
printf("\ttime = %d\n", time);
printf("\tcrc32 = x%08x\n", crc32);
printf("\texpandedSize = %d\n", expandedSize);
printf("\tcompressedSize = %d\n", compressedSize);
printf("\tinternalAttributes = x%04x\n", internalAttributes);
printf("\texternalAttributes = x%08x\n", externalAttributes);
}
}
}
/**
* Object representing the entire archive.
* ZipArchives are collections of ArchiveMembers.
*/
class ZipArchive
{
ubyte[] data; /// Read Only: array representing the entire contents of the archive.
uint endrecOffset;
uint diskNumber; /// Read Only: 0 since multi-disk zip archives are not supported.
uint diskStartDir; /// Read Only: 0 since multi-disk zip archives are not supported.
uint numEntries; /// Read Only: number of ArchiveMembers in the directory.
uint totalEntries; /// Read Only: same as totalEntries.
char[] comment; /// Read/Write: the archive comment. Must be less than 65536 bytes in length.
/**
* Read Only: array indexed by the name of each member of the archive.
* Example:
* All the members of the archive can be accessed with a foreach loop:
* --------------------
* ZipArchive archive = new ZipArchive(data);
* foreach (ArchiveMember am; archive.directory)
* {
* writefln("member name is '%s'", am.name);
* }
* --------------------
*/
ArchiveMember[char[]] directory;
debug (print)
{
void print()
{
printf("\tdiskNumber = %u\n", diskNumber);
printf("\tdiskStartDir = %u\n", diskStartDir);
printf("\tnumEntries = %u\n", numEntries);
printf("\ttotalEntries = %u\n", totalEntries);
printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr);
}
}
/* ============ Creating a new archive =================== */
/** Constructor to use when creating a new archive.
*/
this()
{
}
/** Add de to the archive.
*/
void addMember(ArchiveMember de)
{
directory[de.name] = de;
}
/** Delete de from the archive.
*/
void deleteMember(ArchiveMember de)
{
directory.remove(de.name);
}
/**
* Construct an archive out of the current members of the archive.
*
* Fills in the properties data[], diskNumber, diskStartDir, numEntries,
* totalEntries, and directory[].
* For each ArchiveMember, fills in properties crc32, compressedSize,
* compressedData[].
*
* Returns: array representing the entire archive.
*/
void[] build()
{ uint i;
uint directoryOffset;
if (comment.length > 0xFFFF)
throw new ZipException("archive comment longer than 65535");
// Compress each member; compute size
uint archiveSize = 0;
uint directorySize = 0;
foreach (ArchiveMember de; directory)
{
de.expandedSize = de.expandedData.length;
switch (de.compressionMethod)
{
case 0:
de.compressedData = de.expandedData;
break;
case 8:
de.compressedData = cast(ubyte[])std.zlib.compress(cast(void[])de.expandedData);
de.compressedData = de.compressedData[2 .. de.compressedData.length - 4];
break;
default:
throw new ZipException("unsupported compression method");
}
de.compressedSize = de.compressedData.length;
de.crc32 = std.zlib.crc32(0, cast(void[])de.expandedData);
archiveSize += 30 + de.name.length +
de.extra.length +
de.compressedSize;
directorySize += 46 + de.name.length +
de.extra.length +
de.comment.length;
}
data = new ubyte[archiveSize + directorySize + 22 + comment.length];
// Populate the data[]
// Store each archive member
i = 0;
foreach (ArchiveMember de; directory)
{
de.offset = i;
data[i .. i + 4] = cast(ubyte[])"PK\x03\x04";
putUshort(i + 4, de.extractVersion);
putUshort(i + 6, de.flags);
putUshort(i + 8, de.compressionMethod);
putUint (i + 10, cast(uint)de.time);
putUint (i + 14, de.crc32);
putUint (i + 18, de.compressedSize);
putUint (i + 22, de.expandedData.length);
putUshort(i + 26, cast(ushort)de.name.length);
putUshort(i + 28, cast(ushort)de.extra.length);
i += 30;
data[i .. i + de.name.length] = cast(ubyte[])de.name[];
i += de.name.length;
data[i .. i + de.extra.length] = cast(ubyte[])de.extra[];
i += de.extra.length;
data[i .. i + de.compressedSize] = de.compressedData[];
i += de.compressedSize;
}
// Write directory
directoryOffset = i;
numEntries = 0;
foreach (ArchiveMember de; directory)
{
data[i .. i + 4] = cast(ubyte[])"PK\x01\x02";
putUshort(i + 4, de.madeVersion);
putUshort(i + 6, de.extractVersion);
putUshort(i + 8, de.flags);
putUshort(i + 10, de.compressionMethod);
putUint (i + 12, cast(uint)de.time);
putUint (i + 16, de.crc32);
putUint (i + 20, de.compressedSize);
putUint (i + 24, de.expandedSize);
putUshort(i + 28, cast(ushort)de.name.length);
putUshort(i + 30, cast(ushort)de.extra.length);
putUshort(i + 32, cast(ushort)de.comment.length);
putUshort(i + 34, de.diskNumber);
putUshort(i + 36, de.internalAttributes);
putUint (i + 38, de.externalAttributes);
putUint (i + 42, de.offset);
i += 46;
data[i .. i + de.name.length] = cast(ubyte[])de.name[];
i += de.name.length;
data[i .. i + de.extra.length] = cast(ubyte[])de.extra[];
i += de.extra.length;
data[i .. i + de.comment.length] = cast(ubyte[])de.comment[];
i += de.comment.length;
numEntries++;
}
totalEntries = numEntries;
// Write end record
endrecOffset = i;
data[i .. i + 4] = cast(ubyte[])"PK\x05\x06";
putUshort(i + 4, cast(ushort)diskNumber);
putUshort(i + 6, cast(ushort)diskStartDir);
putUshort(i + 8, cast(ushort)numEntries);
putUshort(i + 10, cast(ushort)totalEntries);
putUint (i + 12, directorySize);
putUint (i + 16, directoryOffset);
putUshort(i + 20, cast(ushort)comment.length);
i += 22;
// Write archive comment
assert(i + comment.length == data.length);
data[i .. data.length] = cast(ubyte[])comment[];
return cast(void[])data;
}
/* ============ Reading an existing archive =================== */
/**
* Constructor to use when reading an existing archive.
*
* Fills in the properties data[], diskNumber, diskStartDir, numEntries,
* totalEntries, comment[], and directory[].
* For each ArchiveMember, fills in
* properties madeVersion, extractVersion, flags, compressionMethod, time,
* crc32, compressedSize, expandedSize, compressedData[], diskNumber,
* internalAttributes, externalAttributes, name[], extra[], comment[].
* Use expand() to get the expanded data for each ArchiveMember.
*
* Params:
* buffer = the entire contents of the archive.
*/
this(void[] buffer)
{ int iend;
int i;
int endcommentlength;
uint directorySize;
uint directoryOffset;
this.data = cast(ubyte[]) buffer;
// Find 'end record index' by searching backwards for signature
iend = data.length - 66000;
if (iend < 0)
iend = 0;
for (i = data.length - 22; 1; i--)
{
if (i < iend)
throw new ZipException("no end record");
if (data[i .. i + 4] == cast(ubyte[])"PK\x05\x06")
{
endcommentlength = getUshort(i + 20);
if (i + 22 + endcommentlength > data.length)
continue;
comment = cast(char[])data[i + 22 .. i + 22 + endcommentlength];
endrecOffset = i;
break;
}
}
// Read end record data
diskNumber = getUshort(i + 4);
diskStartDir = getUshort(i + 6);
numEntries = getUshort(i + 8);
totalEntries = getUshort(i + 10);
if (numEntries != totalEntries)
throw new ZipException("multiple disk zips not supported");
directorySize = getUint(i + 12);
directoryOffset = getUint(i + 16);
if (directoryOffset + directorySize > i)
throw new ZipException("corrupted directory");
i = directoryOffset;
for (int n = 0; n < numEntries; n++)
{
/* The format of an entry is:
* 'PK' 1, 2
* directory info
* path
* extra data
* comment
*/
uint offset;
uint namelen;
uint extralen;
uint commentlen;
if (data[i .. i + 4] != cast(ubyte[])"PK\x01\x02")
throw new ZipException("invalid directory entry 1");
ArchiveMember de = new ArchiveMember();
de.madeVersion = getUshort(i + 4);
de.extractVersion = getUshort(i + 6);
de.flags = getUshort(i + 8);
de.compressionMethod = getUshort(i + 10);
de.time = cast(DosFileTime)getUint(i + 12);
de.crc32 = getUint(i + 16);
de.compressedSize = getUint(i + 20);
de.expandedSize = getUint(i + 24);
namelen = getUshort(i + 28);
extralen = getUshort(i + 30);
commentlen = getUshort(i + 32);
de.diskNumber = getUshort(i + 34);
de.internalAttributes = getUshort(i + 36);
de.externalAttributes = getUint(i + 38);
de.offset = getUint(i + 42);
i += 46;
if (i + namelen + extralen + commentlen > directoryOffset + directorySize)
throw new ZipException("invalid directory entry 2");
de.name = cast(char[])data[i .. i + namelen];
i += namelen;
de.extra = data[i .. i + extralen];
i += extralen;
de.comment = cast(char[])data[i .. i + commentlen];
i += commentlen;
directory[de.name] = de;
}
if (i != directoryOffset + directorySize)
throw new ZipException("invalid directory entry 3");
}
/*****
* Decompress the contents of archive member de and return the expanded
* data.
*
* Fills in properties extractVersion, flags, compressionMethod, time,
* crc32, compressedSize, expandedSize, expandedData[], name[], extra[].
*/
ubyte[] expand(ArchiveMember de)
{ uint namelen;
uint extralen;
if (data[de.offset .. de.offset + 4] != cast(ubyte[])"PK\x03\x04")
throw new ZipException("invalid directory entry 4");
// These values should match what is in the main zip archive directory
de.extractVersion = getUshort(de.offset + 4);
de.flags = getUshort(de.offset + 6);
de.compressionMethod = getUshort(de.offset + 8);
de.time = cast(DosFileTime)getUint(de.offset + 10);
de.crc32 = getUint(de.offset + 14);
de.compressedSize = getUint(de.offset + 18);
de.expandedSize = getUint(de.offset + 22);
namelen = getUshort(de.offset + 26);
extralen = getUshort(de.offset + 28);
debug(print)
{
printf("\t\texpandedSize = %d\n", de.expandedSize);
printf("\t\tcompressedSize = %d\n", de.compressedSize);
printf("\t\tnamelen = %d\n", namelen);
printf("\t\textralen = %d\n", extralen);
}
if (de.flags & 1)
throw new ZipException("encryption not supported");
int i;
i = de.offset + 30 + namelen + extralen;
if (i + de.compressedSize > endrecOffset)
throw new ZipException("invalid directory entry 5");
de.compressedData = data[i .. i + de.compressedSize];
debug(print) arrayPrint(de.compressedData);
switch (de.compressionMethod)
{
case 0:
de.expandedData = de.compressedData;
return de.expandedData;
case 8:
// -15 is a magic value used to decompress zip files.
// It has the effect of not requiring the 2 byte header
// and 4 byte trailer.
de.expandedData = cast(ubyte[])std.zlib.uncompress(cast(void[])de.compressedData, de.expandedSize, -15);
return de.expandedData;
default:
throw new ZipException("unsupported compression method");
}
assert(0);
}
/* ============ Utility =================== */
ushort getUshort(int i)
{
version (LittleEndian)
{
return *cast(ushort *)&data[i];
}
else
{
ubyte b0 = data[i];
ubyte b1 = data[i + 1];
return (b1 << 8) | b0;
}
}
uint getUint(int i)
{
version (LittleEndian)
{
return *cast(uint *)&data[i];
}
else
{
return bswap(*cast(uint *)&data[i]);
}
}
void putUshort(int i, ushort us)
{
version (LittleEndian)
{
*cast(ushort *)&data[i] = us;
}
else
{
data[i] = cast(ubyte)us;
data[i + 1] = cast(ubyte)(us >> 8);
}
}
void putUint(int i, uint ui)
{
version (BigEndian)
{
ui = bswap(ui);
}
*cast(uint *)&data[i] = ui;
}
}
debug(print)
{
void arrayPrint(ubyte[] array)
{
printf("array %p,%d\n", cast(void*)array, array.length);
for (int i = 0; i < array.length; i++)
{
printf("%02x ", array[i]);
if (((i + 1) & 15) == 0)
printf("\n");
}
printf("\n");
}
}

View File

@@ -1,618 +0,0 @@
/**
* Compress/decompress data using the $(LINK2 http://www._zlib.net, zlib library).
*
* References:
* $(LINK2 http://en.wikipedia.org/wiki/Zlib, Wikipedia)
* License:
* Public Domain
*
* Macros:
* WIKI = Phobos/StdZlib
*/
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
Modified by David Friedman, February 2007
*/
module std.zlib;
//debug=zlib; // uncomment to turn on debugging printf's
private import etc.c.zlib, std.stdint;
// Values for 'mode'
enum
{
Z_NO_FLUSH = 0,
Z_SYNC_FLUSH = 2,
Z_FULL_FLUSH = 3,
Z_FINISH = 4,
}
/*************************************
* Errors throw a ZlibException.
*/
class ZlibException : Exception
{
this(int errnum)
{ char[] msg;
switch (errnum)
{
case Z_STREAM_END: msg = "stream end"; break;
case Z_NEED_DICT: msg = "need dict"; break;
case Z_ERRNO: msg = "errno"; break;
case Z_STREAM_ERROR: msg = "stream error"; break;
case Z_DATA_ERROR: msg = "data error"; break;
case Z_MEM_ERROR: msg = "mem error"; break;
case Z_BUF_ERROR: msg = "buf error"; break;
case Z_VERSION_ERROR: msg = "version error"; break;
default: msg = "unknown error"; break;
}
super(msg);
}
}
/**************************************************
* Compute the Adler32 checksum of the data in buf[]. adler is the starting
* value when computing a cumulative checksum.
*/
uint adler32(uint adler, void[] buf)
{
return etc.c.zlib.adler32(adler, cast(ubyte *)buf, buf.length);
}
unittest
{
static ubyte[] data = [1,2,3,4,5,6,7,8,9,10];
uint adler;
debug(zlib) printf("D.zlib.adler32.unittest\n");
adler = adler32(0u, cast(void[])data);
debug(zlib) printf("adler = %x\n", adler);
assert(adler == 0xdc0037);
}
/*********************************
* Compute the CRC32 checksum of the data in buf[]. crc is the starting value
* when computing a cumulative checksum.
*/
uint crc32(uint crc, void[] buf)
{
return etc.c.zlib.crc32(crc, cast(ubyte *)buf, buf.length);
}
unittest
{
static ubyte[] data = [1,2,3,4,5,6,7,8,9,10];
uint crc;
debug(zlib) printf("D.zlib.crc32.unittest\n");
crc = crc32(0u, cast(void[])data);
debug(zlib) printf("crc = %x\n", crc);
assert(crc == 0x2520577b);
}
/*********************************************
* Compresses the data in srcbuf[] using compression _level level.
* The default value
* for level is 6, legal values are 1..9, with 1 being the least compression
* and 9 being the most.
* Returns the compressed data.
*/
void[] compress(void[] srcbuf, int level)
in
{
assert(-1 <= level && level <= 9);
}
body
{
int err;
ubyte[] destbuf;
Culong_t destlen;
destlen = srcbuf.length + ((srcbuf.length + 1023) / 1024) + 12;
destbuf = new ubyte[destlen];
err = etc.c.zlib.compress2(destbuf.ptr, &destlen, cast(ubyte *)srcbuf, srcbuf.length, level);
if (err)
{ delete destbuf;
throw new ZlibException(err);
}
destbuf.length = destlen;
return destbuf;
}
/*********************************************
* ditto
*/
void[] compress(void[] buf)
{
return compress(buf, Z_DEFAULT_COMPRESSION);
}
/*********************************************
* Decompresses the data in srcbuf[].
* Params: destlen = size of the uncompressed data.
* It need not be accurate, but the decompression will be faster if the exact
* size is supplied.
* Returns: the decompressed data.
*/
void[] uncompress(void[] srcbuf, size_t destlen = 0u, int winbits = 15)
{
int err;
ubyte[] destbuf;
if (!destlen)
destlen = srcbuf.length * 2 + 1;
while (1)
{
etc.c.zlib.z_stream zs;
destbuf = new ubyte[destlen];
zs.next_in = cast(ubyte*) srcbuf;
zs.avail_in = srcbuf.length;
zs.next_out = destbuf.ptr;
zs.avail_out = destlen;
err = etc.c.zlib.inflateInit2(&zs, winbits);
if (err)
{ delete destbuf;
throw new ZlibException(err);
}
err = etc.c.zlib.inflate(&zs, Z_NO_FLUSH);
switch (err)
{
case Z_OK:
etc.c.zlib.inflateEnd(&zs);
destlen = destbuf.length * 2;
continue;
case Z_STREAM_END:
destbuf.length = zs.total_out;
err = etc.c.zlib.inflateEnd(&zs);
if (err != Z_OK)
goto Lerr;
return destbuf;
default:
etc.c.zlib.inflateEnd(&zs);
Lerr:
delete destbuf;
throw new ZlibException(err);
}
}
assert(0);
}
unittest
{
ubyte[] src = cast(ubyte[])
"the quick brown fox jumps over the lazy dog\r
the quick brown fox jumps over the lazy dog\r
";
ubyte[] dst;
ubyte[] result;
//arrayPrint(src);
dst = cast(ubyte[])compress(cast(void[])src);
//arrayPrint(dst);
result = cast(ubyte[])uncompress(cast(void[])dst);
//arrayPrint(result);
assert(result == src);
}
/+
void arrayPrint(ubyte[] array)
{
//printf("array %p,%d\n", (void*)array, array.length);
for (int i = 0; i < array.length; i++)
{
printf("%02x ", array[i]);
if (((i + 1) & 15) == 0)
printf("\n");
}
printf("\n\n");
}
+/
/*********************************************
* Used when the data to be compressed is not all in one buffer.
*/
class Compress
{
private:
z_stream zs;
int level = Z_DEFAULT_COMPRESSION;
int inited;
void error(int err)
{
if (inited)
{ deflateEnd(&zs);
inited = 0;
}
throw new ZlibException(err);
}
public:
/**
* Construct. level is the same as for D.zlib.compress().
*/
this(int level)
in
{
assert(1 <= level && level <= 9);
}
body
{
this.level = level;
}
/// ditto
this()
{
}
~this()
{ int err;
if (inited)
{
inited = 0;
err = deflateEnd(&zs);
if (err)
error(err);
}
}
/**
* Compress the data in buf and return the compressed data.
* The buffers
* returned from successive calls to this should be concatenated together.
*/
void[] compress(void[] buf)
{ int err;
ubyte[] destbuf;
if (buf.length == 0)
return null;
if (!inited)
{
err = deflateInit(&zs, level);
if (err)
error(err);
inited = 1;
}
destbuf = new ubyte[zs.avail_in + buf.length];
zs.next_out = destbuf.ptr;
zs.avail_out = destbuf.length;
if (zs.avail_in)
buf = cast(void[])zs.next_in[0 .. zs.avail_in] ~ buf;
zs.next_in = cast(ubyte*) buf.ptr;
zs.avail_in = buf.length;
err = deflate(&zs, Z_NO_FLUSH);
if (err != Z_STREAM_END && err != Z_OK)
{ delete destbuf;
error(err);
}
destbuf.length = destbuf.length - zs.avail_out;
return destbuf;
}
/***
* Compress and return any remaining data.
* The returned data should be appended to that returned by compress().
* Params:
* mode = one of the following:
* $(DL
$(DT Z_SYNC_FLUSH )
$(DD Syncs up flushing to the next byte boundary.
Used when more data is to be compressed later on.)
$(DT Z_FULL_FLUSH )
$(DD Syncs up flushing to the next byte boundary.
Used when more data is to be compressed later on,
and the decompressor needs to be restartable at this
point.)
$(DT Z_FINISH)
$(DD (default) Used when finished compressing the data. )
)
*/
void[] flush(int mode = Z_FINISH)
in
{
assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH);
}
body
{
void[] destbuf;
ubyte[512] tmpbuf = void;
int err;
if (!inited)
return null;
/* may be zs.avail_out+<some constant>
* zs.avail_out is set nonzero by deflate in previous compress()
*/
//tmpbuf = new void[zs.avail_out];
zs.next_out = tmpbuf.ptr;
zs.avail_out = tmpbuf.length;
while( (err = deflate(&zs, mode)) != Z_STREAM_END)
{
if (err == Z_OK)
{
if (zs.avail_out != 0 && mode != Z_FINISH)
break;
else if(zs.avail_out == 0)
{
destbuf ~= tmpbuf;
zs.next_out = tmpbuf.ptr;
zs.avail_out = tmpbuf.length;
continue;
}
err = Z_BUF_ERROR;
}
delete destbuf;
error(err);
}
destbuf ~= tmpbuf[0 .. (tmpbuf.length - zs.avail_out)];
if (mode == Z_FINISH)
{
err = deflateEnd(&zs);
inited = 0;
if (err)
error(err);
}
return destbuf;
}
}
/******
* Used when the data to be decompressed is not all in one buffer.
*/
class UnCompress
{
private:
z_stream zs;
int inited;
int done;
uint destbufsize;
void error(int err)
{
if (inited)
{ inflateEnd(&zs);
inited = 0;
}
throw new ZlibException(err);
}
public:
/**
* Construct. destbufsize is the same as for D.zlib.uncompress().
*/
this(uint destbufsize)
{
this.destbufsize = destbufsize;
}
/** ditto */
this()
{
}
~this()
{ int err;
if (inited)
{
inited = 0;
err = inflateEnd(&zs);
if (err)
error(err);
}
done = 1;
}
/**
* Decompress the data in buf and return the decompressed data.
* The buffers returned from successive calls to this should be concatenated
* together.
*/
void[] uncompress(void[] buf)
in
{
assert(!done);
}
body
{ int err;
ubyte[] destbuf;
if (buf.length == 0)
return null;
if (!inited)
{
err = inflateInit(&zs);
if (err)
error(err);
inited = 1;
}
if (!destbufsize)
destbufsize = buf.length * 2;
destbuf = new ubyte[zs.avail_in * 2 + destbufsize];
zs.next_out = destbuf.ptr;
zs.avail_out = destbuf.length;
if (zs.avail_in)
buf = cast(void[])zs.next_in[0 .. zs.avail_in] ~ buf;
zs.next_in = cast(ubyte*) buf;
zs.avail_in = buf.length;
err = inflate(&zs, Z_NO_FLUSH);
if (err != Z_STREAM_END && err != Z_OK)
{ delete destbuf;
error(err);
}
destbuf.length = destbuf.length - zs.avail_out;
return destbuf;
}
/**
* Decompress and return any remaining data.
* The returned data should be appended to that returned by uncompress().
* The UnCompress object cannot be used further.
*/
void[] flush()
in
{
assert(!done);
}
out
{
assert(done);
}
body
{
ubyte[] extra;
ubyte[] destbuf;
int err;
done = 1;
if (!inited)
return null;
L1:
destbuf = new ubyte[zs.avail_in * 2 + 100];
zs.next_out = destbuf.ptr;
zs.avail_out = destbuf.length;
err = etc.c.zlib.inflate(&zs, Z_NO_FLUSH);
if (err == Z_OK && zs.avail_out == 0)
{
extra ~= destbuf;
goto L1;
}
if (err != Z_STREAM_END)
{
delete destbuf;
if (err == Z_OK)
err = Z_BUF_ERROR;
error(err);
}
destbuf = destbuf.ptr[0 .. zs.next_out - destbuf.ptr];
err = etc.c.zlib.inflateEnd(&zs);
inited = 0;
if (err)
error(err);
if (extra.length)
destbuf = extra ~ destbuf;
return destbuf;
}
}
/* ========================== unittest ========================= */
private import std.stdio;
private import std.random;
unittest // by Dave
{
debug(zlib) printf("std.zlib.unittest\n");
bool CompressThenUncompress (ubyte[] src)
{
try {
ubyte[] dst = cast(ubyte[])std.zlib.compress(cast(void[])src);
double ratio = (dst.length / cast(double)src.length);
debug(zlib) writef("src.length: ", src.length, ", dst: ", dst.length, ", Ratio = ", ratio);
ubyte[] uncompressedBuf;
uncompressedBuf = cast(ubyte[])std.zlib.uncompress(cast(void[])dst);
assert(src.length == uncompressedBuf.length);
assert(src == uncompressedBuf);
}
catch {
debug(zlib) writefln(" ... Exception thrown when src.length = ", src.length, ".");
return false;
}
return true;
}
// smallish buffers
for(int idx = 0; idx < 25; idx++) {
char[] buf = new char[rand() % 100];
// Alternate between more & less compressible
foreach(inout char c; buf) c = ' ' + (rand() % (idx % 2 ? 91 : 2));
if(CompressThenUncompress(cast(ubyte[])buf)) {
debug(zlib) printf("; Success.\n");
} else {
return;
}
}
// larger buffers
for(int idx = 0; idx < 25; idx++) {
char[] buf = new char[rand() % 1000/*0000*/];
// Alternate between more & less compressible
foreach(inout char c; buf) c = ' ' + (rand() % (idx % 2 ? 91 : 10));
if(CompressThenUncompress(cast(ubyte[])buf)) {
debug(zlib) printf("; Success.\n");
} else {
return;
}
}
debug(zlib) printf("PASSED std.zlib.unittest\n");
}
unittest // by Artem Rebrov
{
Compress cmp = new Compress;
UnCompress decmp = new UnCompress;
void[] input;
input = "tesatdffadf";
void[] buf = cmp.compress(input);
buf ~= cmp.flush();
void[] output = decmp.uncompress(buf);
//writefln("input = '%s'", cast(char[])input);
//writefln("output = '%s'", cast(char[])output);
assert( output[] == input[] );
}

View File

@@ -1,39 +0,0 @@
// byte
module typeinfo1.ti_byte;
class TypeInfo_g : TypeInfo
{
char[] toString() { return "byte"; }
hash_t getHash(void *p)
{
return *cast(byte *)p;
}
int equals(void *p1, void *p2)
{
return *cast(byte *)p1 == *cast(byte *)p2;
}
int compare(void *p1, void *p2)
{
return *cast(byte *)p1 - *cast(byte *)p2;
}
size_t tsize()
{
return byte.sizeof;
}
void swap(void *p1, void *p2)
{
byte t;
t = *cast(byte *)p1;
*cast(byte *)p1 = *cast(byte *)p2;
*cast(byte *)p2 = t;
}
}

View File

@@ -1,67 +0,0 @@
// cdouble
module typeinfo1.ti_cdouble;
class TypeInfo_r : TypeInfo
{
char[] toString() { return "cdouble"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
(cast(uint *)p)[2] + (cast(uint *)p)[3];
}
static int _equals(cdouble f1, cdouble f2)
{
return f1 == f2;
}
static int _compare(cdouble f1, cdouble f2)
{ int result;
if (f1.re < f2.re)
result = -1;
else if (f1.re > f2.re)
result = 1;
else if (f1.im < f2.im)
result = -1;
else if (f1.im > f2.im)
result = 1;
else
result = 0;
return result;
}
int equals(void *p1, void *p2)
{
return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
}
size_t tsize()
{
return cdouble.sizeof;
}
void swap(void *p1, void *p2)
{
cdouble t;
t = *cast(cdouble *)p1;
*cast(cdouble *)p1 = *cast(cdouble *)p2;
*cast(cdouble *)p2 = t;
}
void[] init()
{ static cdouble r;
return (cast(cdouble *)&r)[0 .. 1];
}
}

View File

@@ -1,66 +0,0 @@
// cfloat
module typeinfo1.ti_cfloat;
class TypeInfo_q : TypeInfo
{
char[] toString() { return "cfloat"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1];
}
static int _equals(cfloat f1, cfloat f2)
{
return f1 == f2;
}
static int _compare(cfloat f1, cfloat f2)
{ int result;
if (f1.re < f2.re)
result = -1;
else if (f1.re > f2.re)
result = 1;
else if (f1.im < f2.im)
result = -1;
else if (f1.im > f2.im)
result = 1;
else
result = 0;
return result;
}
int equals(void *p1, void *p2)
{
return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
}
size_t tsize()
{
return cfloat.sizeof;
}
void swap(void *p1, void *p2)
{
cfloat t;
t = *cast(cfloat *)p1;
*cast(cfloat *)p1 = *cast(cfloat *)p2;
*cast(cfloat *)p2 = t;
}
void[] init()
{ static cfloat r;
return (cast(cfloat *)&r)[0 .. 1];
}
}

View File

@@ -1,43 +0,0 @@
module typeinfo1.ti_char;
class TypeInfo_a : TypeInfo
{
char[] toString() { return "char"; }
hash_t getHash(void *p)
{
return *cast(char *)p;
}
int equals(void *p1, void *p2)
{
return *cast(char *)p1 == *cast(char *)p2;
}
int compare(void *p1, void *p2)
{
return *cast(char *)p1 - *cast(char *)p2;
}
size_t tsize()
{
return char.sizeof;
}
void swap(void *p1, void *p2)
{
char t;
t = *cast(char *)p1;
*cast(char *)p1 = *cast(char *)p2;
*cast(char *)p2 = t;
}
void[] init()
{ static char c;
return (cast(char *)&c)[0 .. 1];
}
}

View File

@@ -1,68 +0,0 @@
// creal
module typeinfo1.ti_creal;
class TypeInfo_c : TypeInfo
{
char[] toString() { return "creal"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
(cast(uint *)p)[2] + (cast(uint *)p)[3] +
(cast(uint *)p)[4];
}
static int _equals(creal f1, creal f2)
{
return f1 == f2;
}
static int _compare(creal f1, creal f2)
{ int result;
if (f1.re < f2.re)
result = -1;
else if (f1.re > f2.re)
result = 1;
else if (f1.im < f2.im)
result = -1;
else if (f1.im > f2.im)
result = 1;
else
result = 0;
return result;
}
int equals(void *p1, void *p2)
{
return _equals(*cast(creal *)p1, *cast(creal *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(creal *)p1, *cast(creal *)p2);
}
size_t tsize()
{
return creal.sizeof;
}
void swap(void *p1, void *p2)
{
creal t;
t = *cast(creal *)p1;
*cast(creal *)p1 = *cast(creal *)p2;
*cast(creal *)p2 = t;
}
void[] init()
{ static creal r;
return (cast(creal *)&r)[0 .. 1];
}
}

View File

@@ -1,45 +0,0 @@
// dchar
module typeinfo1.ti_dchar;
class TypeInfo_w : TypeInfo
{
char[] toString() { return "dchar"; }
hash_t getHash(void *p)
{
return *cast(dchar *)p;
}
int equals(void *p1, void *p2)
{
return *cast(dchar *)p1 == *cast(dchar *)p2;
}
int compare(void *p1, void *p2)
{
return *cast(dchar *)p1 - *cast(dchar *)p2;
}
size_t tsize()
{
return dchar.sizeof;
}
void swap(void *p1, void *p2)
{
dchar t;
t = *cast(dchar *)p1;
*cast(dchar *)p1 = *cast(dchar *)p2;
*cast(dchar *)p2 = t;
}
void[] init()
{ static dchar c;
return (cast(dchar *)&c)[0 .. 1];
}
}

View File

@@ -1,40 +0,0 @@
// delegate
module typeinfo1.ti_delegate;
alias void delegate(int) dg;
class TypeInfo_D : TypeInfo
{
hash_t getHash(void *p)
{ long l = *cast(long *)p;
return cast(uint)(l + (l >> 32));
}
int equals(void *p1, void *p2)
{
return *cast(dg *)p1 == *cast(dg *)p2;
}
size_t tsize()
{
return dg.sizeof;
}
void swap(void *p1, void *p2)
{
dg t;
t = *cast(dg *)p1;
*cast(dg *)p1 = *cast(dg *)p2;
*cast(dg *)p2 = t;
}
uint flags()
{
return 1;
}
}

View File

@@ -1,70 +0,0 @@
// double
module typeinfo1.ti_double;
class TypeInfo_d : TypeInfo
{
char[] toString() { return "double"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1];
}
static bool _isnan(double d)
{
return d !<>= 0;
}
static int _equals(double f1, double f2)
{
return f1 == f2 ||
(_isnan(f1) && _isnan(f2));
}
static int _compare(double d1, double d2)
{
if (d1 !<>= d2) // if either are NaN
{
if (_isnan(d1))
{ if (_isnan(d2))
return 0;
return -1;
}
return 1;
}
return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
}
int equals(void *p1, void *p2)
{
return _equals(*cast(double *)p1, *cast(double *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(double *)p1, *cast(double *)p2);
}
size_t tsize()
{
return double.sizeof;
}
void swap(void *p1, void *p2)
{
double t;
t = *cast(double *)p1;
*cast(double *)p1 = *cast(double *)p2;
*cast(double *)p2 = t;
}
void[] init()
{ static double r;
return (&r)[0 .. 1];
}
}

View File

@@ -1,70 +0,0 @@
// float
module typeinfo1.ti_float;
import std.gc: malloc;
class TypeInfo_f : TypeInfo
{
char[] toString() { return "float"; }
hash_t getHash(void *p)
{
return *cast(uint *)p;
}
static bool _isnan(float f)
{
return f !<>= 0;
}
static int _equals(float f1, float f2)
{
return f1 == f2 ||
(_isnan(f1) && _isnan(f2));
}
static int _compare(float d1, float d2)
{
if (d1 !<>= d2) // if either are NaN
{
if (_isnan(d1))
{ if (_isnan(d2))
return 0;
return -1;
}
return 1;
}
return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
}
int equals(void *p1, void *p2)
{
return _equals(*cast(float *)p1, *cast(float *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(float *)p1, *cast(float *)p2);
}
size_t tsize()
{
return float.sizeof;
}
void swap(void *p1, void *p2)
{
float t;
t = *cast(float *)p1;
*cast(float *)p1 = *cast(float *)p2;
*cast(float *)p2 = t;
}
void[] init()
{
return (cast(float*)malloc(float.sizeof))[0..1];
}
}

View File

@@ -1,12 +0,0 @@
// idouble
module typeinfo1.ti_idouble;
private import typeinfo1.ti_double;
class TypeInfo_p : TypeInfo_d
{
char[] toString() { return "idouble"; }
}

View File

@@ -1,12 +0,0 @@
// ifloat
module typeinfo1.ti_ifloat;
private import typeinfo1.ti_float;
class TypeInfo_o : TypeInfo_f
{
char[] toString() { return "ifloat"; }
}

View File

@@ -1,43 +0,0 @@
// int
module typeinfo1.ti_int;
class TypeInfo_i : TypeInfo
{
char[] toString() { return "int"; }
hash_t getHash(void *p)
{
return *cast(uint *)p;
}
int equals(void *p1, void *p2)
{
return *cast(uint *)p1 == *cast(uint *)p2;
}
int compare(void *p1, void *p2)
{
if (*cast(int*) p1 < *cast(int*) p2)
return -1;
else if (*cast(int*) p1 > *cast(int*) p2)
return 1;
return 0;
}
size_t tsize()
{
return int.sizeof;
}
void swap(void *p1, void *p2)
{
int t;
t = *cast(int *)p1;
*cast(int *)p1 = *cast(int *)p2;
*cast(int *)p2 = t;
}
}

Some files were not shown because too many files have changed in this diff Show More