From e1850b5ee7c5b09f8b5bdd4823cf096be863167d Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 21:27:06 +0000 Subject: [PATCH 01/81] PowerPC WIP. Some of this is indeed hacky and will be changed. svn path=/branches/powerpc/; revision=22591 --- reactos/tools/nci/nci.mak | 6 +- reactos/tools/nci/ncitool.c | 85 ++++++++---- reactos/tools/pefixup.mak | 4 +- reactos/tools/ppc.lost+found/link-ntoskrnl | 3 + reactos/tools/ppc.lost+found/pmake | 12 ++ reactos/tools/rsym.c | 32 +++++ reactos/tools/rsym.h | 2 +- reactos/tools/ssprintf.cpp | 6 + reactos/tools/wrc/newstruc.c | 149 +++++++++------------ reactos/tools/wrc/wrc.mak | 4 +- reactos/tools/wrc/wrctypes.h | 5 + 11 files changed, 191 insertions(+), 117 deletions(-) create mode 100755 reactos/tools/ppc.lost+found/link-ntoskrnl create mode 100755 reactos/tools/ppc.lost+found/pmake diff --git a/reactos/tools/nci/nci.mak b/reactos/tools/nci/nci.mak index f98e801a519..c3e6c76a200 100644 --- a/reactos/tools/nci/nci.mak +++ b/reactos/tools/nci/nci.mak @@ -30,11 +30,11 @@ NCI_HOST_LFLAGS = $(TOOLS_LFLAGS) $(NCI_TARGET): $(NCI_OBJECTS) | $(NCI_OUT) $(ECHO_LD) - ${host_gcc} $(NCI_OBJECTS) $(NCI_HOST_LFLAGS) -o $@ + ${host_gcc} -g $(NCI_OBJECTS) $(NCI_HOST_LFLAGS) -o $@ $(NCI_INT_)ncitool.o: $(NCI_BASE_)ncitool.c | $(NCI_INT) $(ECHO_CC) - ${host_gcc} $(NCI_HOST_CFLAGS) -c $< -o $@ + ${host_gcc} -g $(NCI_HOST_CFLAGS) -c $< -o $@ .PHONY: nci_clean nci_clean: @@ -63,7 +63,7 @@ NCI_SERVICE_FILES = \ $(NCI_SERVICE_FILES): $(NCI_TARGET) $(KERNEL_SVC_DB) $(WIN32K_SVC_DB) $(ECHO_NCI) - $(Q)$(NCI_TARGET) \ + $(Q)$(NCI_TARGET) -arch $(ARCH) \ $(KERNEL_SVC_DB) \ $(WIN32K_SVC_DB) \ $(KERNEL_SERVICE_TABLE) \ diff --git a/reactos/tools/nci/ncitool.c b/reactos/tools/nci/ncitool.c index bdfdab8f362..712a5976e32 100644 --- a/reactos/tools/nci/ncitool.c +++ b/reactos/tools/nci/ncitool.c @@ -53,6 +53,16 @@ " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \ " call *%%ecx\n" \ " ret $0x%x\n\n" + +#define UserModeStub_ppc " mflr 0\n" \ + " addi 1,1,-16\n" \ + " li 0,%x\n" \ + " stw 0,1(0)\n" \ + " sc\n" \ + " lwz 0,1(0)\n" \ + " mtlr 0\n" \ + " addi 1,1,16\n" \ + " blr\n" #elif defined(_MSC_VER) #define UserModeStub_x86 " asm { \n" \ " mov eax, %xh\n" \ @@ -75,6 +85,9 @@ " pushl $KGDT_R0_CODE\n" \ " call _KiSystemService\n" \ " ret $0x%x\n\n" + +#define KernelModeStub_ppc " bl KiSystemService\n" \ + " rfi\n" #elif defined(_MSC_VER) #define KernelModeStub_x86 " asm { \n" \ " mov eax, %xh\n" \ @@ -89,14 +102,28 @@ #endif /***** Arch Dependent Stuff ******/ -//#ifdef _M_IX86 -#define ARGS_TO_BYTES(x) x*4 -#define UserModeStub UserModeStub_x86 -#define KernelModeStub KernelModeStub_x86 +struct ncitool_data_t { + const char *arch; + int args_to_bytes; + const char *km_stub; + const char *um_stub; + const char *global_header; + const char *declaration; +}; -//#elseif -//#error Unsupported Architecture -//#endif +struct ncitool_data_t ncitool_data[] = { + { "x86", 4, KernelModeStub_x86, UserModeStub_x86, + ".global _%s@%d\n", "_%s@%d:\n" }, + { "powerpc", 4, KernelModeStub_ppc, UserModeStub_ppc, + "\t.globl %s\n", "%s:\n" }, + { 0 } +}; +int arch_sel = 0; +#define ARGS_TO_BYTES(x) 4*(ncitool_data[arch_sel].args_to_bytes) +#define UserModeStub ncitool_data[arch_sel].um_stub +#define KernelModeStub ncitool_data[arch_sel].km_stub +#define GlobalHeader ncitool_data[arch_sel].global_header +#define Declaration ncitool_data[arch_sel].declaration /* FUNCTIONS ****************************************************************/ @@ -162,10 +189,10 @@ WriteStubHeader(FILE* StubFile, unsigned StackBytes) { /* Export the function */ - fprintf(StubFile, ".global _%s@%d\n", SyscallName, StackBytes); + fprintf(StubFile, GlobalHeader, SyscallName, StackBytes); /* Define it */ - fprintf(StubFile, "_%s@%d:\n\n", SyscallName, StackBytes); + fprintf(StubFile, Declaration, SyscallName, StackBytes); } @@ -489,7 +516,7 @@ CreateSystemServiceTable(FILE *SyscallDb, void usage(char * argv0) { - printf("Usage: %s sysfuncs.lst w32ksvc.db napi.h ssdt.h napi.S zw.S win32k.S win32k.S\n" + printf("Usage: %s [-arch ] sysfuncs.lst w32ksvc.db napi.h ssdt.h napi.S zw.S win32k.S win32k.S\n" " sysfuncs.lst native system functions database\n" " w32ksvc.db native graphic functions database\n" " napi.h NTOSKRNL service table\n" @@ -497,19 +524,31 @@ void usage(char * argv0) " napi.S NTDLL stubs\n" " zw.S NTOSKRNL Zw stubs\n" " win32k.S GDI32 stubs\n" - " win32k.S USER32 stubs\n", + " win32k.S USER32 stubs\n" + " -arch is optional, default is x86\n", argv0 ); } int main(int argc, char* argv[]) { - FILE * Files[Arguments]; - int FileNumber; + FILE * Files[Arguments] = { }; + int FileNumber, ArgOffset = 1; char * OpenType = "r"; + /* Catch architecture argument */ + if (argc > 3 && !strcmp(argv[1],"-arch")) { + int i; + for( i = 0; ncitool_data[arch_sel].arch && strcmp(argv[2],ncitool_data[i].arch); i++ ); + if (!ncitool_data[arch_sel].arch) { + usage(argv[0]); + return 1; + } + arch_sel = i; + ArgOffset = 3; + } /* Make sure all arguments all there */ - if (argc != Arguments + 1) { + if (argc != Arguments + ArgOffset) { usage(argv[0]); return(1); } @@ -519,11 +558,11 @@ int main(int argc, char* argv[]) /* Open the File */ if (FileNumber == 2) OpenType = "wb"; - Files[FileNumber] = fopen(argv[FileNumber + 1], OpenType); + Files[FileNumber] = fopen(argv[FileNumber + ArgOffset], OpenType); /* Check for failure and error out if so */ if (!Files[FileNumber]) { - perror(argv[FileNumber + 1]); + perror(argv[FileNumber + ArgOffset]); return (1); } @@ -532,20 +571,20 @@ int main(int argc, char* argv[]) /* Write the File Headers */ WriteFileHeader(Files[NtosUserStubs], "System Call Stubs for Native API", - argv[NtosUserStubs + 1]); + argv[NtosUserStubs + ArgOffset]); WriteFileHeader(Files[NtosKernelStubs], "System Call Stubs for Native API", - argv[NtosKernelStubs + 1]); + argv[NtosKernelStubs + ArgOffset]); fputs("#include \n\n", Files[NtosKernelStubs]); WriteFileHeader(Files[Win32kGdiStubs], "System Call Stubs for Native API", - argv[Win32kGdiStubs + 1]); + argv[Win32kGdiStubs + ArgOffset]); WriteFileHeader(Files[Win32kUserStubs], "System Call Stubs for Native API", - argv[Win32kUserStubs + 1]); + argv[Win32kUserStubs + ArgOffset]); /* Create the System Stubs */ @@ -572,15 +611,15 @@ int main(int argc, char* argv[]) CreateSystemServiceTable(Files[NativeSystemDb], Files[NtosServiceTable], "Main", - argv[NtosServiceTable + 1]); + argv[NtosServiceTable + ArgOffset]); CreateSystemServiceTable(Files[NativeGuiDb], Files[Win32kServiceTable], "Win32k", - argv[Win32kServiceTable + 1]); + argv[Win32kServiceTable + ArgOffset]); /* Close all files */ - for (FileNumber = 0; FileNumber < Arguments; FileNumber++) { + for (FileNumber = 0; FileNumber < Arguments-ArgOffset; FileNumber++) { /* Close the File */ fclose(Files[FileNumber]); diff --git a/reactos/tools/pefixup.mak b/reactos/tools/pefixup.mak index 7f4aa793981..fec1a90ab7b 100644 --- a/reactos/tools/pefixup.mak +++ b/reactos/tools/pefixup.mak @@ -24,11 +24,11 @@ pefixup: $(PEFIXUP_TARGET) $(PEFIXUP_TARGET): $(PEFIXUP_OBJECTS) | $(PEFIXUP_OUT) $(ECHO_LD) - ${host_gcc} $(PEFIXUP_OBJECTS) $(PEFIXUP_HOST_LFLAGS) -o $@ + ${host_gcc} -g $(PEFIXUP_OBJECTS) $(PEFIXUP_HOST_LFLAGS) -o $@ $(PEFIXUP_INT_)pefixup.o: $(PEFIXUP_BASE_)pefixup.c | $(PEFIXUP_INT) $(ECHO_CC) - ${host_gcc} $(PEFIXUP_HOST_CFLAGS) -c $< -o $@ + ${host_gcc} -g $(PEFIXUP_HOST_CFLAGS) -c $< -o $@ .PHONY: pefixup_clean pefixup_clean: diff --git a/reactos/tools/ppc.lost+found/link-ntoskrnl b/reactos/tools/ppc.lost+found/link-ntoskrnl new file mode 100755 index 00000000000..df2e348dca6 --- /dev/null +++ b/reactos/tools/ppc.lost+found/link-ntoskrnl @@ -0,0 +1,3 @@ +#!/bin/sh -xv + +reactos-powerpc-gcc --begin-group -v -Wl,--subsystem,native -Wl,--entry,NtProcessStartup -Wl,--image-base,0x80000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe obj-ppc/ntoskrnl/ke/powerpc/main_asm.o obj-ppc/ntoskrnl/ke/apc.o obj-ppc/ntoskrnl/ke/bug.o obj-ppc/ntoskrnl/ke/clock.o obj-ppc/ntoskrnl/ke/device.o obj-ppc/ntoskrnl/ke/dpc.o obj-ppc/ntoskrnl/ke/event.o obj-ppc/ntoskrnl/ke/exception.o obj-ppc/ntoskrnl/ke/gate.o obj-ppc/ntoskrnl/ke/gmutex.o obj-ppc/ntoskrnl/ke/ipi.o obj-ppc/ntoskrnl/ke/kqueue.o obj-ppc/ntoskrnl/ke/kthread.o obj-ppc/ntoskrnl/ke/main.o obj-ppc/ntoskrnl/ke/mutex.o obj-ppc/ntoskrnl/ke/process.o obj-ppc/ntoskrnl/ke/profile.o obj-ppc/ntoskrnl/ke/queue.o obj-ppc/ntoskrnl/ke/sem.o obj-ppc/ntoskrnl/ke/spinlock.o obj-ppc/ntoskrnl/ke/timer.o obj-ppc/ntoskrnl/ke/usercall.o obj-ppc/ntoskrnl/ke/wait.o obj-ppc/ntoskrnl/cc/cacheman.o obj-ppc/ntoskrnl/cc/copy.o obj-ppc/ntoskrnl/cc/fs.o obj-ppc/ntoskrnl/cc/mdl.o obj-ppc/ntoskrnl/cc/pin.o obj-ppc/ntoskrnl/cc/view.o obj-ppc/ntoskrnl/cm/import.o obj-ppc/ntoskrnl/cm/ntfunc.o obj-ppc/ntoskrnl/cm/regfile.o obj-ppc/ntoskrnl/cm/registry.o obj-ppc/ntoskrnl/cm/regobj.o obj-ppc/ntoskrnl/dbgk/dbgkutil.o obj-ppc/ntoskrnl/dbgk/debug.o obj-ppc/ntoskrnl/ex/atom.o obj-ppc/ntoskrnl/ex/callback.o obj-ppc/ntoskrnl/ex/dbgctrl.o obj-ppc/ntoskrnl/ex/error.o obj-ppc/ntoskrnl/ex/event.o obj-ppc/ntoskrnl/ex/evtpair.o obj-ppc/ntoskrnl/ex/fmutex.o obj-ppc/ntoskrnl/ex/handle.o obj-ppc/ntoskrnl/ex/init.o obj-ppc/ntoskrnl/ex/lookas.o obj-ppc/ntoskrnl/ex/mutant.o obj-ppc/ntoskrnl/ex/power.o obj-ppc/ntoskrnl/ex/pushlock.o obj-ppc/ntoskrnl/ex/profile.o obj-ppc/ntoskrnl/ex/resource.o obj-ppc/ntoskrnl/ex/rundown.o obj-ppc/ntoskrnl/ex/sem.o obj-ppc/ntoskrnl/ex/sysinfo.o obj-ppc/ntoskrnl/ex/time.o obj-ppc/ntoskrnl/ex/timer.o obj-ppc/ntoskrnl/ex/uuid.o obj-ppc/ntoskrnl/ex/win32k.o obj-ppc/ntoskrnl/ex/work.o obj-ppc/ntoskrnl/ex/zone.o obj-ppc/ntoskrnl/ex/zw.o obj-ppc/ntoskrnl/fs/context.o obj-ppc/ntoskrnl/fs/fastio.o obj-ppc/ntoskrnl/fs/filelock.o obj-ppc/ntoskrnl/fs/mcb.o obj-ppc/ntoskrnl/fs/name.o obj-ppc/ntoskrnl/fs/notify.o obj-ppc/ntoskrnl/fs/oplock.o obj-ppc/ntoskrnl/fs/pool.o obj-ppc/ntoskrnl/fs/tunnel.o obj-ppc/ntoskrnl/fs/unc.o obj-ppc/ntoskrnl/fs/util.o obj-ppc/ntoskrnl/inbv/inbv.o obj-ppc/ntoskrnl/io/adapter.o obj-ppc/ntoskrnl/io/arcname.o obj-ppc/ntoskrnl/io/bootlog.o obj-ppc/ntoskrnl/io/controller.o obj-ppc/ntoskrnl/io/device.o obj-ppc/ntoskrnl/io/deviface.o obj-ppc/ntoskrnl/io/disk.o obj-ppc/ntoskrnl/io/driver.o obj-ppc/ntoskrnl/io/efi.o obj-ppc/ntoskrnl/io/error.o obj-ppc/ntoskrnl/io/event.o obj-ppc/ntoskrnl/io/fs.o obj-ppc/ntoskrnl/io/iocomp.o obj-ppc/ntoskrnl/io/iomgr.o obj-ppc/ntoskrnl/io/iowork.o obj-ppc/ntoskrnl/io/irp.o obj-ppc/ntoskrnl/io/irq.o obj-ppc/ntoskrnl/io/mdl.o obj-ppc/ntoskrnl/io/plugplay.o obj-ppc/ntoskrnl/io/pnpdma.o obj-ppc/ntoskrnl/io/pnpmgr.o obj-ppc/ntoskrnl/io/pnpnotify.o obj-ppc/ntoskrnl/io/pnpreport.o obj-ppc/ntoskrnl/io/pnproot.o obj-ppc/ntoskrnl/io/rawfs.o obj-ppc/ntoskrnl/io/remlock.o obj-ppc/ntoskrnl/io/resource.o obj-ppc/ntoskrnl/io/share.o obj-ppc/ntoskrnl/io/symlink.o obj-ppc/ntoskrnl/io/timer.o obj-ppc/ntoskrnl/io/vpb.o obj-ppc/ntoskrnl/io/wmi.o obj-ppc/ntoskrnl/io/file.o obj-ppc/ntoskrnl/kd/wrappers/bochs.o obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o obj-ppc/ntoskrnl/kd/kdinit.o obj-ppc/ntoskrnl/kd/kdio.o obj-ppc/ntoskrnl/kd/kdmain.o obj-ppc/ntoskrnl/ldr/loader.o obj-ppc/ntoskrnl/ldr/rtl.o obj-ppc/ntoskrnl/lpc/close.o obj-ppc/ntoskrnl/lpc/complete.o obj-ppc/ntoskrnl/lpc/connect.o obj-ppc/ntoskrnl/lpc/create.o obj-ppc/ntoskrnl/lpc/listen.o obj-ppc/ntoskrnl/lpc/port.o obj-ppc/ntoskrnl/lpc/query.o obj-ppc/ntoskrnl/lpc/queue.o obj-ppc/ntoskrnl/lpc/receive.o obj-ppc/ntoskrnl/lpc/reply.o obj-ppc/ntoskrnl/lpc/send.o obj-ppc/ntoskrnl/mm/anonmem.o obj-ppc/ntoskrnl/mm/aspace.o obj-ppc/ntoskrnl/mm/balance.o obj-ppc/ntoskrnl/mm/cont.o obj-ppc/ntoskrnl/mm/drvlck.o obj-ppc/ntoskrnl/mm/freelist.o obj-ppc/ntoskrnl/mm/iospace.o obj-ppc/ntoskrnl/mm/kmap.o obj-ppc/ntoskrnl/mm/marea.o obj-ppc/ntoskrnl/mm/mdl.o obj-ppc/ntoskrnl/mm/mm.o obj-ppc/ntoskrnl/mm/process.o obj-ppc/ntoskrnl/mm/mminit.o obj-ppc/ntoskrnl/mm/mpw.o obj-ppc/ntoskrnl/mm/ncache.o obj-ppc/ntoskrnl/mm/npool.o obj-ppc/ntoskrnl/mm/pagefile.o obj-ppc/ntoskrnl/mm/pageop.o obj-ppc/ntoskrnl/mm/pager.o obj-ppc/ntoskrnl/mm/pagfault.o obj-ppc/ntoskrnl/mm/paging.o obj-ppc/ntoskrnl/mm/pe.o obj-ppc/ntoskrnl/mm/physical.o obj-ppc/ntoskrnl/mm/pool.o obj-ppc/ntoskrnl/mm/ppool.o obj-ppc/ntoskrnl/mm/region.o obj-ppc/ntoskrnl/mm/rmap.o obj-ppc/ntoskrnl/mm/section.o obj-ppc/ntoskrnl/mm/verifier.o obj-ppc/ntoskrnl/mm/virtual.o obj-ppc/ntoskrnl/mm/wset.o obj-ppc/ntoskrnl/mm/elf32.o obj-ppc/ntoskrnl/mm/elf64.o obj-ppc/ntoskrnl/ob/obdir.o obj-ppc/ntoskrnl/ob/obinit.o obj-ppc/ntoskrnl/ob/obhandle.o obj-ppc/ntoskrnl/ob/obname.o obj-ppc/ntoskrnl/ob/oblife.o obj-ppc/ntoskrnl/ob/obref.o obj-ppc/ntoskrnl/ob/sdcache.o obj-ppc/ntoskrnl/ob/security.o obj-ppc/ntoskrnl/ob/symlink.o obj-ppc/ntoskrnl/ob/wait.o obj-ppc/ntoskrnl/po/power.o obj-ppc/ntoskrnl/ps/debug.o obj-ppc/ntoskrnl/ps/idle.o obj-ppc/ntoskrnl/ps/job.o obj-ppc/ntoskrnl/ps/kill.o obj-ppc/ntoskrnl/ps/locale.o obj-ppc/ntoskrnl/ps/notify.o obj-ppc/ntoskrnl/ps/process.o obj-ppc/ntoskrnl/ps/psmgr.o obj-ppc/ntoskrnl/ps/query.o obj-ppc/ntoskrnl/ps/quota.o obj-ppc/ntoskrnl/ps/security.o obj-ppc/ntoskrnl/ps/suspend.o obj-ppc/ntoskrnl/ps/thread.o obj-ppc/ntoskrnl/ps/win32.o obj-ppc/ntoskrnl/rtl/libsupp.o obj-ppc/ntoskrnl/rtl/misc.o obj-ppc/ntoskrnl/rtl/nls.o obj-ppc/ntoskrnl/rtl/regio.o obj-ppc/ntoskrnl/rtl/strtok.o obj-ppc/ntoskrnl/se/access.o obj-ppc/ntoskrnl/se/acl.o obj-ppc/ntoskrnl/se/audit.o obj-ppc/ntoskrnl/se/lsa.o obj-ppc/ntoskrnl/se/luid.o obj-ppc/ntoskrnl/se/priv.o obj-ppc/ntoskrnl/se/sd.o obj-ppc/ntoskrnl/se/semgr.o obj-ppc/ntoskrnl/se/sid.o obj-ppc/ntoskrnl/se/token.o obj-ppc/ntoskrnl/ntoskrnl.coff obj-ppc/ntoskrnl/kdbg/kdb_symbols.o obj-ppc/lib/drivers/csq/csq.a obj-ppc/hal/hal/libhal.a obj-ppc/lib/kjs/kjs.a obj-ppc/lib/pseh/pseh.a obj-ppc/lib/rtl/rtl.a obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/wdmguid/wdmguid.a -nostartfiles -nostdlib -lgcc -g --end-group diff --git a/reactos/tools/ppc.lost+found/pmake b/reactos/tools/ppc.lost+found/pmake new file mode 100755 index 00000000000..2d1ce52ad2e --- /dev/null +++ b/reactos/tools/ppc.lost+found/pmake @@ -0,0 +1,12 @@ +#!/bin/sh + +export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin +make \ + HOST=mingw32-linux \ + ROS_INTERMEDIATE=obj-ppc \ + ROS_OUTPUT=output-ppc \ + ROS_PREFIX=reactos-powerpc \ + ROS_INSTALL=rosppc \ + ROS_AUTOMAKE=makefile.ppc \ + ROS_RBUILDFLAGS=-rReactOS-ppc.rbuild \ + $* diff --git a/reactos/tools/rsym.c b/reactos/tools/rsym.c index aa6e2f01a69..0afe2ffbe06 100644 --- a/reactos/tools/rsym.c +++ b/reactos/tools/rsym.c @@ -27,6 +27,35 @@ #include "rsym.h" +static inline WORD dtohs(WORD in) +{ + PBYTE in_ptr = (PBYTE)∈ + return in_ptr[0] | (in_ptr[1] << 8); +} + +static inline WORD htods(WORD in) +{ + WORD out; + PBYTE out_ptr = (PBYTE)&out; + out_ptr[0] = in; out_ptr[1] = in >> 8; + return out; +} + +static inline DWORD dtohl(DWORD in) +{ + PBYTE in_ptr = (PBYTE)∈ + return in_ptr[0] | (in_ptr[1] << 8) | (in_ptr[2] << 16) | (in_ptr[3] << 24); +} + +static inline DWORD htodl(DWORD in) +{ + DWORD out; + PBYTE out_ptr = (PBYTE)&out; + out_ptr[0] = in ; out_ptr[1] = in >> 8; + out_ptr[2] = in >> 16; out_ptr[3] = in >> 24; + return out; +} + static int CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2) { @@ -814,6 +843,9 @@ int main(int argc, char* argv[]) /* Check if MZ header exists */ PEDosHeader = (PIMAGE_DOS_HEADER) FileData; + PEDosHeader->e_magic = dtohs(PEDosHeader->e_magic); + PEDosHeader->e_lfanew = dtohl(PEDosHeader->e_lfanew); + if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L) { perror("Input file is not a PE image.\n"); diff --git a/reactos/tools/rsym.h b/reactos/tools/rsym.h index b9346058f61..6c68fe91f86 100644 --- a/reactos/tools/rsym.h +++ b/reactos/tools/rsym.h @@ -10,7 +10,7 @@ #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 -typedef unsigned char BYTE; +typedef unsigned char BYTE, *PBYTE; typedef unsigned char UCHAR; typedef unsigned short WORD; typedef unsigned short USHORT; diff --git a/reactos/tools/ssprintf.cpp b/reactos/tools/ssprintf.cpp index 4c54589fb54..a6fbb101e0a 100644 --- a/reactos/tools/ssprintf.cpp +++ b/reactos/tools/ssprintf.cpp @@ -690,6 +690,7 @@ wnumberf(std::wstring& f, double __n, wchar_t exp_sign, int size, int precision return true; } +#ifdef __i386__ static bool numberfl(std::string& f, long double __n, char exp_sign, int size, int precision, int type) { @@ -1091,6 +1092,7 @@ wnumberfl(std::wstring& f, long double __n, wchar_t exp_sign, int size, int pre } return true; } +#endif static int do_string(std::string& f, const char* s, int len, int field_width, int precision, int flags) @@ -1507,7 +1509,9 @@ ssvprintf ( const char *fmt, va_list args ) } else { if ( precision == -1 ) precision = 6; +#ifdef __i386__ result = numberfl(f,_ldouble,*fmt,field_width,precision,flags); +#endif if (result < 0) { assert(!"TODO FIXME handle error better"); @@ -1831,7 +1835,9 @@ sswvprintf ( const wchar_t* fmt, va_list args ) } else { if ( precision == -1 ) precision = 6; +#ifdef __i386__ result = wnumberfl(f,_ldouble,*fmt,field_width,precision,flags); +#endif if (result < 0) { assert(!"TODO FIXME handle error better"); diff --git a/reactos/tools/wrc/newstruc.c b/reactos/tools/wrc/newstruc.c index 5d3ce95cb0b..66c6a4dd55a 100644 --- a/reactos/tools/wrc/newstruc.c +++ b/reactos/tools/wrc/newstruc.c @@ -69,6 +69,29 @@ __NEW_STRUCT_FUNC(string) __NEW_STRUCT_FUNC(toolbar_item) __NEW_STRUCT_FUNC(ani_any) +void hdump( void *v, int l ) { + int i; + char *c = (char *)v, *begin = c; + + while( l > 0 ) { + if( (c - begin) ) + printf("\n"); + printf("%08x:", c); + for( i = 0; i < l && i < 16; i++ ) { + printf(" %02x", c[i] & 0xff); + } + for( ; i < 16; i++ ) { + printf(" "); + } + printf(" -- "); + for( i = 0; i < l && i < 16; i++ ) { + printf("%c", isprint(c[i]) ? c[i] : '.'); + } + c += 16; l -= 16; + } + printf("\n"); +} + /* New instances for all types of structures */ /* Very inefficient (in size), but very functional :-] * Especially for type-checking. @@ -984,7 +1007,10 @@ ver_words_t *add_ver_words(ver_words_t *w, int i) return w; } -#define MSGTAB_BAD_PTR(p, b, l, r) (((l) - ((char *)(p) - (char *)(b))) > (r)) +#define MSGTAB_BAD_PTR(p, b, l, r) \ + (printf("MSGTAB_BAD_PTR(%x,%x,%d,r) => %x > r=%x\n", p,b,l, \ + ((l) - ((char *)(p) - (char *)(b))), r), \ + (((l) - ((char *)(p) - (char *)(b))) > (r))) messagetable_t *new_messagetable(raw_data_t *rd, int *memopt) { messagetable_t *msg = (messagetable_t *)xmalloc(sizeof(messagetable_t)); @@ -1023,97 +1049,48 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt) if(!hi && !lo) yyerror("Invalid messagetable block count 0"); - if(!hi && lo) /* Messagetable byteorder == native byteorder */ - { #ifdef WORDS_BIGENDIAN - if(byteorder != WRC_BO_LITTLE) goto out; + if(byteorder != WRC_BO_LITTLE) goto out; #else - if(byteorder != WRC_BO_BIG) goto out; + if(byteorder != WRC_BO_BIG) goto out; #endif - /* Resource byteorder != native byteorder */ - - mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]); - if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp))) - yyerror("Messagetable's blocks are outside of defined data"); - for(i = 0; i < nblk; i++) - { - msgtab_entry_t *mep, *next_mep; - DWORD id; - - mep = (msgtab_entry_t *)(((char *)rd->data) + mbp[i].offset); - - for(id = mbp[i].idlo; id <= mbp[i].idhi; id++) - { - if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length)) - yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id); - if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */ - { - WORD *wp = (WORD *)&mep[1]; - int l = mep->length/2 - 2; /* Length included header */ - int n; - - if(mep->length & 1) - yyerror("Message 0x%08lx is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length); - for(n = 0; n < l; n++) - wp[n] = BYTESWAP_WORD(wp[n]); - - } - next_mep = (msgtab_entry_t *)(((char *)mep) + mep->length); - mep->length = BYTESWAP_WORD(mep->length); - mep->flags = BYTESWAP_WORD(mep->flags); - mep = next_mep; - } - - mbp[i].idlo = BYTESWAP_DWORD(mbp[i].idlo); - mbp[i].idhi = BYTESWAP_DWORD(mbp[i].idhi); - mbp[i].offset = BYTESWAP_DWORD(mbp[i].offset); - } - } - if(hi && !lo) /* Messagetable byteorder != native byteorder */ + /* Resource byteorder != native byteorder */ + + mbp = BYTESWAP_DWORD((msgtab_block_t *)&(((DWORD *)rd->data)[1])); + if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp))) + yyerror("[1] Messagetable's blocks are outside of defined data"); + for(i = 0; i < nblk; i++) { -#ifdef WORDS_BIGENDIAN - if(byteorder == WRC_BO_LITTLE) goto out; -#else - if(byteorder == WRC_BO_BIG) goto out; -#endif - /* Resource byteorder == native byteorder */ - - mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]); - nblk = BYTESWAP_DWORD(nblk); - if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp))) - yyerror("Messagetable's blocks are outside of defined data"); - for(i = 0; i < nblk; i++) + msgtab_entry_t *mep, *next_mep; + DWORD id; + + mep = (msgtab_entry_t *)(((char *)rd->data) + mbp[i].offset); + + for(id = mbp[i].idlo; id <= mbp[i].idhi; id++) + { + if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length)) + yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id); + if(BYTESWAP_DWORD(mep->flags) == 1) /* Docu says 'flags == 0x0001' for unicode */ { - msgtab_entry_t *mep; - DWORD id; - - mbp[i].idlo = BYTESWAP_DWORD(mbp[i].idlo); - mbp[i].idhi = BYTESWAP_DWORD(mbp[i].idhi); - mbp[i].offset = BYTESWAP_DWORD(mbp[i].offset); - mep = (msgtab_entry_t *)(((char *)rd->data) + mbp[i].offset); - - for(id = mbp[i].idlo; id <= mbp[i].idhi; id++) - { - mep->length = BYTESWAP_WORD(mep->length); - mep->flags = BYTESWAP_WORD(mep->flags); - - if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length)) - yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id); - if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */ - { - WORD *wp = (WORD *)&mep[1]; - int l = mep->length/2 - 2; /* Length included header */ - int n; - - if(mep->length & 1) - yyerror("Message 0x%08lx is unicode (block %d), but has odd length (%d)", id, (int)i, mep->length); - for(n = 0; n < l; n++) - wp[n] = BYTESWAP_WORD(wp[n]); - - } - mep = (msgtab_entry_t *)(((char *)mep) + mep->length); - } + WORD *wp = (WORD *)&mep[1]; + int l = BYTESWAP_DWORD(mep->length)/2 - 2; /* Length included header */ + int n; + + if(BYTESWAP_DWORD(mep->length) & 1) + yyerror("Message 0x%08lx is unicode (block %d), but has odd length (%d)", id, (int)i, BYTESWAP_DWORD(mep->length)); + for(n = 0; n < l; n++) + wp[n] = BYTESWAP_WORD(wp[n]); + } + next_mep = (msgtab_entry_t *)(((char *)mep) + BYTESWAP_DWORD(mep->length)); + mep->length = BYTESWAP_WORD(mep->length); + mep->flags = BYTESWAP_WORD(mep->flags); + mep = next_mep; + } + + mbp[i].idlo = BYTESWAP_DWORD(mbp[i].idlo); + mbp[i].idhi = BYTESWAP_DWORD(mbp[i].idhi); + mbp[i].offset = BYTESWAP_DWORD(mbp[i].offset); } out: diff --git a/reactos/tools/wrc/wrc.mak b/reactos/tools/wrc/wrc.mak index 96a12c66596..43be8c62a0d 100644 --- a/reactos/tools/wrc/wrc.mak +++ b/reactos/tools/wrc/wrc.mak @@ -70,7 +70,7 @@ wrc: $(WRC_TARGET) $(WRC_TARGET): $(WRC_OBJECTS) $(WRC_LIBS) | $(WRC_OUT) $(ECHO_LD) - ${host_gcc} $(WRC_OBJECTS) $(WRC_LIBS) $(WRC_HOST_LFLAGS) -o $@ + ${host_gcc} -g $(WRC_OBJECTS) $(WRC_LIBS) $(WRC_HOST_LFLAGS) -o $@ $(WRC_INT_)dumpres.o: $(WRC_BASE_)dumpres.c | $(WRC_INT) $(ECHO_CC) @@ -82,7 +82,7 @@ $(WRC_INT_)genres.o: $(WRC_BASE_)genres.c | $(WRC_INT) $(WRC_INT_)newstruc.o: $(WRC_BASE_)newstruc.c | $(WRC_INT) $(ECHO_CC) - ${host_gcc} $(WRC_HOST_CFLAGS) -c $< -o $@ + ${host_gcc} -g $(WRC_HOST_CFLAGS) -c $< -o $@ $(WRC_INT_)readres.o: $(WRC_BASE_)readres.c | $(WRC_INT) $(ECHO_CC) diff --git a/reactos/tools/wrc/wrctypes.h b/reactos/tools/wrc/wrctypes.h index f81e79367f4..eab09d3c702 100644 --- a/reactos/tools/wrc/wrctypes.h +++ b/reactos/tools/wrc/wrctypes.h @@ -80,8 +80,13 @@ #define WRC_HIBYTE(w) (((WORD)(w) >> 8) & 0xff) #define WRC_LOWORD(d) ((DWORD)(d) & 0xffff) #define WRC_HIWORD(d) (((DWORD)(d) >> 16) & 0xffff) +#ifndef WORDS_BIGENDIAN #define BYTESWAP_WORD(w) ((WORD)(((WORD)WRC_LOBYTE(w) << 8) + (WORD)WRC_HIBYTE(w))) #define BYTESWAP_DWORD(d) ((DWORD)(((DWORD)BYTESWAP_WORD(WRC_LOWORD(d)) << 16) + ((DWORD)BYTESWAP_WORD(WRC_HIWORD(d))))) +#else +#define BYTESWAP_WORD(w) ((WORD)(w)) +3define BYTESWAP_DWORD(d) ((DWORD)(d)) +#endif /* Binary resource structure */ #define RES_BLOCKSIZE 512 From 771a05678e15c895d62ab8cd00b658f9135804cc Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 21:34:12 +0000 Subject: [PATCH 02/81] ReactOS PowerPC WIP. This will be edited and merged, and likely shrunk. Hacks will be removed and indeed your favorite assembly snippet will eventually not be just 'blr', so please *don't panic*. svn path=/branches/powerpc/; revision=22592 --- reactos/Makefile | 8 +- reactos/ReactOS-ppc.rbuild | 15 +- reactos/boot/freeldr/bootsect/ofwboot.s | 15 +- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 7 +- reactos/boot/freeldr/freeldr/drivemap.c | 2 + .../boot/freeldr/freeldr/include/freeldr.h | 2 + reactos/hal/hal/hal.c | 9 +- reactos/include/ddk/ndis.h | 1 - reactos/include/ddk/winddk.h | 222 +++++++++++++++++- reactos/include/ndk/mmtypes.h | 7 + reactos/include/ndk/powerpc/ketypes.h | 44 +++- reactos/include/ndk/pstypes.h | 4 + reactos/include/reactos/debug.h | 2 +- reactos/include/reactos/elf/machine.h | 4 + reactos/include/reactos/libs/pseh/setjmp.h | 7 + reactos/include/reactos/probe.h | 4 + reactos/include/winnt.h | 21 +- reactos/lib/kjs/ksrc/longjmp.S | 9 +- reactos/lib/kjs/ksrc/setjmp.S | 9 +- reactos/lib/pseh/pseh.rbuild | 16 +- reactos/lib/rossym/find.c | 4 + reactos/lib/rtl/heap.c | 2 + reactos/lib/rtl/nls.c | 4 +- reactos/ntoskrnl/ex/init.c | 4 + reactos/ntoskrnl/ex/power.c | 2 + reactos/ntoskrnl/ex/sysinfo.c | 3 +- reactos/ntoskrnl/include/internal/arch/ke.h | 2 + reactos/ntoskrnl/include/internal/arch/mm.h | 2 + reactos/ntoskrnl/include/internal/arch/ps.h | 3 + reactos/ntoskrnl/include/internal/ex.h | 6 + reactos/ntoskrnl/include/internal/ntoskrnl.h | 9 +- .../ntoskrnl/include/internal/powerpc/ke.h | 46 +++- reactos/ntoskrnl/io/pnpmgr.c | 18 +- reactos/ntoskrnl/kd/kdmain.c | 4 + reactos/ntoskrnl/kd/wrappers/gdbstub.c | 22 ++ reactos/ntoskrnl/ke/apc.c | 4 + reactos/ntoskrnl/ke/bug.c | 6 + reactos/ntoskrnl/ke/clock.c | 4 + reactos/ntoskrnl/ke/dpc.c | 2 +- reactos/ntoskrnl/ke/ipi.c | 8 + reactos/ntoskrnl/ke/kthread.c | 2 + reactos/ntoskrnl/ke/main.c | 1 - reactos/ntoskrnl/ke/process.c | 4 + reactos/ntoskrnl/ke/profile.c | 2 + reactos/ntoskrnl/mm/pagefile.c | 4 + reactos/ntoskrnl/ntoskrnl.def | 1 + reactos/ntoskrnl/ntoskrnl.rbuild | 5 + reactos/ntoskrnl/ps/debug.c | 4 + reactos/ntoskrnl/ps/idle.c | 4 + reactos/ntoskrnl/ps/psmgr.c | 4 + 50 files changed, 548 insertions(+), 46 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index 8ec2925c90c..8b555f9227c 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -376,7 +376,13 @@ $(ROS_AUTOMAKE): $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES) $(ECHO_RBUILD) $(Q)$(RBUILD_TARGET) $(ROS_RBUILDFLAGS) mingw -world: all bootcd livecd +world: all + $(MAKE) KDBG=$(KDBG) DBG=$(DBG) \ + ROS_AUTOMAKE=$(ROS_AUTOMAKE) \ + ROS_INSTALL=$(ROS_INSTALL) \ + ROS_INTERMEDIATE=$(ROS_INTERMEDIATE) \ + ROS_OUTPUT=$(ROS_OUTPUT) \ + bootcd livecd universe: $(MAKE) KDBG=1 DBG=1 \ diff --git a/reactos/ReactOS-ppc.rbuild b/reactos/ReactOS-ppc.rbuild index 418405a912e..1b0f1b52a22 100644 --- a/reactos/ReactOS-ppc.rbuild +++ b/reactos/ReactOS-ppc.rbuild @@ -18,14 +18,14 @@ - + extern - -v + @@ -41,18 +41,15 @@ - -Wpointer-arith . include - include/reactos - include/libs - include/drivers - include/subsys - include/ndk - include include/crt include/ddk + include/GL + include/ndk + include/reactos + include/reactos/libs diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index d367382829d..ac9b039b8e2 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -6,6 +6,7 @@ _start: .long 0 .long 0 + .globl _begin _begin: sync isync @@ -19,16 +20,18 @@ _begin: mtmsr %r0 isync - bl setup_bats - - li %r8,0x3030 - mtmsr %r8 - /* Store ofw call addr */ mr %r21,%r5 lis %r10,0xe00000@ha stw %r5,ofw_call_addr - _start@l(%r10) + bl setup_bats + + li %r8,0x3030 + mtmsr %r8 + + bl ofw_print_regs + lis %r4,_binary_freeldr_tmp_end@ha addi %r4,%r4,_binary_freeldr_tmp_end@l lis %r3,_binary_freeldr_tmp_start@ha @@ -61,7 +64,7 @@ _begin: lis %r3,call_ofw@ha addi %r3,%r3,call_ofw - _start - b call_freeldr + blr /* * lifted from ppc/boot/openfirmware/misc.S diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 23997df7c78..4e17e0a2718 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -12,6 +12,11 @@ #define NDEBUG #include +int xstrnicmp( const char *a, const char *b, int n ) { + while( n-- && *a && (*a++ == *b++) ); + return *a - *b; +} + /* Base Addres of Kernel in Physical Memory */ #define KERNEL_BASE_PHYS 0x200000 @@ -131,7 +136,7 @@ FrLdrGetKernelBase(VOID) while ((p = strchr(p, '/')) != NULL) { /* Find "/3GB" */ - if (!strnicmp(p + 1, "3GB", 3)) { + if (!xstrnicmp(p + 1, "3GB", 3)) { /* Make sure there's nothing following it */ if (p[4] == ' ' || p[4] == 0) { diff --git a/reactos/boot/freeldr/freeldr/drivemap.c b/reactos/boot/freeldr/freeldr/drivemap.c index a10a5cc1e24..af886a87d0f 100644 --- a/reactos/boot/freeldr/freeldr/drivemap.c +++ b/reactos/boot/freeldr/freeldr/drivemap.c @@ -171,6 +171,7 @@ ULONG DriveMapGetBiosDriveNumber(PCSTR DeviceName) VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap) { +#ifdef _M_IX86 ULONG* RealModeIVT = (ULONG*)0x00000000; USHORT* BiosLowMemorySize = (USHORT*)0x00000413; @@ -202,6 +203,7 @@ VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap) RealModeIVT[0x13] = DriveMapHandlerSegOff; CacheInvalidateCacheData(); +#endif DriveMapInstalled = TRUE; } diff --git a/reactos/boot/freeldr/freeldr/include/freeldr.h b/reactos/boot/freeldr/freeldr/include/freeldr.h index c2cf1e122f0..6f178403d25 100644 --- a/reactos/boot/freeldr/freeldr/include/freeldr.h +++ b/reactos/boot/freeldr/freeldr/include/freeldr.h @@ -61,6 +61,8 @@ #include #include #include +#elif defined(_PPC_) +#include #endif /* misc files */ #include diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index 995a1df1d89..f793201f511 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -836,13 +836,14 @@ KeQueryPerformanceCounter( } #undef KeRaiseIrql -VOID -NTAPI +NTOSAPI +KIRQL +DDKAPI KeRaiseIrql( - KIRQL NewIrql, - PKIRQL OldIrql) + IN KIRQL NewIrql) { UNIMPLEMENTED; + return 0; } diff --git a/reactos/include/ddk/ndis.h b/reactos/include/ddk/ndis.h index 55516be51af..865be83e3d3 100644 --- a/reactos/include/ddk/ndis.h +++ b/reactos/include/ddk/ndis.h @@ -4126,7 +4126,6 @@ typedef struct _NDIS_INTERRUPT { KEVENT DpcsCompletedEvent; } NDIS_INTERRUPT, *PNDIS_INTERRUPT; - typedef enum _NDIS_WORK_ITEM_TYPE { NdisWorkItemRequest, NdisWorkItemSend, diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index ee3e711a152..81108472062 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -5268,10 +5268,190 @@ KfReleaseSpinLock( #define KeGetDcacheFillSize() 1L +#elif defined(_PPC_) + +typedef ULONG PFN_NUMBER, *PPFN_NUMBER; + +#define PASSIVE_LEVEL 0 +#define LOW_LEVEL 0 +#define APC_LEVEL 1 +#define DISPATCH_LEVEL 2 +#define PROFILE_LEVEL 27 +#define CLOCK1_LEVEL 28 +#define CLOCK2_LEVEL 28 +#define IPI_LEVEL 29 +#define SYNCH_LEVEL (IPI_LEVEL-1) +#define POWER_LEVEL 30 +#define HIGH_LEVEL 31 + +extern NTOSAPI PVOID MmHighestUserAddress; +extern NTOSAPI PVOID MmSystemRangeStart; +extern NTOSAPI ULONG_PTR MmUserProbeAddress; + +#define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress +#define MM_SYSTEM_RANGE_START MmSystemRangeStart +#define MM_USER_PROBE_ADDRESS MmUserProbeAddress +#define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 +#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 + +#define KI_USER_SHARED_DATA 0xffdf0000 +#define SharedUserData ((KUSER_SHARED_DATA * CONST) KI_USER_SHARED_DATA) + +#define EFLAG_SIGN 0x8000 +#define EFLAG_ZERO 0x4000 +#define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO) + +#define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) +#define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT) +#define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) + +typedef struct _KPCR_TIB { + PVOID ExceptionList; /* 00 */ + PVOID StackBase; /* 04 */ + PVOID StackLimit; /* 08 */ + PVOID SubSystemTib; /* 0C */ + _ANONYMOUS_UNION union { + PVOID FiberData; /* 10 */ + DWORD Version; /* 10 */ + } DUMMYUNIONNAME; + PVOID ArbitraryUserPointer; /* 14 */ + struct _KPCR_TIB *Self; /* 18 */ +} KPCR_TIB, *PKPCR_TIB; /* 1C */ + +#define PCR_MINOR_VERSION 1 +#define PCR_MAJOR_VERSION 1 + +typedef struct _KPCR { + KPCR_TIB Tib; /* 00 */ + struct _KPCR *Self; /* 1C */ + struct _KPRCB *Prcb; /* 20 */ + KIRQL Irql; /* 24 */ + ULONG IRR; /* 28 */ + ULONG IrrActive; /* 2C */ + ULONG IDR; /* 30 */ + PVOID KdVersionBlock; /* 34 */ + PUSHORT IDT; /* 38 */ + PUSHORT GDT; /* 3C */ + struct _KTSS *TSS; /* 40 */ + USHORT MajorVersion; /* 44 */ + USHORT MinorVersion; /* 46 */ + KAFFINITY SetMember; /* 48 */ + ULONG StallScaleFactor; /* 4C */ + UCHAR SpareUnused; /* 50 */ + UCHAR Number; /* 51 */ +} KPCR, *PKPCR; /* 54 */ + +#if !defined(__INTERLOCKED_DECLARED) +#define __INTERLOCKED_DECLARED + +NTOSAPI +LONG +DDKFASTAPI +InterlockedIncrement( + IN PLONG VOLATILE Addend); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedDecrement( + IN PLONG VOLATILE Addend); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedCompareExchange( + IN OUT PLONG VOLATILE Destination, + IN LONG Exchange, + IN LONG Comparand); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedExchange( + IN OUT PLONG VOLATILE Target, + IN LONG Value); + +NTOSAPI +LONG +DDKFASTAPI +InterlockedExchangeAdd( + IN OUT PLONG VOLATILE Addend, + IN LONG Value); + +/* + * PVOID + * InterlockedExchangePointer( + * IN OUT PVOID VOLATILE *Target, + * IN PVOID Value) + */ +#define InterlockedExchangePointer(Target, Value) \ + ((PVOID) InterlockedExchange((PLONG) Target, (LONG) Value)) + +/* + * PVOID + * InterlockedCompareExchangePointer( + * IN OUT PVOID *Destination, + * IN PVOID Exchange, + * IN PVOID Comparand) + */ +#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \ + ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand)) + +#endif /* !__INTERLOCKED_DECLARED */ + +NTOSAPI +VOID +DDKFASTAPI +KefAcquireSpinLockAtDpcLevel( + IN PKSPIN_LOCK SpinLock); + +NTOSAPI +VOID +DDKFASTAPI +KefReleaseSpinLockFromDpcLevel( + IN PKSPIN_LOCK SpinLock); + +NTHALAPI +KIRQL +DDKFASTAPI +KfAcquireSpinLock( + IN PKSPIN_LOCK SpinLock); + +NTHALAPI +VOID +DDKFASTAPI +KfReleaseSpinLock( + IN PKSPIN_LOCK SpinLock, + IN KIRQL NewIrql); + +#define KeAcquireSpinLockAtDpcLevel(SpinLock) KefAcquireSpinLockAtDpcLevel(SpinLock) +#define KeReleaseSpinLockFromDpcLevel(SpinLock) KefReleaseSpinLockFromDpcLevel(SpinLock) +#define KeAcquireSpinLock(a,b) *(b) = KfAcquireSpinLock(a) +#define KeReleaseSpinLock(a,b) KfReleaseSpinLock(a,b) + +#define RtlCopyMemoryNonTemporal RtlCopyMemory + +#define KeGetDcacheFillSize() 1L + +typedef enum _INTERLOCKED_RESULT { + ResultNegative = -1, + ResultZero = 0, + ResultPositive = 1 +} INTERLOCKED_RESULT; + +typedef struct _KFLOATING_SAVE { + ULONG Fr[32]; +} KFLOATING_SAVE, *PKFLOATING_SAVE; + +static __inline +ULONG +DDKAPI +KeGetCurrentProcessorNumber(VOID) +{ + return 0; // XXX arty fixme +} #endif /* _X86_ */ - - /* ** Utillity functions */ @@ -8653,6 +8833,15 @@ KeMemoryBarrier( #endif } +#elif defined(_PPC_) + +static __inline +VOID +KeMemoryBarrier( + VOID) +{ +} + #endif NTOSAPI @@ -8959,6 +9148,35 @@ KeRaiseIrqlToSynchLevel( #define KeLowerIrql(a) KfLowerIrql(a) #define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a) +#elif defined(_PPC_) + +NTHALAPI +VOID +FASTCALL +KfLowerIrql( + IN KIRQL NewIrql); + +NTHALAPI +KIRQL +FASTCALL +KfRaiseIrql( + IN KIRQL NewIrql); + +NTHALAPI +KIRQL +DDKAPI +KeRaiseIrqlToDpcLevel( + VOID); + +NTHALAPI +KIRQL +DDKAPI +KeRaiseIrqlToSynchLevel( + VOID); + +#define KeLowerIrql(a) KfLowerIrql(a) +#define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a) + #else NTOSAPI diff --git a/reactos/include/ndk/mmtypes.h b/reactos/include/ndk/mmtypes.h index 3ff541be0d5..7d2682ba22e 100644 --- a/reactos/include/ndk/mmtypes.h +++ b/reactos/include/ndk/mmtypes.h @@ -207,6 +207,7 @@ typedef struct _SECTION_IMAGE_INFORMATION // // PTE Structures // +#ifndef _M_PPC typedef struct _MMPTE { union @@ -221,6 +222,12 @@ typedef struct _MMPTE MMPTE_LIST List; }; } MMPTE, *PMMPTE; +#else +typedef struct _MMPTE +{ + ULONG Long; +} MMPTE, *PMMPTE; +#endif // // Section Information structure diff --git a/reactos/include/ndk/powerpc/ketypes.h b/reactos/include/ndk/powerpc/ketypes.h index 739fb7ae854..548c261962e 100644 --- a/reactos/include/ndk/powerpc/ketypes.h +++ b/reactos/include/ndk/powerpc/ketypes.h @@ -31,6 +31,45 @@ Author: #define IPI_FREEZE 3 #define IPI_PACKET_READY 4 #define IPI_SYNCH_REQUEST 10 +#define MAXIMUM_VECTOR 0x100 + +#ifndef ROUND_UP +#define ROUND_UP(x,y) (((x) + ((y)-1)) & ~((y)-1)) +#endif + +typedef double DOUBLE; + +typedef struct _FX_SAVE_AREA { + ULONG Fr[32]; +} FX_SAVE_AREA; + +typedef struct _LDT_ENTRY { + USHORT LimitLow; + USHORT BaseLow; + union + { + struct + { + UCHAR BaseMid; + UCHAR Flags1; + UCHAR Flags2; + UCHAR BaseHi; + } Bytes; + struct + { + ULONG BaseMid : 8; + ULONG Type : 5; + ULONG Dpl : 2; + ULONG Pres : 1; + ULONG LimitHi : 4; + ULONG Sys : 1; + ULONG Reserved_0 : 1; + ULONG Default_Big : 1; + ULONG Granularity : 1; + ULONG BaseHi : 8; + } Bits; + } HighWord; +} LDT_ENTRY; // // Trap Frame Definition @@ -42,7 +81,7 @@ typedef struct _KTRAP_FRAME UCHAR PreviousMode; UCHAR SavedApcStateIndex; UCHAR SavedKernelApcDisable; - UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), ULONGLONG]; + UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), sizeof(ULONGLONG))]; ULONG FILL2; ULONG Gpr0; ULONG Gpr1; @@ -403,7 +442,8 @@ typedef struct _KIPCR // // TSS Definition // -typedef struct _KTSS, KTSS, *PKTSS; +typedef struct _KTSS { +} KTSS, *PKTSS; // // PowerPC Exception Frame diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 954e1c5ad2a..942d0ae7ddf 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -1117,7 +1117,11 @@ typedef struct _EPROCESS #endif union { +#ifdef _M_IX86 HARDWARE_PTE_X86 PagedirectoryPte; +#else + HARDWARE_PTE_PPC PagedirectoryPte; +#endif ULONGLONG Filler; }; ULONG Session; diff --git a/reactos/include/reactos/debug.h b/reactos/include/reactos/debug.h index a668913b79f..7e99d2ce07e 100644 --- a/reactos/include/reactos/debug.h +++ b/reactos/include/reactos/debug.h @@ -125,7 +125,7 @@ RtlAssert( #elif defined(_M_MIPS) #define ASM_BREAKPOINT "\nbreak\n" #else -#error Unsupported architecture. +#define ASM_BREAKPOINT "\ntwi 1\n" #endif #ifndef KEBUGCHECK diff --git a/reactos/include/reactos/elf/machine.h b/reactos/include/reactos/elf/machine.h index 27d7e494ebd..a570b1c4adf 100644 --- a/reactos/include/reactos/elf/machine.h +++ b/reactos/include/reactos/elf/machine.h @@ -5,6 +5,10 @@ #define _REACTOS_ELF_MACHINE_IS_TARGET #include #undef _REACTOS_ELF_MACHINE_IS_TARGET +#elif defined(_M_PPC) +#define _REACTOS_ELF_MACHINE_IS_TARGET +#include +#undef _REACTOS_ELF_MACHINE_IS_TARGET #else #error Unsupported target architecture #endif diff --git a/reactos/include/reactos/libs/pseh/setjmp.h b/reactos/include/reactos/libs/pseh/setjmp.h index c7096b4f73c..575c7cfd143 100644 --- a/reactos/include/reactos/libs/pseh/setjmp.h +++ b/reactos/include/reactos/libs/pseh/setjmp.h @@ -34,6 +34,13 @@ typedef struct __SEHJmpBuf unsigned long JB_Edi; } _SEHJmpBuf_t[1]; +#elif defined(_M_PPC) +typedef struct __SEHJmpBuf +{ + unsigned long R[32]; + unsigned long LR, CTR; +} +_SEHJmpBuf_t[1]; #endif #ifdef __cplusplus diff --git a/reactos/include/reactos/probe.h b/reactos/include/reactos/probe.h index 04e83369ab6..e13dfa8d40d 100644 --- a/reactos/include/reactos/probe.h +++ b/reactos/include/reactos/probe.h @@ -5,6 +5,10 @@ #error Header intended for use by NTOSKRNL/WIN32K only! #endif +#if defined(_M_PPC) +extern ULONG_PTR MmUserProbeAddress; +#endif + static const UNICODE_STRING __emptyUnicodeString = {0}; static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}}; static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}}; diff --git a/reactos/include/winnt.h b/reactos/include/winnt.h index bfaab02e6ef..f793c8d7e4f 100644 --- a/reactos/include/winnt.h +++ b/reactos/include/winnt.h @@ -1838,6 +1838,9 @@ typedef struct _CONTEXT { DWORD Dr6; DWORD Dr7; } CONTEXT; +typedef struct _FLOATING_SAVE_AREA { + DWORD Fr[32]; +} FLOATING_SAVE_AREA; #elif defined(_ALPHA_) #define CONTEXT_ALPHA 0x20000 #define CONTEXT_CONTROL (CONTEXT_ALPHA|1L) @@ -3699,16 +3702,21 @@ typedef struct _OBJECT_TYPE_LIST { static __inline__ PVOID GetCurrentFiber(void) { +#ifdef _X86_ void* ret; __asm__ __volatile__ ( "movl %%fs:0x10,%0" : "=r" (ret) /* allow use of reg eax,ebx,ecx,edx,esi,edi */ ); return ret; +#elif defined(_PPC_) + return NULL; +#endif } static __inline__ struct _TEB * NtCurrentTeb(void) { +#ifdef _X86_ struct _TEB *ret; __asm__ __volatile__ ( @@ -3718,6 +3726,9 @@ static __inline__ struct _TEB * NtCurrentTeb(void) ); return ret; +#elif defined(_PPC_) + return NULL; +#endif } #elif defined(__WATCOMC__) @@ -3778,13 +3789,14 @@ InterlockedBitTestAndSet(IN LONG *Base, IN LONG Bit) { LONG OldBit; - +#ifdef _M_IX86 __asm__ __volatile__("lock " "btsl %2,%1\n\t" "sbbl %0,%0\n\t" :"=r" (OldBit),"=m" (*Base) :"Ir" (Bit) : "memory"); +#endif return OldBit; } @@ -3793,19 +3805,24 @@ InterlockedBitTestAndReset(IN LONG *Base, IN LONG Bit) { LONG OldBit; - +#ifdef _M_IX86 __asm__ __volatile__("lock " "btrl %2,%1\n\t" "sbbl %0,%0\n\t" :"=r" (OldBit),"=m" (*Base) :"Ir" (Bit) : "memory"); +#endif return OldBit; } #endif +#ifdef _M_IX86 #define YieldProcessor() __asm__ __volatile__("pause"); +#elif defined(_M_PPC) +#define YieldProcessor() __asm__("ori 0,0,0"); +#endif #if defined(_AMD64_) #if defined(_M_AMD64) diff --git a/reactos/lib/kjs/ksrc/longjmp.S b/reactos/lib/kjs/ksrc/longjmp.S index f998344ae06..7cb15cfee9d 100644 --- a/reactos/lib/kjs/ksrc/longjmp.S +++ b/reactos/lib/kjs/ksrc/longjmp.S @@ -38,7 +38,8 @@ * return PC */ -.globl _longjmp +#ifdef _M_IX86 + .globl _longjmp _longjmp: pushl %ebp movl %esp,%ebp @@ -69,4 +70,8 @@ _longjmp: */ jmpl *20(%ecx) - +#else + .globl _longjmp +_longjmp: + blr +#endif diff --git a/reactos/lib/kjs/ksrc/setjmp.S b/reactos/lib/kjs/ksrc/setjmp.S index 885908e5ec4..2d310dc348b 100644 --- a/reactos/lib/kjs/ksrc/setjmp.S +++ b/reactos/lib/kjs/ksrc/setjmp.S @@ -37,7 +37,8 @@ * ptr to jmp_buf * return PC */ -.globl _setjmp +#ifdef _M_IX86 + .globl _setjmp _setjmp: pushl %ebp movl %esp,%ebp @@ -56,4 +57,8 @@ _setjmp: xorl %eax,%eax /* return 0 the first time */ leave ret - +#else + .globl _setjmp +_setjmp: + blr +#endif diff --git a/reactos/lib/pseh/pseh.rbuild b/reactos/lib/pseh/pseh.rbuild index 15e96420ebe..29ae4563ae5 100644 --- a/reactos/lib/pseh/pseh.rbuild +++ b/reactos/lib/pseh/pseh.rbuild @@ -1,8 +1,16 @@ - - framebased.asm - setjmp.asm - + + + framebased.asm + setjmp.asm + + + + + framebased.s + setjmp.s + + framebased.c diff --git a/reactos/lib/rossym/find.c b/reactos/lib/rossym/find.c index 6f18c356248..8487f9d5174 100644 --- a/reactos/lib/rossym/find.c +++ b/reactos/lib/rossym/find.c @@ -104,7 +104,11 @@ RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo, if (RosSymInfo->Symbols == NULL || RosSymInfo->SymbolsCount == 0 || RosSymInfo->Strings == NULL || RosSymInfo->StringsLength == 0) { +#ifdef _X86_ __asm__("int $3\n"); +#elif defined(_PPC_) +__asm__("twi 0,0,0\n"); +#endif DPRINT1("Uninitialized RosSymInfo\n"); return FALSE; } diff --git a/reactos/lib/rtl/heap.c b/reactos/lib/rtl/heap.c index d420a85a7f7..d9d0cf1601f 100644 --- a/reactos/lib/rtl/heap.c +++ b/reactos/lib/rtl/heap.c @@ -962,6 +962,7 @@ int HEAP_IsInsideHeap( void DumpStackFrames ( PULONG Frame, ULONG FrameCount ) { +#ifdef _M_IX86 ULONG i=0; DbgPrint("Frames: "); @@ -983,6 +984,7 @@ void DumpStackFrames ( PULONG Frame, ULONG FrameCount ) DbgPrint(" "); } DbgPrint("\n"); +#endif } /*********************************************************************** diff --git a/reactos/lib/rtl/nls.c b/reactos/lib/rtl/nls.c index 9923dbcde5f..6789b249c7c 100644 --- a/reactos/lib/rtl/nls.c +++ b/reactos/lib/rtl/nls.c @@ -365,7 +365,7 @@ RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) DPRINT("RtlResetRtlTranslations() called\n"); /* Set ANSI data */ - NlsAnsiToUnicodeTable = NlsTable->AnsiTableInfo.MultiByteTable; + NlsAnsiToUnicodeTable = (void *)NlsTable->AnsiTableInfo.MultiByteTable; NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable; NlsDbcsUnicodeToAnsiTable = (PWCHAR)NlsTable->AnsiTableInfo.WideCharTable; NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0); @@ -374,7 +374,7 @@ RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage); /* Set OEM data */ - NlsOemToUnicodeTable = NlsTable->OemTableInfo.MultiByteTable; + NlsOemToUnicodeTable = (void *)NlsTable->OemTableInfo.MultiByteTable; NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable; NlsDbcsUnicodeToOemTable = (PWCHAR)NlsTable->OemTableInfo.WideCharTable; NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0); diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index f9c1e11f275..d81ee305ead 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -73,7 +73,9 @@ InitSystemSharedUserPage (PCSZ ParameterLine) * The shared user page has been zeroed-out right after creation. * There is NO need to do this again. */ +#ifdef _M_IX86 Ki386SetProcessorFeatures(); +#endif /* Set the Version Data */ SharedUserData->NtProductType = NtProductWinNt; @@ -238,6 +240,7 @@ VOID STDCALL ExecuteRuntimeAsserts(VOID) { +#ifdef _M_IX86 /* * Fail at runtime if someone has changed various structures without * updating the offsets used for the assembler code. @@ -265,6 +268,7 @@ ExecuteRuntimeAsserts(VOID) ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0); ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE); ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA); +#endif } __inline diff --git a/reactos/ntoskrnl/ex/power.c b/reactos/ntoskrnl/ex/power.c index 3dd62dbc351..acdc62ce4da 100644 --- a/reactos/ntoskrnl/ex/power.c +++ b/reactos/ntoskrnl/ex/power.c @@ -36,7 +36,9 @@ KiHaltProcessorDpcRoutine(IN PKDPC Dpc, while (TRUE) { KfRaiseIrql(SYNCH_LEVEL); +#ifdef _M_IX86 Ke386HaltProcessor(); +#endif } } diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index b9dc72c3e8e..9dd9a196eb0 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -1646,8 +1646,9 @@ NtFlushInstructionCache ( ) { PAGED_CODE(); - +#ifdef _M_IX86 __asm__("wbinvd\n"); +#endif return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/include/internal/arch/ke.h b/reactos/ntoskrnl/include/internal/arch/ke.h index 8cdcf9cde0f..d71629ca3ad 100644 --- a/reactos/ntoskrnl/include/internal/arch/ke.h +++ b/reactos/ntoskrnl/include/internal/arch/ke.h @@ -21,6 +21,8 @@ #ifdef _M_IX86 #include "../i386/ke.h" +#elif defined(_M_PPC) +#include "../powerpc/ke.h" #else #error "Unknown processor" #endif diff --git a/reactos/ntoskrnl/include/internal/arch/mm.h b/reactos/ntoskrnl/include/internal/arch/mm.h index aded673559b..ba71467d381 100644 --- a/reactos/ntoskrnl/include/internal/arch/mm.h +++ b/reactos/ntoskrnl/include/internal/arch/mm.h @@ -21,6 +21,8 @@ #ifdef _M_IX86 #include +#elif defined(_M_PPC) +#include #else #error "Unknown processor" #endif diff --git a/reactos/ntoskrnl/include/internal/arch/ps.h b/reactos/ntoskrnl/include/internal/arch/ps.h index c10edcb32aa..014124ff353 100644 --- a/reactos/ntoskrnl/include/internal/arch/ps.h +++ b/reactos/ntoskrnl/include/internal/arch/ps.h @@ -4,6 +4,9 @@ #ifdef _M_IX86 #define KiArchContextSwitch KiSwapContext #define KiArchInitThreadWithContext Ke386InitThreadWithContext +#elif defined(_M_PPC) +#define KiArchContextSwitch KiSwapContext +#define KiArchInitThreadWithContext KePPCInitThreadWithContext #else #error "Unknown processor" #endif diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 8eb5cfb18cb..ff149a03a10 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -16,6 +16,7 @@ extern POBJECT_TYPE ExEventPairObjectType; EX_HANDLE_ENTRY_AUDITONCLOSE))) /* Note: we only use a spinlock on SMP. On UP, we cli/sti intead */ +#ifdef _M_IX86 #ifndef CONFIG_SMP #define ExAcquireResourceLock(l, i) { \ (void)i; \ @@ -25,6 +26,11 @@ extern POBJECT_TYPE ExEventPairObjectType; #else #define ExAcquireResourceLock(l, i) KeAcquireSpinLock(l, i); #define ExReleaseResourceLock(l, i) KeReleaseSpinLock(l, i); +#endif /* CONFIG_SMP */ +#elif defined(_M_PPC) /* _M_IX86 */ +/* XXX arty fixme */ +#define ExAcquireResourceLock(l,i) KeAcquireSpinLock(l,i); +#define ExReleaseResourceLock(l,i) KeReleaseSpinLock(l,i); #endif /* INITIALIZATION FUNCTIONS *************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 65b6e2b7c9a..2fa20e46260 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -12,9 +12,15 @@ #ifdef _NTOSKRNL_ #include "ke.h" +#ifdef _M_IX86 #include "i386/mm.h" #include "i386/fpu.h" #include "i386/v86m.h" +#elif defined(_M_PPC) +#include "powerpc/mm.h" +#else +#error "Unknown CPU" +#endif #include "ob.h" #include "mm.h" #include "ps.h" @@ -247,7 +253,8 @@ DefaultQueryInfoBufferCheck(UINT Class, /* on Itanium if the 24 most significant bits are set, we're not dealing with offsets anymore. */ #define IsPointerOffset(Ptr) (((ULONG_PTR)(Ptr) & 0xFFFFFF0000000000ULL) == 0) - +#elif defined(_PPC_) +#define IsPointerOffset(Ptr) ((LONG_PTR)(Ptr) >= 0) #else #error IsPointerOffset() needs to be defined for this architecture #endif diff --git a/reactos/ntoskrnl/include/internal/powerpc/ke.h b/reactos/ntoskrnl/include/internal/powerpc/ke.h index a2973609ff5..cfa14164b9e 100644 --- a/reactos/ntoskrnl/include/internal/powerpc/ke.h +++ b/reactos/ntoskrnl/include/internal/powerpc/ke.h @@ -126,11 +126,53 @@ __asm__ __volatile__("mfmsr 0\n\t" \ #define KePPCHaltProcessor() ; -#endif /* __ASM__ */ - #define KeArchEraseFlags() #define KeArchDisableInterrupts() KePPCDisableInterrupts() +static __inline struct _KPRCB * KeGetCurrentPrcb( + VOID) +{ + ULONG Value = 0; + return (struct _KPRCB *) Value; +} + +static __inline KIRQL KeGetCurrentIrql( + VOID) +{ + return PASSIVE_LEVEL; +} + +VOID +STDCALL +KePPCInitThreadWithContext( + PKTHREAD Thread, + PKSYSTEM_ROUTINE SystemRoutine, + PKSTART_ROUTINE StartRoutine, + PVOID StartContext, + PCONTEXT Context); + +VOID +STDCALL +KeApplicationProcessorInitDispatcher( + VOID); + +VOID +STDCALL +KeCreateApplicationProcessorIdleThread( + ULONG Id); + +#ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */ +VOID +STDCALL +KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, + PKSTART_ROUTINE StartRoutine, + PVOID StartContext, + BOOLEAN UserThread, + KTRAP_FRAME TrapFrame); +#endif + +#endif /* __ASM__ */ + #endif /* __NTOSKRNL_INCLUDE_INTERNAL_POWERPC_KE_H */ /* EOF */ diff --git a/reactos/ntoskrnl/io/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr.c index 7863df2dc78..0f836ffd812 100644 --- a/reactos/ntoskrnl/io/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr.c @@ -775,6 +775,7 @@ IopInitiatePnpIrp(PDEVICE_OBJECT DeviceObject, return Status; } +ULONG TreeTraverse = 0; NTSTATUS IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) @@ -782,6 +783,10 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) PDEVICE_NODE ParentDeviceNode; PDEVICE_NODE ChildDeviceNode; NTSTATUS Status; + ULONG Indent = TreeTraverse; + + while( Indent-- ) DbgPrint(" "); + DPRINT1("Checking device node 0x%x\n", Context->DeviceNode); /* Copy context data so we don't overwrite it in subsequent calls to this function */ ParentDeviceNode = Context->DeviceNode; @@ -793,6 +798,8 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) return Status; } + TreeTraverse++; + /* Traversal of all children nodes */ for (ChildDeviceNode = ParentDeviceNode->Child; ChildDeviceNode != NULL; @@ -804,10 +811,19 @@ IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) Status = IopTraverseDeviceTreeNode(Context); if (!NT_SUCCESS(Status)) { - return Status; + Indent = TreeTraverse; + while( Indent-- ) DbgPrint(" "); + DPRINT1("Device node 0x%x done (bad)\n", Context->DeviceNode); + TreeTraverse--; + return Status; } } + Indent = TreeTraverse; + while( Indent-- ) DbgPrint(" "); + DPRINT1("Device node 0x%x done (good)\n", Context->DeviceNode); + + TreeTraverse--; return Status; } diff --git a/reactos/ntoskrnl/kd/kdmain.c b/reactos/ntoskrnl/kd/kdmain.c index 88b5e0424f1..126914d1fc6 100644 --- a/reactos/ntoskrnl/kd/kdmain.c +++ b/reactos/ntoskrnl/kd/kdmain.c @@ -198,7 +198,11 @@ KeEnterKernelDebugger(VOID) KdEnteredDebugger = TRUE; /* Halt the CPU */ +#ifdef _M_IX86 for (;;) Ke386HaltProcessor(); +#elif defined(_M_PPC) + for (;;); +#endif } /* diff --git a/reactos/ntoskrnl/kd/wrappers/gdbstub.c b/reactos/ntoskrnl/kd/wrappers/gdbstub.c index 64047de09b3..8c6c174dd35 100644 --- a/reactos/ntoskrnl/kd/wrappers/gdbstub.c +++ b/reactos/ntoskrnl/kd/wrappers/gdbstub.c @@ -129,6 +129,7 @@ typedef struct _CPU_REGISTER static CPU_REGISTER GspRegisters[NUMREGS] = { +#ifdef _M_IX86 { 4, FIELD_OFFSET(KTRAP_FRAME, Eax), FIELD_OFFSET(CONTEXT, Eax), TRUE }, { 4, FIELD_OFFSET(KTRAP_FRAME, Ecx), FIELD_OFFSET(CONTEXT, Ecx), TRUE }, { 4, FIELD_OFFSET(KTRAP_FRAME, Edx), FIELD_OFFSET(CONTEXT, Edx), FALSE }, @@ -145,6 +146,7 @@ static CPU_REGISTER GspRegisters[NUMREGS] = { 4, FIELD_OFFSET(KTRAP_FRAME, SegEs), FIELD_OFFSET(CONTEXT, SegEs), TRUE }, { 4, FIELD_OFFSET(KTRAP_FRAME, SegFs), FIELD_OFFSET(CONTEXT, SegFs), TRUE }, { 4, FIELD_OFFSET(KTRAP_FRAME, SegGs), FIELD_OFFSET(CONTEXT, SegGs), TRUE } +#endif }; static PCHAR GspThreadStates[DeferredReady+1] = @@ -563,8 +565,12 @@ GspLong2Hex(PCHAR *Address, static LONG GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame) { +#ifdef _M_IX86 return KeGetPreviousMode() == KernelMode ? (LONG) &TrapFrame->HardwareEsp : (LONG)TrapFrame->HardwareEsp; +#elif defined(_M_PPC) + return 0; +#endif } @@ -613,12 +619,14 @@ GspGetRegisters(PCHAR Address, case ESP: Value = (ULONG_PTR) (KernelStack + 8); break; +#ifdef _M_IX86 case CS: Value = KGDT_R0_CODE; break; case DS: Value = KGDT_R0_DATA; break; +#endif default: Value = 0; break; @@ -1332,12 +1340,16 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, DPRINT("Thread %p acquired mutex\n", PsGetCurrentThread()); /* Disable hardware debugging while we are inside the stub */ +#ifdef _M_IX86 #if defined(__GNUC__) __asm__("movl %0,%%db7" : /* no output */ : "r" (0)); #elif defined(_MSC_VER) __asm mov eax, 0 __asm mov dr7, eax #else #error Unknown compiler for inline assembler +#endif +#elif defined(_M_PPC) + /* XXX arty fixme */ #endif GspUnloadBreakpoints(TrapFrame); @@ -1373,6 +1385,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, ptr = GspMem2Hex((PCHAR) &Esp, ptr, 4, 0); *ptr++ = ';'; +#ifdef _M_IX86 *ptr++ = HexChars[EBP]; *ptr++ = ':'; ptr = GspMem2Hex((PCHAR) &TrapFrame->Ebp, ptr, 4, 0); /* FP */ @@ -1382,6 +1395,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, *ptr++ = ':'; ptr = GspMem2Hex((PCHAR) &TrapFrame->Eip, ptr, 4, 0); /* PC */ *ptr++ = ';'; +#endif *ptr = '\0'; @@ -1558,12 +1572,16 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, Context->EFlags |= 0x100; } +#ifdef _M_IX86 #if defined(__GNUC__) asm volatile ("movl %%db6, %0\n" : "=r" (dr6_) : ); #elif defined(_MSC_VER) __asm mov eax, dr6 __asm mov dr6_, eax; #else #error Unknown compiler for inline assembler +#endif +#elif defined(_M_PPC) + /* XXX arty fixme */ #endif if (!(dr6_ & 0x4000)) { @@ -1581,12 +1599,16 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, } } GspLoadBreakpoints(TrapFrame); +#ifdef _M_IX86 #if defined(__GNUC__) asm volatile ("movl %0, %%db6\n" : : "r" (0)); #elif defined(_MSC_VER) __asm mov eax, 0 __asm mov dr6, eax; #else #error Unknown compiler for inline assembler +#endif +#elif defined(_M_PPC) + /* XXX arty fixme */ #endif if (NULL != GspDbgThread) diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index a367aeeb04f..4f02df5d3f1 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -908,8 +908,10 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame, KeGetCurrentThread()->TrapFrame); +#ifdef _M_IX86 /* Don't deliver APCs in V86 mode */ if (TrapFrame->EFlags & X86_EFLAGS_VM) return; +#endif /* Save the full context */ Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; @@ -928,9 +930,11 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, &Context, sizeof(CONTEXT)); +#ifdef _M_IX86 /* Run at APC dispatcher */ TrapFrame->Eip = (ULONG)KeUserApcDispatcher; TrapFrame->HardwareEsp = Stack; +#endif /* Setup the stack */ *(PULONG_PTR)(Stack + 0 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalRoutine; diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index d471ca40773..b6c09d56a91 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -35,7 +35,9 @@ static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL}; static LIST_ENTRY BugcheckReasonCallbackListHead = {NULL,NULL}; static ULONG InBugCheck; static PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages; +#ifdef _M_IX86 static ULONG KeBugCheckCount = 1; +#endif /* FUNCTIONS *****************************************************************/ @@ -298,6 +300,7 @@ KeBugCheckWithTf(ULONG BugCheckCode, ULONG BugCheckParameter4, PKTRAP_FRAME Tf) { +#ifdef _M_IX86 KIRQL OldIrql; BOOLEAN GotExtendedCrashInfo = FALSE; PVOID Address = 0; @@ -469,6 +472,9 @@ KeBugCheckWithTf(ULONG BugCheckCode, /* Halt this CPU now */ for (;;) Ke386HaltProcessor(); +#elif defined(_M_PPC) + for (;;); +#endif } /* diff --git a/reactos/ntoskrnl/ke/clock.c b/reactos/ntoskrnl/ke/clock.c index 29a27cd84a7..7a5171b23cc 100644 --- a/reactos/ntoskrnl/ke/clock.c +++ b/reactos/ntoskrnl/ke/clock.c @@ -260,6 +260,7 @@ KeUpdateRunTime( CurrentThread = Prcb->CurrentThread; CurrentProcess = CurrentThread->ApcState.Process; +#ifdef _M_IX86 /* * Cs bit 0 is always set for user mode if we are in protected mode. * V86 mode is counted as user time. @@ -288,6 +289,7 @@ KeUpdateRunTime( Prcb->KernelTime++; } } +#endif #if 0 DpcLastCount = Prcb->DpcLastCount; @@ -341,6 +343,7 @@ KeUpdateSystemTime( * FUNCTION: Handles a timer interrupt */ { +#ifdef _M_IX86 LARGE_INTEGER Time; ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL); @@ -378,6 +381,7 @@ KeUpdateSystemTime( * Queue a DPC that will expire timers */ KeInsertQueueDpc(&KiExpireTimerDpc, (PVOID)TrapFrame->Eip, 0); +#endif } /* diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 5ca1616d96c..40b8f84ef9d 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -441,7 +441,7 @@ KiQuantumEnd(VOID) /* Set DPC Event if requested */ if (Prcb->DpcSetEventRequest) { - KeSetEvent(&Prcb->DpcEvent, 0, 0); + KeSetEvent((void *)&Prcb->DpcEvent, 0, 0); } /* Check if Quantum expired */ diff --git a/reactos/ntoskrnl/ke/ipi.c b/reactos/ntoskrnl/ke/ipi.c index a43593a0faf..e95d5becf79 100644 --- a/reactos/ntoskrnl/ke/ipi.c +++ b/reactos/ntoskrnl/ke/ipi.c @@ -33,7 +33,9 @@ KiIpiSendRequest(KAFFINITY TargetSet, ULONG IpiRequest) if (TargetSet & Current) { Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); +#ifdef _M_IX86 Ke386TestAndSetBit(IpiRequest, &Pcr->Prcb->IpiFrozen); +#endif HalRequestIpi(i); } } @@ -48,8 +50,10 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN PVOID ExceptionFrame) { #ifdef DBG +#ifdef _M_IX86 LARGE_INTEGER StartTime, CurrentTime, Frequency; ULONG Count = 5; +#endif #endif PKPRCB Prcb; @@ -59,6 +63,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, Prcb = KeGetCurrentPrcb(); +#ifdef _M_IX86 if (Ke386TestAndClearBit(IPI_APC, &Prcb->IpiFrozen)) { HalRequestSoftwareInterrupt(APC_LEVEL); @@ -111,6 +116,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, } (void)InterlockedExchangePointer(&Prcb->SignalDone, NULL); } +#endif DPRINT("KiIpiServiceRoutine done\n"); return TRUE; } @@ -140,11 +146,13 @@ KiIpiSendPacket(KAFFINITY TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID { Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0)); +#ifdef _M_IX86 Ke386TestAndSetBit(IPI_SYNCH_REQUEST, &Prcb->IpiFrozen); if (Processor != CurrentPrcb->SetMember) { HalRequestIpi(i); } +#endif } } if (TargetSet & CurrentPrcb->SetMember) diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 145e6b65dff..f49054c156b 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -885,7 +885,9 @@ KeInitializeThread(PKPROCESS Process, Thread->UserAffinity = Process->Affinity; Thread->DisableBoost = Process->DisableBoost; Thread->AutoAlignment = Process->AutoAlignment; +#ifdef _M_IX86 Thread->Iopl = Process->Iopl; +#endif /* Set the Thread to initalized */ Thread->State = Initialized; diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 01cfd818b5e..d76371f5f76 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -18,7 +18,6 @@ #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF)) - ULONG NtMajorVersion = 5; ULONG NtMinorVersion = 0; ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(4, 0); diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 8631d2fc47d..faa1f067474 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -133,7 +133,9 @@ KeInitializeProcess(PKPROCESS Process, Process->QuantumReset = 6; Process->DirectoryTableBase = DirectoryTableBase; Process->AutoAlignment = TRUE; +#ifdef _M_IX86 Process->IopmOffset = 0xFFFF; +#endif Process->State = ProcessInMemory; /* Initialize the Thread List */ @@ -176,8 +178,10 @@ NTAPI KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess) { +#ifdef _M_IX86 DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); +#endif } /* diff --git a/reactos/ntoskrnl/ke/profile.c b/reactos/ntoskrnl/ke/profile.c index 1ebea2378d7..787d078fb0f 100644 --- a/reactos/ntoskrnl/ke/profile.c +++ b/reactos/ntoskrnl/ke/profile.c @@ -226,6 +226,7 @@ KiParseProfileList(IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE Source, IN PLIST_ENTRY ListHead) { +#ifdef _M_IX86 PULONG BucketValue; PKPROFILE Profile; @@ -248,6 +249,7 @@ KiParseProfileList(IN PKTRAP_FRAME TrapFrame, /* Increment the value */ ++BucketValue; } +#endif } /* diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index 26f72f86202..084fa794b8c 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -548,6 +548,7 @@ MmDumpToPagingFile(ULONG BugCode, Headers->Type = MmCoreDumpType; if (TrapFrame != NULL) { +#ifdef _M_IX86 if (!(TrapFrame->EFlags & (1 << 17))) { memcpy(&Headers->TrapFrame, TrapFrame, @@ -555,8 +556,11 @@ MmDumpToPagingFile(ULONG BugCode, } else { +#endif memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME)); +#ifdef _M_IX86 } +#endif } Headers->BugCheckCode = BugCode; Headers->BugCheckParameters[0] = BugCodeParameter1; diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 6d1ebd1bad4..7bd853f31fd 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1510,3 +1510,4 @@ wcsspn wcsstr wcstombs wctomb +KeDumpStackFrames@4 \ No newline at end of file diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 3992b2f3e36..a19bac88af9 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -44,6 +44,11 @@ v86m_sup.S vdm.c + + + + main_asm.S + apc.c bug.c diff --git a/reactos/ntoskrnl/ps/debug.c b/reactos/ntoskrnl/ps/debug.c index c8fbb779f24..05773f80c2c 100644 --- a/reactos/ntoskrnl/ps/debug.c +++ b/reactos/ntoskrnl/ps/debug.c @@ -56,12 +56,14 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc, Event = &GetSetContext->Event; Mode = GetSetContext->Mode; +#ifdef _M_IX86 if (TrapFrame->SegCs == KGDT_R0_CODE && Mode != KernelMode) { GetSetContext->Status = STATUS_ACCESS_DENIED; } else { +#endif /* Check if it's a set or get */ if (*SystemArgument1) { /* Get the Context */ @@ -71,7 +73,9 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc, KeContextToTrapFrame(Context, NULL, TrapFrame, Context->ContextFlags, Mode); } GetSetContext->Status = STATUS_SUCCESS; +#ifdef _M_IX86 } +#endif /* Notify the Native API that we are done */ KeSetEvent(Event, IO_NO_INCREMENT, FALSE); diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c index 2b1d39c51b7..fe43e7b3346 100644 --- a/reactos/ntoskrnl/ps/idle.c +++ b/reactos/ntoskrnl/ps/idle.c @@ -45,7 +45,11 @@ PsIdleThreadMain(PVOID Context) NtYieldExecution(); +#ifdef _M_IX86 Ke386HaltProcessor(); +#elif defined(_M_PPC) + for(;;); +#endif } } diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index d1b32f6d16c..49f52c9a310 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -199,7 +199,9 @@ PsInitProcessManagment(VOID) RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS)); PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF; +#ifdef _M_IX86 PsIdleProcess->Pcb.IopmOffset = 0xffff; +#endif PsIdleProcess->Pcb.BasePriority = PROCESS_PRIORITY_IDLE; PsIdleProcess->Pcb.QuantumReset = 6; InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead); @@ -243,7 +245,9 @@ PsInitProcessManagment(VOID) #else PsInitialSystemProcess->Pcb.Affinity = KeActiveProcessors; #endif +#ifdef _M_IX86 PsInitialSystemProcess->Pcb.IopmOffset = 0xffff; +#endif PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIORITY_NORMAL; PsInitialSystemProcess->Pcb.QuantumReset = 6; InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead); From 8d033e5f1b89bea2abf4c4fbc7fd9933d6f3c2e9 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 21:52:03 +0000 Subject: [PATCH 03/81] Add ARCH=powerpc, for initial build. svn path=/branches/powerpc/; revision=22593 --- reactos/tools/ppc.lost+found/pmake | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/tools/ppc.lost+found/pmake b/reactos/tools/ppc.lost+found/pmake index 2d1ce52ad2e..942a1f2d7ca 100755 --- a/reactos/tools/ppc.lost+found/pmake +++ b/reactos/tools/ppc.lost+found/pmake @@ -2,6 +2,7 @@ export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin make \ + ARCH=powerpc \ HOST=mingw32-linux \ ROS_INTERMEDIATE=obj-ppc \ ROS_OUTPUT=output-ppc \ From f55d60a18310418fe5677981fb61a69a6b5f5dc4 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 21:56:05 +0000 Subject: [PATCH 04/81] PowerPC wip stragglers. svn path=/branches/powerpc/; revision=22594 --- reactos/lib/pseh/powerpc/framebased.s | 50 +++++++++++++++++++++++++++ reactos/lib/pseh/powerpc/setjmp.s | 43 +++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 reactos/lib/pseh/powerpc/framebased.s create mode 100644 reactos/lib/pseh/powerpc/setjmp.s diff --git a/reactos/lib/pseh/powerpc/framebased.s b/reactos/lib/pseh/powerpc/framebased.s new file mode 100644 index 00000000000..49d2bd9a6d9 --- /dev/null +++ b/reactos/lib/pseh/powerpc/framebased.s @@ -0,0 +1,50 @@ +# Copyright (c) 2004/2005 KJK::Hyperion + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to dos so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + .section .text + + .globl __SEHCleanHandlerEnvironment +__SEHCleanHandlerEnvironment: + blr + + .globl __SEHCurrentRegistration +__SEHCurrentRegistration: + blr + + .globl __SEHRegisterFrame +__SEHRegisterFrame: + blr + + .globl __SEHUnregisterFrame +__SEHUnregisterFrame: + blr + + .globl __SEHGlobalUnwind +__SEHGlobalUnwind: + + .globl __SEHRtlUnwind + +# RtlUnwind clobbers all the "don't clobber" registers, so we save them + blr + +.RestoreRegisters: + blr + +# EOF diff --git a/reactos/lib/pseh/powerpc/setjmp.s b/reactos/lib/pseh/powerpc/setjmp.s new file mode 100644 index 00000000000..2a6dc32a670 --- /dev/null +++ b/reactos/lib/pseh/powerpc/setjmp.s @@ -0,0 +1,43 @@ +# Copyright (c) 2004/2005 KJK::Hyperion + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to dos so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + .section .text + +# Note: the undecorated names are for Borland C++ (and possibly other compilers +# using the OMF format) + .globl _SEHSetJmp + .globl __SEHSetJmp +_SEHSetJmp: +__SEHSetJmp: + blr + + .globl _SEHLongJmp + .globl __SEHLongJmp +_SEHLongJmp: +__SEHLongJmp: + blr + + .globl _SEHLongJmp_KeepEsp + .globl __SEHLongJmp_KeepEsp +_SEHLongJmp_KeepEsp: +__SEHLongJmp_KeepEsp: + blr + +# EOF From fc38707bc03337d684ce781bef52c4424bb825e5 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 22:03:20 +0000 Subject: [PATCH 05/81] WIP straggler. svn path=/branches/powerpc/; revision=22595 --- reactos/include/reactos/elf/elf-powerpc.h | 153 ++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 reactos/include/reactos/elf/elf-powerpc.h diff --git a/reactos/include/reactos/elf/elf-powerpc.h b/reactos/include/reactos/elf/elf-powerpc.h new file mode 100644 index 00000000000..cc862299636 --- /dev/null +++ b/reactos/include/reactos/elf/elf-powerpc.h @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 1996-1997 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $ + */ + +#ifndef _MACHINE_ELF_H_ +#define _MACHINE_ELF_H_ 1 + +/* + * ELF definitions for the powerpc architecture. + */ + +#ifdef _REACTOS_ELF_MACHINE_IS_TARGET + +#ifndef __ELF_WORD_SIZE +#define __ELF_WORD_SIZE 32 /* Used by */ +#endif + +#include + +#define ELF_ARCH EM_386 + +#define ELF_MACHINE_OK(x) ((x) == EM_386 || (x) == EM_486) + +/* + * Auxiliary vector entries for passing information to the interpreter. + * + * The powerpc supplement to the SVR4 ABI specification names this "auxv_t", + * but POSIX lays claim to all symbols ending with "_t". + */ + +typedef struct { /* Auxiliary vector entry on initial stack */ + int a_type; /* Entry type. */ + union { + long a_val; /* Integer value. */ + void *a_ptr; /* Address. */ + void (*a_fcn)(void); /* Function pointer (not used). */ + } a_un; +} Elf32_Auxinfo; + +#if __ELF_WORD_SIZE == 64 +/* Fake for amd64 loader support */ +typedef struct { + int fake; +} Elf64_Auxinfo; +#endif + +__ElfType(Auxinfo); + +/* Values for a_type. */ +#define AT_NULL 0 /* Terminates the vector. */ +#define AT_IGNORE 1 /* Ignored entry. */ +#define AT_EXECFD 2 /* File descriptor of program to load. */ +#define AT_PHDR 3 /* Program header of program already loaded. */ +#define AT_PHENT 4 /* Size of each program header entry. */ +#define AT_PHNUM 5 /* Number of program header entries. */ +#define AT_PAGESZ 6 /* Page size in bytes. */ +#define AT_BASE 7 /* Interpreter's base address. */ +#define AT_FLAGS 8 /* Flags (unused for powerpc). */ +#define AT_ENTRY 9 /* Where interpreter should transfer control. */ + +/* + * The following non-standard values are used for passing information + * from John Polstra's testbed program to the dynamic linker. These + * are expected to go away soon. + * + * Unfortunately, these overlap the Linux non-standard values, so they + * must not be used in the same context. + */ +#define AT_BRK 10 /* Starting point for sbrk and brk. */ +#define AT_DEBUG 11 /* Debugging level. */ + +/* + * The following non-standard values are used in Linux ELF binaries. + */ +#define AT_NOTELF 10 /* Program is not ELF ?? */ +#define AT_UID 11 /* Real uid. */ +#define AT_EUID 12 /* Effective uid. */ +#define AT_GID 13 /* Real gid. */ +#define AT_EGID 14 /* Effective gid. */ + +#define AT_COUNT 15 /* Count of defined aux entry types. */ + +/* Define "machine" characteristics */ +#define ELF_TARG_CLASS ELFCLASS32 +#define ELF_TARG_DATA ELFDATA2LSB +#define ELF_TARG_MACH EM_386 +#define ELF_TARG_VER 1 + +#endif /* _REACTOS_ELF_MACHINE_IS_TARGET */ + +/* + * Relocation types. + */ + +#define R_386_NONE 0 /* No relocation. */ +#define R_386_32 1 /* Add symbol value. */ +#define R_386_PC32 2 /* Add PC-relative symbol value. */ +#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ +#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ +#define R_386_COPY 5 /* Copy data from shared object. */ +#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ +#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ +#define R_386_RELATIVE 8 /* Add load address of shared object. */ +#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ +#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ +#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ +#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ +#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ +#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ +#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ +#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ +#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ +#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ +#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ +#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ +#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ +#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ +#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ +#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ +#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ + +#define R_386_COUNT 38 /* Count of defined relocation types. */ + +#endif /* !_MACHINE_ELF_H_ */ From 1ef3e5d46497262d575b5df79456fbaf60f4c7c6 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 22:07:06 +0000 Subject: [PATCH 06/81] Added simple main function for powerpc. svn path=/branches/powerpc/; revision=22596 --- reactos/ntoskrnl/ke/powerpc/main_asm.S | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 reactos/ntoskrnl/ke/powerpc/main_asm.S diff --git a/reactos/ntoskrnl/ke/powerpc/main_asm.S b/reactos/ntoskrnl/ke/powerpc/main_asm.S new file mode 100644 index 00000000000..34f65311035 --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/main_asm.S @@ -0,0 +1,57 @@ +#include +#include + +#define AP_MAGIC (0x12481020) + +.global _kernel_stack +.global _kernel_stack_top +.global _kernel_trap_stack +.global _kernel_trap_stack_top + + .section .bss + .align 12 + + +/* guard page for the kernel stack */ +.fill 4096, 1, 0 + +_kernel_stack: +.fill 3*4096, 1, 0 +_kernel_stack_top: + +/* guard page for the trap stack */ +.fill 4096, 1, 0 + +_kernel_trap_stack: +.fill 3*4096, 1, 0 +_kernel_trap_stack_top: + + .text + .globl NtProcessStartup +NtProcessStartup: + lis 0,AP_MAGIC@ha + ori 0,0,AP_MAGIC@l + cmpw 0,0,3 + bne .m1 + + /* + * Reserve space for the floating point save area. + */ + addi 1,1,-SIZEOF_FX_SAVE_AREA + + /* + * Call the application processor initialization code + */ + bl _KiSystemStartup + +.m1: + /* Load the initial kernel stack */ + lis 1,_kernel_stack_top@ha + ori 1,1,_kernel_stack_top@l + addi 1,1,-SIZEOF_FX_SAVE_AREA + + /* Call the main kernel initialization */ + mr 3,5 + mr 4,6 + bl __main + From 61239b654c5a7a1ef5a1ae2d3a22a1043be98e8c Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 22:10:40 +0000 Subject: [PATCH 07/81] WIP Stragglers. svn path=/branches/powerpc/; revision=22597 --- reactos/boot/freeldr/freeldr/include/arch/powerpc/compat.h | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 reactos/boot/freeldr/freeldr/include/arch/powerpc/compat.h diff --git a/reactos/boot/freeldr/freeldr/include/arch/powerpc/compat.h b/reactos/boot/freeldr/freeldr/include/arch/powerpc/compat.h new file mode 100644 index 00000000000..5a4e8657f2f --- /dev/null +++ b/reactos/boot/freeldr/freeldr/include/arch/powerpc/compat.h @@ -0,0 +1,6 @@ +#ifndef FREELDR_ARCH_POWERPC_COMPAT_H +#define FREELDR_ARCH_POWERPC_COMPAT_H + +#include + +#endif/*FREELDR_ARCH_POWERPC_COMPAT_H*/ From b0ae60eb7d716a650d59a672f017647d7850021f Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 22:21:34 +0000 Subject: [PATCH 08/81] Added link for freeldr. svn path=/branches/powerpc/; revision=22598 --- reactos/tools/ppc.lost+found/link-freeldr | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 reactos/tools/ppc.lost+found/link-freeldr diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr new file mode 100755 index 00000000000..1b2b68b48be --- /dev/null +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -0,0 +1,8 @@ +#!/bin/sh + +export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin +ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a +objcopy -O binary freeldr.elf freeldr.tmp +objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload +reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s +ld -EB -Ttext 0xe00000 -e _begin -o ofwldr ofwboot.o ofwldr.payload From 3ea4c44cdacbefa0262d578710a5b9697187a91b Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 24 Jun 2006 23:53:21 +0000 Subject: [PATCH 09/81] Small update to WIP. svn path=/branches/powerpc/; revision=22604 --- reactos/tools/ppc.lost+found/link-ntoskrnl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/tools/ppc.lost+found/link-ntoskrnl b/reactos/tools/ppc.lost+found/link-ntoskrnl index df2e348dca6..905b6ecf5d4 100755 --- a/reactos/tools/ppc.lost+found/link-ntoskrnl +++ b/reactos/tools/ppc.lost+found/link-ntoskrnl @@ -1,3 +1,3 @@ #!/bin/sh -xv -reactos-powerpc-gcc --begin-group -v -Wl,--subsystem,native -Wl,--entry,NtProcessStartup -Wl,--image-base,0x80000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe obj-ppc/ntoskrnl/ke/powerpc/main_asm.o obj-ppc/ntoskrnl/ke/apc.o obj-ppc/ntoskrnl/ke/bug.o obj-ppc/ntoskrnl/ke/clock.o obj-ppc/ntoskrnl/ke/device.o obj-ppc/ntoskrnl/ke/dpc.o obj-ppc/ntoskrnl/ke/event.o obj-ppc/ntoskrnl/ke/exception.o obj-ppc/ntoskrnl/ke/gate.o obj-ppc/ntoskrnl/ke/gmutex.o obj-ppc/ntoskrnl/ke/ipi.o obj-ppc/ntoskrnl/ke/kqueue.o obj-ppc/ntoskrnl/ke/kthread.o obj-ppc/ntoskrnl/ke/main.o obj-ppc/ntoskrnl/ke/mutex.o obj-ppc/ntoskrnl/ke/process.o obj-ppc/ntoskrnl/ke/profile.o obj-ppc/ntoskrnl/ke/queue.o obj-ppc/ntoskrnl/ke/sem.o obj-ppc/ntoskrnl/ke/spinlock.o obj-ppc/ntoskrnl/ke/timer.o obj-ppc/ntoskrnl/ke/usercall.o obj-ppc/ntoskrnl/ke/wait.o obj-ppc/ntoskrnl/cc/cacheman.o obj-ppc/ntoskrnl/cc/copy.o obj-ppc/ntoskrnl/cc/fs.o obj-ppc/ntoskrnl/cc/mdl.o obj-ppc/ntoskrnl/cc/pin.o obj-ppc/ntoskrnl/cc/view.o obj-ppc/ntoskrnl/cm/import.o obj-ppc/ntoskrnl/cm/ntfunc.o obj-ppc/ntoskrnl/cm/regfile.o obj-ppc/ntoskrnl/cm/registry.o obj-ppc/ntoskrnl/cm/regobj.o obj-ppc/ntoskrnl/dbgk/dbgkutil.o obj-ppc/ntoskrnl/dbgk/debug.o obj-ppc/ntoskrnl/ex/atom.o obj-ppc/ntoskrnl/ex/callback.o obj-ppc/ntoskrnl/ex/dbgctrl.o obj-ppc/ntoskrnl/ex/error.o obj-ppc/ntoskrnl/ex/event.o obj-ppc/ntoskrnl/ex/evtpair.o obj-ppc/ntoskrnl/ex/fmutex.o obj-ppc/ntoskrnl/ex/handle.o obj-ppc/ntoskrnl/ex/init.o obj-ppc/ntoskrnl/ex/lookas.o obj-ppc/ntoskrnl/ex/mutant.o obj-ppc/ntoskrnl/ex/power.o obj-ppc/ntoskrnl/ex/pushlock.o obj-ppc/ntoskrnl/ex/profile.o obj-ppc/ntoskrnl/ex/resource.o obj-ppc/ntoskrnl/ex/rundown.o obj-ppc/ntoskrnl/ex/sem.o obj-ppc/ntoskrnl/ex/sysinfo.o obj-ppc/ntoskrnl/ex/time.o obj-ppc/ntoskrnl/ex/timer.o obj-ppc/ntoskrnl/ex/uuid.o obj-ppc/ntoskrnl/ex/win32k.o obj-ppc/ntoskrnl/ex/work.o obj-ppc/ntoskrnl/ex/zone.o obj-ppc/ntoskrnl/ex/zw.o obj-ppc/ntoskrnl/fs/context.o obj-ppc/ntoskrnl/fs/fastio.o obj-ppc/ntoskrnl/fs/filelock.o obj-ppc/ntoskrnl/fs/mcb.o obj-ppc/ntoskrnl/fs/name.o obj-ppc/ntoskrnl/fs/notify.o obj-ppc/ntoskrnl/fs/oplock.o obj-ppc/ntoskrnl/fs/pool.o obj-ppc/ntoskrnl/fs/tunnel.o obj-ppc/ntoskrnl/fs/unc.o obj-ppc/ntoskrnl/fs/util.o obj-ppc/ntoskrnl/inbv/inbv.o obj-ppc/ntoskrnl/io/adapter.o obj-ppc/ntoskrnl/io/arcname.o obj-ppc/ntoskrnl/io/bootlog.o obj-ppc/ntoskrnl/io/controller.o obj-ppc/ntoskrnl/io/device.o obj-ppc/ntoskrnl/io/deviface.o obj-ppc/ntoskrnl/io/disk.o obj-ppc/ntoskrnl/io/driver.o obj-ppc/ntoskrnl/io/efi.o obj-ppc/ntoskrnl/io/error.o obj-ppc/ntoskrnl/io/event.o obj-ppc/ntoskrnl/io/fs.o obj-ppc/ntoskrnl/io/iocomp.o obj-ppc/ntoskrnl/io/iomgr.o obj-ppc/ntoskrnl/io/iowork.o obj-ppc/ntoskrnl/io/irp.o obj-ppc/ntoskrnl/io/irq.o obj-ppc/ntoskrnl/io/mdl.o obj-ppc/ntoskrnl/io/plugplay.o obj-ppc/ntoskrnl/io/pnpdma.o obj-ppc/ntoskrnl/io/pnpmgr.o obj-ppc/ntoskrnl/io/pnpnotify.o obj-ppc/ntoskrnl/io/pnpreport.o obj-ppc/ntoskrnl/io/pnproot.o obj-ppc/ntoskrnl/io/rawfs.o obj-ppc/ntoskrnl/io/remlock.o obj-ppc/ntoskrnl/io/resource.o obj-ppc/ntoskrnl/io/share.o obj-ppc/ntoskrnl/io/symlink.o obj-ppc/ntoskrnl/io/timer.o obj-ppc/ntoskrnl/io/vpb.o obj-ppc/ntoskrnl/io/wmi.o obj-ppc/ntoskrnl/io/file.o obj-ppc/ntoskrnl/kd/wrappers/bochs.o obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o obj-ppc/ntoskrnl/kd/kdinit.o obj-ppc/ntoskrnl/kd/kdio.o obj-ppc/ntoskrnl/kd/kdmain.o obj-ppc/ntoskrnl/ldr/loader.o obj-ppc/ntoskrnl/ldr/rtl.o obj-ppc/ntoskrnl/lpc/close.o obj-ppc/ntoskrnl/lpc/complete.o obj-ppc/ntoskrnl/lpc/connect.o obj-ppc/ntoskrnl/lpc/create.o obj-ppc/ntoskrnl/lpc/listen.o obj-ppc/ntoskrnl/lpc/port.o obj-ppc/ntoskrnl/lpc/query.o obj-ppc/ntoskrnl/lpc/queue.o obj-ppc/ntoskrnl/lpc/receive.o obj-ppc/ntoskrnl/lpc/reply.o obj-ppc/ntoskrnl/lpc/send.o obj-ppc/ntoskrnl/mm/anonmem.o obj-ppc/ntoskrnl/mm/aspace.o obj-ppc/ntoskrnl/mm/balance.o obj-ppc/ntoskrnl/mm/cont.o obj-ppc/ntoskrnl/mm/drvlck.o obj-ppc/ntoskrnl/mm/freelist.o obj-ppc/ntoskrnl/mm/iospace.o obj-ppc/ntoskrnl/mm/kmap.o obj-ppc/ntoskrnl/mm/marea.o obj-ppc/ntoskrnl/mm/mdl.o obj-ppc/ntoskrnl/mm/mm.o obj-ppc/ntoskrnl/mm/process.o obj-ppc/ntoskrnl/mm/mminit.o obj-ppc/ntoskrnl/mm/mpw.o obj-ppc/ntoskrnl/mm/ncache.o obj-ppc/ntoskrnl/mm/npool.o obj-ppc/ntoskrnl/mm/pagefile.o obj-ppc/ntoskrnl/mm/pageop.o obj-ppc/ntoskrnl/mm/pager.o obj-ppc/ntoskrnl/mm/pagfault.o obj-ppc/ntoskrnl/mm/paging.o obj-ppc/ntoskrnl/mm/pe.o obj-ppc/ntoskrnl/mm/physical.o obj-ppc/ntoskrnl/mm/pool.o obj-ppc/ntoskrnl/mm/ppool.o obj-ppc/ntoskrnl/mm/region.o obj-ppc/ntoskrnl/mm/rmap.o obj-ppc/ntoskrnl/mm/section.o obj-ppc/ntoskrnl/mm/verifier.o obj-ppc/ntoskrnl/mm/virtual.o obj-ppc/ntoskrnl/mm/wset.o obj-ppc/ntoskrnl/mm/elf32.o obj-ppc/ntoskrnl/mm/elf64.o obj-ppc/ntoskrnl/ob/obdir.o obj-ppc/ntoskrnl/ob/obinit.o obj-ppc/ntoskrnl/ob/obhandle.o obj-ppc/ntoskrnl/ob/obname.o obj-ppc/ntoskrnl/ob/oblife.o obj-ppc/ntoskrnl/ob/obref.o obj-ppc/ntoskrnl/ob/sdcache.o obj-ppc/ntoskrnl/ob/security.o obj-ppc/ntoskrnl/ob/symlink.o obj-ppc/ntoskrnl/ob/wait.o obj-ppc/ntoskrnl/po/power.o obj-ppc/ntoskrnl/ps/debug.o obj-ppc/ntoskrnl/ps/idle.o obj-ppc/ntoskrnl/ps/job.o obj-ppc/ntoskrnl/ps/kill.o obj-ppc/ntoskrnl/ps/locale.o obj-ppc/ntoskrnl/ps/notify.o obj-ppc/ntoskrnl/ps/process.o obj-ppc/ntoskrnl/ps/psmgr.o obj-ppc/ntoskrnl/ps/query.o obj-ppc/ntoskrnl/ps/quota.o obj-ppc/ntoskrnl/ps/security.o obj-ppc/ntoskrnl/ps/suspend.o obj-ppc/ntoskrnl/ps/thread.o obj-ppc/ntoskrnl/ps/win32.o obj-ppc/ntoskrnl/rtl/libsupp.o obj-ppc/ntoskrnl/rtl/misc.o obj-ppc/ntoskrnl/rtl/nls.o obj-ppc/ntoskrnl/rtl/regio.o obj-ppc/ntoskrnl/rtl/strtok.o obj-ppc/ntoskrnl/se/access.o obj-ppc/ntoskrnl/se/acl.o obj-ppc/ntoskrnl/se/audit.o obj-ppc/ntoskrnl/se/lsa.o obj-ppc/ntoskrnl/se/luid.o obj-ppc/ntoskrnl/se/priv.o obj-ppc/ntoskrnl/se/sd.o obj-ppc/ntoskrnl/se/semgr.o obj-ppc/ntoskrnl/se/sid.o obj-ppc/ntoskrnl/se/token.o obj-ppc/ntoskrnl/ntoskrnl.coff obj-ppc/ntoskrnl/kdbg/kdb_symbols.o obj-ppc/lib/drivers/csq/csq.a obj-ppc/hal/hal/libhal.a obj-ppc/lib/kjs/kjs.a obj-ppc/lib/pseh/pseh.a obj-ppc/lib/rtl/rtl.a obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/wdmguid/wdmguid.a -nostartfiles -nostdlib -lgcc -g --end-group +reactos-powerpc-gcc --begin-group -v -Wl,--subsystem,native -Wl,--entry,NtProcessStartup -Wl,--image-base,0x80000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe obj-ppc/ntoskrnl/ke/powerpc/main_asm.o obj-ppc/ntoskrnl/ke/apc.o obj-ppc/ntoskrnl/ke/bug.o obj-ppc/ntoskrnl/ke/clock.o obj-ppc/ntoskrnl/ke/device.o obj-ppc/ntoskrnl/ke/dpc.o obj-ppc/ntoskrnl/ke/event.o obj-ppc/ntoskrnl/ke/exception.o obj-ppc/ntoskrnl/ke/gate.o obj-ppc/ntoskrnl/ke/gmutex.o obj-ppc/ntoskrnl/ke/ipi.o obj-ppc/ntoskrnl/ke/kqueue.o obj-ppc/ntoskrnl/ke/kthread.o obj-ppc/ntoskrnl/ke/main.o obj-ppc/ntoskrnl/ke/mutex.o obj-ppc/ntoskrnl/ke/process.o obj-ppc/ntoskrnl/ke/profile.o obj-ppc/ntoskrnl/ke/queue.o obj-ppc/ntoskrnl/ke/sem.o obj-ppc/ntoskrnl/ke/spinlock.o obj-ppc/ntoskrnl/ke/timer.o obj-ppc/ntoskrnl/ke/usercall.o obj-ppc/ntoskrnl/ke/wait.o obj-ppc/ntoskrnl/cc/cacheman.o obj-ppc/ntoskrnl/cc/copy.o obj-ppc/ntoskrnl/cc/fs.o obj-ppc/ntoskrnl/cc/mdl.o obj-ppc/ntoskrnl/cc/pin.o obj-ppc/ntoskrnl/cc/view.o obj-ppc/ntoskrnl/cm/import.o obj-ppc/ntoskrnl/cm/ntfunc.o obj-ppc/ntoskrnl/cm/regfile.o obj-ppc/ntoskrnl/cm/registry.o obj-ppc/ntoskrnl/cm/regobj.o obj-ppc/ntoskrnl/dbgk/dbgkutil.o obj-ppc/ntoskrnl/dbgk/debug.o obj-ppc/ntoskrnl/ex/atom.o obj-ppc/ntoskrnl/ex/callback.o obj-ppc/ntoskrnl/ex/dbgctrl.o obj-ppc/ntoskrnl/ex/error.o obj-ppc/ntoskrnl/ex/event.o obj-ppc/ntoskrnl/ex/evtpair.o obj-ppc/ntoskrnl/ex/fmutex.o obj-ppc/ntoskrnl/ex/handle.o obj-ppc/ntoskrnl/ex/init.o obj-ppc/ntoskrnl/ex/lookas.o obj-ppc/ntoskrnl/ex/mutant.o obj-ppc/ntoskrnl/ex/power.o obj-ppc/ntoskrnl/ex/pushlock.o obj-ppc/ntoskrnl/ex/profile.o obj-ppc/ntoskrnl/ex/resource.o obj-ppc/ntoskrnl/ex/rundown.o obj-ppc/ntoskrnl/ex/sem.o obj-ppc/ntoskrnl/ex/sysinfo.o obj-ppc/ntoskrnl/ex/time.o obj-ppc/ntoskrnl/ex/timer.o obj-ppc/ntoskrnl/ex/uuid.o obj-ppc/ntoskrnl/ex/win32k.o obj-ppc/ntoskrnl/ex/work.o obj-ppc/ntoskrnl/ex/zone.o obj-ppc/ntoskrnl/ex/zw.o obj-ppc/ntoskrnl/fs/context.o obj-ppc/ntoskrnl/fs/fastio.o obj-ppc/ntoskrnl/fs/filelock.o obj-ppc/ntoskrnl/fs/mcb.o obj-ppc/ntoskrnl/fs/name.o obj-ppc/ntoskrnl/fs/notify.o obj-ppc/ntoskrnl/fs/oplock.o obj-ppc/ntoskrnl/fs/pool.o obj-ppc/ntoskrnl/fs/tunnel.o obj-ppc/ntoskrnl/fs/unc.o obj-ppc/ntoskrnl/fs/util.o obj-ppc/ntoskrnl/inbv/inbv.o obj-ppc/ntoskrnl/io/adapter.o obj-ppc/ntoskrnl/io/arcname.o obj-ppc/ntoskrnl/io/bootlog.o obj-ppc/ntoskrnl/io/controller.o obj-ppc/ntoskrnl/io/device.o obj-ppc/ntoskrnl/io/deviface.o obj-ppc/ntoskrnl/io/disk.o obj-ppc/ntoskrnl/io/driver.o obj-ppc/ntoskrnl/io/efi.o obj-ppc/ntoskrnl/io/error.o obj-ppc/ntoskrnl/io/event.o obj-ppc/ntoskrnl/io/fs.o obj-ppc/ntoskrnl/io/iocomp.o obj-ppc/ntoskrnl/io/iomgr.o obj-ppc/ntoskrnl/io/iowork.o obj-ppc/ntoskrnl/io/irp.o obj-ppc/ntoskrnl/io/irq.o obj-ppc/ntoskrnl/io/mdl.o obj-ppc/ntoskrnl/io/plugplay.o obj-ppc/ntoskrnl/io/pnpdma.o obj-ppc/ntoskrnl/io/pnpmgr.o obj-ppc/ntoskrnl/io/pnpnotify.o obj-ppc/ntoskrnl/io/pnpreport.o obj-ppc/ntoskrnl/io/pnproot.o obj-ppc/ntoskrnl/io/rawfs.o obj-ppc/ntoskrnl/io/remlock.o obj-ppc/ntoskrnl/io/resource.o obj-ppc/ntoskrnl/io/share.o obj-ppc/ntoskrnl/io/symlink.o obj-ppc/ntoskrnl/io/timer.o obj-ppc/ntoskrnl/io/vpb.o obj-ppc/ntoskrnl/io/wmi.o obj-ppc/ntoskrnl/io/file.o obj-ppc/ntoskrnl/kd/wrappers/bochs.o obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o obj-ppc/ntoskrnl/kd/kdinit.o obj-ppc/ntoskrnl/kd/kdio.o obj-ppc/ntoskrnl/kd/kdmain.o obj-ppc/ntoskrnl/ldr/loader.o obj-ppc/ntoskrnl/ldr/rtl.o obj-ppc/ntoskrnl/lpc/close.o obj-ppc/ntoskrnl/lpc/complete.o obj-ppc/ntoskrnl/lpc/connect.o obj-ppc/ntoskrnl/lpc/create.o obj-ppc/ntoskrnl/lpc/listen.o obj-ppc/ntoskrnl/lpc/port.o obj-ppc/ntoskrnl/lpc/query.o obj-ppc/ntoskrnl/lpc/queue.o obj-ppc/ntoskrnl/lpc/receive.o obj-ppc/ntoskrnl/lpc/reply.o obj-ppc/ntoskrnl/lpc/send.o obj-ppc/ntoskrnl/mm/anonmem.o obj-ppc/ntoskrnl/mm/aspace.o obj-ppc/ntoskrnl/mm/balance.o obj-ppc/ntoskrnl/mm/cont.o obj-ppc/ntoskrnl/mm/drvlck.o obj-ppc/ntoskrnl/mm/freelist.o obj-ppc/ntoskrnl/mm/iospace.o obj-ppc/ntoskrnl/mm/kmap.o obj-ppc/ntoskrnl/mm/marea.o obj-ppc/ntoskrnl/mm/mdl.o obj-ppc/ntoskrnl/mm/mm.o obj-ppc/ntoskrnl/mm/process.o obj-ppc/ntoskrnl/mm/mminit.o obj-ppc/ntoskrnl/mm/mpw.o obj-ppc/ntoskrnl/mm/ncache.o obj-ppc/ntoskrnl/mm/npool.o obj-ppc/ntoskrnl/mm/pagefile.o obj-ppc/ntoskrnl/mm/pageop.o obj-ppc/ntoskrnl/mm/pager.o obj-ppc/ntoskrnl/mm/pagfault.o obj-ppc/ntoskrnl/mm/paging.o obj-ppc/ntoskrnl/mm/pe.o obj-ppc/ntoskrnl/mm/physical.o obj-ppc/ntoskrnl/mm/pool.o obj-ppc/ntoskrnl/mm/ppool.o obj-ppc/ntoskrnl/mm/region.o obj-ppc/ntoskrnl/mm/rmap.o obj-ppc/ntoskrnl/mm/section.o obj-ppc/ntoskrnl/mm/verifier.o obj-ppc/ntoskrnl/mm/virtual.o obj-ppc/ntoskrnl/mm/wset.o obj-ppc/ntoskrnl/mm/elf32.o obj-ppc/ntoskrnl/mm/elf64.o obj-ppc/ntoskrnl/ob/obdir.o obj-ppc/ntoskrnl/ob/obinit.o obj-ppc/ntoskrnl/ob/obhandle.o obj-ppc/ntoskrnl/ob/obname.o obj-ppc/ntoskrnl/ob/oblife.o obj-ppc/ntoskrnl/ob/obref.o obj-ppc/ntoskrnl/ob/sdcache.o obj-ppc/ntoskrnl/ob/symlink.o obj-ppc/ntoskrnl/po/power.o obj-ppc/ntoskrnl/ps/debug.o obj-ppc/ntoskrnl/ps/idle.o obj-ppc/ntoskrnl/ps/job.o obj-ppc/ntoskrnl/ps/kill.o obj-ppc/ntoskrnl/ps/locale.o obj-ppc/ntoskrnl/ps/notify.o obj-ppc/ntoskrnl/ps/process.o obj-ppc/ntoskrnl/ps/psmgr.o obj-ppc/ntoskrnl/ps/query.o obj-ppc/ntoskrnl/ps/quota.o obj-ppc/ntoskrnl/ps/security.o obj-ppc/ntoskrnl/ps/suspend.o obj-ppc/ntoskrnl/ps/thread.o obj-ppc/ntoskrnl/ps/win32.o obj-ppc/ntoskrnl/rtl/libsupp.o obj-ppc/ntoskrnl/rtl/misc.o obj-ppc/ntoskrnl/rtl/nls.o obj-ppc/ntoskrnl/rtl/regio.o obj-ppc/ntoskrnl/rtl/strtok.o obj-ppc/ntoskrnl/se/access.o obj-ppc/ntoskrnl/se/acl.o obj-ppc/ntoskrnl/se/audit.o obj-ppc/ntoskrnl/se/lsa.o obj-ppc/ntoskrnl/se/luid.o obj-ppc/ntoskrnl/se/priv.o obj-ppc/ntoskrnl/se/sd.o obj-ppc/ntoskrnl/se/semgr.o obj-ppc/ntoskrnl/se/sid.o obj-ppc/ntoskrnl/se/token.o obj-ppc/ntoskrnl/ntoskrnl.coff obj-ppc/ntoskrnl/kdbg/kdb_symbols.o obj-ppc/lib/drivers/csq/csq.a obj-ppc/hal/hal/libhal.a obj-ppc/lib/kjs/kjs.a obj-ppc/lib/pseh/pseh.a obj-ppc/lib/rtl/rtl.a obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/wdmguid/wdmguid.a -nostartfiles -nostdlib -lgcc -g --end-group From 9ae023f4774e12cab132634cb2a36d3a5b001b48 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 25 Jun 2006 18:12:29 +0000 Subject: [PATCH 10/81] Get at least the basics working and make regdump output a little nicer. svn path=/branches/powerpc/; revision=22612 --- reactos/boot/freeldr/bootsect/ofwboot.s | 76 ++++++++++--------------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index ac9b039b8e2..627d7658814 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -15,11 +15,6 @@ _begin: addi %r1,%r1,stack@l addi %r1,%r1,16384 - 0x10 - mfmsr %r8 - li %r0,0 - mtmsr %r0 - isync - /* Store ofw call addr */ mr %r21,%r5 lis %r10,0xe00000@ha @@ -27,10 +22,12 @@ _begin: bl setup_bats - li %r8,0x3030 - mtmsr %r8 + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_banner - _start - bl ofw_print_regs + bl ofw_print_string + + bl ofw_print_eol lis %r4,_binary_freeldr_tmp_end@ha addi %r4,%r4,_binary_freeldr_tmp_end@l @@ -40,18 +37,13 @@ _begin: lis %r5,0x8000@ha addi %r5,%r5,0x8000@l + bl ofw_print_regs + bl copy_bits bl zero_registers - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_banner - _start - - bl ofw_print_string - - bl ofw_print_eol - - bl setup_exc +/* bl setup_exc */ /* Zero CTR */ mtcr %r31 @@ -81,36 +73,9 @@ _begin: * the address given as the 1st argument. */ setup_bats: - mfpvr 5 - rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ - cmpwi 0,5,1 - li 0,0 - bne 4f - mtibatl 3,0 /* invalidate BAT first */ - ori 3,3,4 /* set up BAT registers for 601 */ - li 4,0x7f - mtibatu 2,3 - mtibatl 2,4 - oris 3,3,0x80 - oris 4,4,0x80 - mtibatu 3,3 - mtibatl 3,4 - b 5f -4: mtdbatu 3,0 /* invalidate BATs first */ - mtibatu 3,0 - ori 3,3,0xff /* set up BAT registers for 604 */ - li 4,2 - mtdbatl 2,4 - mtdbatu 2,3 - mtibatl 2,4 - mtibatu 2,3 - oris 3,3,0x80 - oris 4,4,0x80 - mtdbatl 3,4 - mtdbatu 3,3 - mtibatl 3,4 - mtibatu 3,3 -5: sync + xor 3,3,3 + + sync isync blr @@ -498,6 +463,25 @@ ofw_register_loop: lwz %r3,144(%r1) addi %r3,%r3,1 stw %r3,144(%r1) + + bl ofw_print_space + + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_init - _start + bl ofw_print_string + lwz %r3,144(%r1) + bl ofw_print_number + bl ofw_print_space + lwz %r3,144(%r1) + mulli %r3,%r3,4 + add %r3,%r1,%r3 + lwz %r3,0(%r3) + stw %r3,152(%r1) + bl ofw_print_number + lwz %r3,144(%r1) + addi %r3,%r3,1 + stw %r3,144(%r1) + b done_dump dump_optional: From 511258568b05b2d678da22d07945b8b25360c660 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 07:32:56 +0000 Subject: [PATCH 11/81] Add ofw interface generator. It's a bit like mig is for mach. Just does some convenience stuff, since we're an unusual OS, and we have special needs wrt OF. svn path=/branches/powerpc/; revision=22654 --- reactos/Makefile | 5 +- reactos/tools/ofw_interface/calls.ofw | 15 + reactos/tools/ofw_interface/ofw_interface.cpp | 270 ++++++++++++++++++ reactos/tools/ofw_interface/ofw_interface.mak | 58 ++++ 4 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 reactos/tools/ofw_interface/calls.ofw create mode 100644 reactos/tools/ofw_interface/ofw_interface.cpp create mode 100644 reactos/tools/ofw_interface/ofw_interface.mak diff --git a/reactos/Makefile b/reactos/Makefile index 8b555f9227c..82353bfdc5b 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -370,7 +370,10 @@ PREAUTO := \ $(ERRCODES_H) \ $(ERRCODES_RC) \ $(NCI_SERVICE_FILES) \ - $(GENDIB_DIB_FILES) + $(GENDIB_DIB_FILES) \ + $(OFW_INTERFACE_OUTPUT) \ + $(OFW_INTERFACE_SOURCE) \ + $(OFW_INTERFACE_HEADER) $(ROS_AUTOMAKE): $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES) $(ECHO_RBUILD) diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw new file mode 100644 index 00000000000..c51f5518ba8 --- /dev/null +++ b/reactos/tools/ofw_interface/calls.ofw @@ -0,0 +1,15 @@ +# Function Args Returns Types +# Real OFW functions to proxy +finddevice 1 1 char* int +open 1 1 int int +getprop 4 1 int char* int*:arg3 int int +write 3 1 int char*:arg2 int int +read 3 1 int char*:arg2 int int +exit 0 0 +child 1 1 int int +peer 1 1 int int +seek 3 1 int int int int +# Convenience functions that interact closely with OFW (written in BE asm) +-dumpregs 0 0 +-print_string 1 0 char* +-print_number 1 0 int diff --git a/reactos/tools/ofw_interface/ofw_interface.cpp b/reactos/tools/ofw_interface/ofw_interface.cpp new file mode 100644 index 00000000000..fdb7a365bb4 --- /dev/null +++ b/reactos/tools/ofw_interface/ofw_interface.cpp @@ -0,0 +1,270 @@ +#include +#include +#include +#include +#include +#include + +class ofw_wrappers { +public: + int base, ctindex; + std::string functions; + std::string names; + std::string calltable; + std::string le_stubs; + std::string of_call; +}; + +std::string uppercase( const std::string &toucase ) { + std::vector ucase_work(toucase.size()); + for( size_t i = 0; i < toucase.size(); i++ ) { + ucase_work[i] = toupper(toucase[i]); + } + return std::string(&ucase_work[0], toucase.size()); +} + +std::string clip_eol( std::string in, const std::string &eol_marks ) { + size_t found; + for( size_t i = 0; i < eol_marks.size(); i++ ) { + found = in.find( eol_marks[i] ); + if( found != std::string::npos ) + in = in.substr( 0, found ); + } + return in; +} + +int round_up( int x, int factor ) { + return (x + (factor - 1)) & (factor - 1); +} + +std::string c_type( const std::string &intype ) { + size_t colon = intype.find(':'); + if( colon != std::string::npos ) return intype.substr(0,colon); + else if( intype.size() ) return intype; + else return "void"; +} + +std::string have_len( const std::string &intype ) { + size_t colon = intype.find(':'); + if( colon != std::string::npos ) return intype.substr(colon+1); + else return ""; +} + +bool need_swap( const std::string &intype ) { + return intype.find('*') != std::string::npos; +} + +void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { + std::istringstream iss(line); + bool make_function = true; + std::string name, argtype, rettype, c_rettype; + std::vector argtypes; + int args, rets, i, local_offset, total_stack; + std::ostringstream function, ct_csource, le_stub, of_call; + + iss >> name >> args >> rets; + + if( !name.size() ) return; + if( name[0] == '-' ) { + name = name.substr(1); + make_function = false; + } + + for( i = 0; i < args; i++ ) { + iss >> argtype; + argtypes.push_back(argtype); + } + + iss >> rettype; + + local_offset = (3 + rets + args) * 4; + total_stack = round_up(12 + local_offset, 16); + + function << "ofw_" << name << ":\n" + << "\t/* Reserve stack space */\n" + << "\tsubi %r1,%r1," << total_stack << "\n" + << "\t/* Store r8, r9, lr */\n" + << "\tstw %r8," << (local_offset + 0) << "(%r1)\n" + << "\tstw %r9," << (local_offset + 4) << "(%r1)\n" + << "\tmflr %r8\n" + << "\tstw %r8," << (local_offset + 8) << "(%r1)\n" + << "\t/* Get read name */\n" + << "\tlis %r8," << wrapper.base << "@ha\n" + << "\taddi %r9,%r8," << name << "_ofw_name - _start\n" + << "\tstw %r9,0(%r1)\n" + << "\t/* " << args << " arguments and " << rets << " return */\n" + << "\tli %r9," << args << "\n" + << "\tstw %r9,4(%r1)\n" + << "\tli %r9," << rets << "\n" + << "\tstw %r9,8(%r1)\n"; + + for( int i = 0; i < args; i++ ) + function << "\tstw %r" << (i+3) << "," << (4 * (i + 3)) << "(%r1)\n"; + + function << "\t/* Load up the call address */\n" + << "\tlwz %r9,ofw_call_addr - _start(%r8)\n" + << "\tmtlr %r9\n" + << "\t/* Set argument */\n" + << "\tmr %r3,%r1\n" + << "\t/* Fire */\n" + << "\tblrl\n" + << "\tlwz %r3," << (local_offset - 4) << "(%r1)\n" + << "\t/* Restore registers */\n" + << "\tlwz %r8," << (local_offset + 8) << "(%r1)\n" + << "\tmtlr %r8\n" + << "\tlwz %r9," << (local_offset + 4) << "(%r1)\n" + << "\tlwz %r8," << (local_offset + 0) << "(%r1)\n" + << "\t/* Return */\n" + << "\taddi %r1,%r1," << total_stack << "\n" + << "\tblr\n"; + + c_rettype = c_type(rettype); + + le_stub << c_rettype << " ofw_" << name << "("; + for( i = 0; i < args; i++ ) { + if( i ) le_stub << ","; + le_stub << c_type(argtypes[i]) << " arg" << i; + } + le_stub << ")"; + of_call << le_stub.str() << ";\n"; + + le_stub << " {\n"; + if( c_rettype != "void" ) + le_stub << "\t" << c_rettype << " ret;\n"; + + for( i = 0; i < args; i++ ) { + if( need_swap(argtypes[i]) ) { + std::string len; + if( have_len(argtypes[i]).size() ) + len = have_len(argtypes[i]); + else { + std::ostringstream oss; + oss << "strlen(arg" << i << ")"; + len = oss.str(); + } + le_stub << "\tle_swap(" + << "arg" << i << "," + << "arg" << i << "+" << len << "," + << "arg" << i << ");\n"; + } + } + + le_stub << "\t"; + if( c_rettype != "void" ) le_stub << "ret = (" << c_rettype << ")"; + + le_stub << "ofproxy(" << (wrapper.ctindex * 4); + + for( i = 0; i < 4; i++ ) { + if( i < args ) le_stub << ",(void *)arg" << i; + else le_stub << ",NULL"; + } + + le_stub << ");\n"; + + for( i = args-1; i >= 0; i-- ) { + if( need_swap(argtypes[i]) ) { + std::string len; + if( have_len(argtypes[i]).size() ) + len = have_len(argtypes[i]); + else { + std::ostringstream oss; + oss << "strlen(arg" << i << ")"; + len = oss.str(); + } + le_stub << "\tle_swap(" + << "arg" << i << "," + << "arg" << i << "+" << len << "," + << "arg" << i << ");\n"; + } + } + + if( c_rettype != "void" ) + le_stub << "\treturn ret;\n"; + + le_stub << "}\n"; + + if( make_function ) wrapper.functions += function.str(); + wrapper.le_stubs += le_stub.str(); + wrapper.of_call += of_call.str(); + wrapper.names += name + "_ofw_name:\n\t.asciz \"" + name + "\"\n"; + wrapper.calltable += std::string("\t.long ofw_") + name + "\n"; + wrapper.ctindex++; +} + +int main( int argc, char **argv ) { + int status = 0; + std::ifstream in; + std::ofstream out, outcsource, outcheader; + std::string line; + const char *eol_marks = "#\r\n"; + ofw_wrappers wrappers; + + wrappers.base = 0xe00000; + wrappers.ctindex = 0; + + if( argc < 5 ) { + fprintf( stderr, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv[0] ); + return 1; + } + + in.open( argv[1] ); + if( !in ) { + fprintf( stderr, "can't open %s\n", argv[1] ); + status = 1; + goto error; + } + + out.open( argv[2] ); + if( !out ) { + fprintf( stderr, "can't open %s\n", argv[2] ); + status = 1; + goto error; + } + + outcsource.open( argv[3] ); + if( !outcsource ) { + fprintf( stderr, "can't open %s\n", argv[3] ); + status = 1; + goto error; + } + + outcheader.open( argv[4] ); + if( !outcheader ) { + fprintf( stderr, "can't open %s\n", argv[4] ); + status = 1; + goto error; + } + + while( std::getline( in, line ) ) { + line = clip_eol( line, eol_marks ); + if( line.size() ) populate_definition( wrappers, line ); + } + + out << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n" + << "\t.section .text\n" + << "\t.globl _start\n" + << "\t.globl ofw_call_addr\n" + << "ofw_call_addr:\n" + << "\t.long 0\n" + << "\n/* Function Wrappers */\n\n" + << wrappers.functions + << "\t/* Function Names */\n\n" + << wrappers.names + << "\n/* Function Call Table for Freeldr */\n\n" + << "ofw_functions:\n" + << wrappers.calltable + << "\n/* End */\n"; + + outcsource << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n" + << "#include \"of.h\"\n" + << wrappers.le_stubs; + + outcheader << "/* AUTOMATICALLY GENERATE BY ofw_interface */\n" + << "#ifndef _OFW_CALLS_H\n" + << "#define _OFW_CALLS_H\n" + << wrappers.of_call + << "#endif/*_OFW_CALLS_H*/\n"; + +error: + return status; +} diff --git a/reactos/tools/ofw_interface/ofw_interface.mak b/reactos/tools/ofw_interface/ofw_interface.mak new file mode 100644 index 00000000000..5afeb40c2a8 --- /dev/null +++ b/reactos/tools/ofw_interface/ofw_interface.mak @@ -0,0 +1,58 @@ +OFW_INTERFACE_BASE = $(TOOLS_BASE_)ofw_interface +OFW_INTERFACE_BASE_ = $(OFW_INTERFACE_BASE)$(SEP) +OFW_INTERFACE_INT = $(INTERMEDIATE_)$(OFW_INTERFACE_BASE) +OFW_INTERFACE_INT_ = $(OFW_INTERFACE_INT)$(SEP) +OFW_INTERFACE_OUT = $(OUTPUT_)$(OFW_INTERFACE_BASE) +OFW_INTERFACE_OUT_ = $(OFW_INTERFACE_OUT)$(SEP) + +OFW_INTERFACE_OUTPUT = boot/freeldr/bootsect/ofw.s +OFW_INTERFACE_SOURCE = boot/freeldr/freeldr/arch/powerpc/ofw.c +OFW_INTERFACE_HEADER = boot/freeldr/freeldr/include/of_call.h +OFW_INTERFACE_INPUT = $(OFW_INTERFACE_BASE_)calls.ofw + +$(OFW_INTERFACE_INT): | $(TOOLS_INT) + $(ECHO_MKDIR) + ${mkdir} $@ + +ifneq ($(INTERMEDIATE),$(OUTPUT)) +$(OFW_INTERFACE_OUT): | $(TOOLS_OUT) + $(ECHO_MKDIR) + ${mkdir} $@ +endif + +OFW_INTERFACE_TARGET = \ + $(EXEPREFIX)$(OFW_INTERFACE_OUT_)ofw_interface$(EXEPOSTFIX) + +OFW_INTERFACE_SOURCES = $(addprefix $(OFW_INTERFACE_BASE_), \ + ofw_interface.cpp \ + ) + +OFW_INTERFACE_OBJECTS = \ + $(addprefix $(INTERMEDIATE_), $(OFW_INTERFACE_SOURCES:.cpp=.o)) + +OFW_INTERFACE_HOST_CFLAGS = $(TOOLS_CFLAGS) + +OFW_INTERFACE_HOST_LFLAGS = $(TOOLS_LFLAGS) + +$(OFW_INTERFACE_TARGET): $(OFW_INTERFACE_OBJECTS) | $(OFW_INTERFACE_OUT) + $(ECHO_LD) + ${host_gpp} $(OFW_INTERFACE_OBJECTS) $(OFW_INTERFACE_HOST_LFLAGS) -o $@ + +$(OFW_INTERFACE_INT_)ofw_interface.o: $(OFW_INTERFACE_BASE_)ofw_interface.cpp | $(OFW_INTERFACE_INT) + $(ECHO_CC) + ${host_gpp} $(OFW_INTERFACE_HOST_CFLAGS) -c $< -o $@ + +$(OFW_INTERFACE_OUTPUT): ofw_interface + $(OFW_INTERFACE_TARGET) \ + $(OFW_INTERFACE_INPUT) \ + $(OFW_INTERFACE_OUTPUT) \ + $(OFW_INTERFACE_SOURCE) \ + $(OFW_INTERFACE_HEADER) + +.PHONY: ofw_interface +ofw_interface: $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT) + +.PHONY: ofw_interface_clean +ofw_interface_clean: + -@$(rm) $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_OBJECTS) 2>$(NUL) +clean: ofw_interface_clean From 67f4a8ac0fd4ec85bd9fac07b082aad035e11c0d Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 07:46:47 +0000 Subject: [PATCH 12/81] Small tweaks. svn path=/branches/powerpc/; revision=22655 --- reactos/Makefile | 1 + reactos/tools/ofw_interface/ofw_interface.mak | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index 82353bfdc5b..49b50ee9314 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -203,6 +203,7 @@ ifeq ($(HALFVERBOSEECHO),yes) ECHO_RSYM =@echo $(QUOTE)[RSYM] $@$(QUOTE) ECHO_WMC =@echo $(QUOTE)[WMC] $@$(QUOTE) ECHO_NCI =@echo $(QUOTE)[NCI] $@$(QUOTE) + ECHO_OFW =@echo $(QUOTE)[OFW] $@$(QUOTE) ECHO_CABMAN =@echo $(QUOTE)[CABMAN] $<$(QUOTE) ECHO_CDMAKE =@echo $(QUOTE)[CDMAKE] $@$(QUOTE) ECHO_MKHIVE =@echo $(QUOTE)[MKHIVE] $@$(QUOTE) diff --git a/reactos/tools/ofw_interface/ofw_interface.mak b/reactos/tools/ofw_interface/ofw_interface.mak index 5afeb40c2a8..85f5a9c8f2b 100644 --- a/reactos/tools/ofw_interface/ofw_interface.mak +++ b/reactos/tools/ofw_interface/ofw_interface.mak @@ -9,6 +9,10 @@ OFW_INTERFACE_OUTPUT = boot/freeldr/bootsect/ofw.s OFW_INTERFACE_SOURCE = boot/freeldr/freeldr/arch/powerpc/ofw.c OFW_INTERFACE_HEADER = boot/freeldr/freeldr/include/of_call.h OFW_INTERFACE_INPUT = $(OFW_INTERFACE_BASE_)calls.ofw +OFW_INTERFACE_SERVICE_FILES = \ + $(OFW_INTERFACE_OUTPUT) \ + $(OFW_INTERFACE_SOURCE) \ + $(OFW_INTERFACE_HEADER) $(OFW_INTERFACE_INT): | $(TOOLS_INT) $(ECHO_MKDIR) @@ -42,15 +46,16 @@ $(OFW_INTERFACE_INT_)ofw_interface.o: $(OFW_INTERFACE_BASE_)ofw_interface.cpp | $(ECHO_CC) ${host_gpp} $(OFW_INTERFACE_HOST_CFLAGS) -c $< -o $@ -$(OFW_INTERFACE_OUTPUT): ofw_interface - $(OFW_INTERFACE_TARGET) \ +$(OFW_SERVICE_FILES): $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT) + $(ECHO_OFW) + $(Q)$(OFW_INTERFACE_TARGET) \ $(OFW_INTERFACE_INPUT) \ $(OFW_INTERFACE_OUTPUT) \ $(OFW_INTERFACE_SOURCE) \ $(OFW_INTERFACE_HEADER) .PHONY: ofw_interface -ofw_interface: $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT) +ofw_interface: $(OFW_INTERFACE_TARGET) .PHONY: ofw_interface_clean ofw_interface_clean: From d91cff1ae8fc5fa38ee41ec853c82fe921baf7af Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 08:01:08 +0000 Subject: [PATCH 13/81] Regularize with generated interfaces. svn path=/branches/powerpc/; revision=22656 --- reactos/Makefile | 4 +- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 90 +------------------ .../boot/freeldr/freeldr/freeldr_arch.rbuild | 1 + reactos/boot/freeldr/freeldr/include/of.h | 14 +-- reactos/tools/ofw_interface/calls.ofw | 2 +- reactos/tools/ofw_interface/ofw_interface.mak | 2 +- 6 files changed, 11 insertions(+), 102 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index 49b50ee9314..68c1d76027e 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -372,9 +372,7 @@ PREAUTO := \ $(ERRCODES_RC) \ $(NCI_SERVICE_FILES) \ $(GENDIB_DIB_FILES) \ - $(OFW_INTERFACE_OUTPUT) \ - $(OFW_INTERFACE_SOURCE) \ - $(OFW_INTERFACE_HEADER) + $(OFW_INTERFACE_SERVICE_FILES) $(ROS_AUTOMAKE): $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES) $(ECHO_RBUILD) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 0f339440a27..674a4b4ac0d 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -29,9 +29,9 @@ BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; -void le_swap( const void *start_addr_v, - const void *end_addr_v, - const void *target_addr_v ) { +void le_swap( void *start_addr_v, + void *end_addr_v, + void *target_addr_v ) { long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8), *end_addr = (long *)ROUND_UP((long)end_addr_v,8), *target_addr = (long *)ROUND_DOWN((long)target_addr_v,8); @@ -45,90 +45,6 @@ void le_swap( const void *start_addr_v, } } -int ofw_finddevice( const char *name ) { - int ret, len; - - len = strlen(name); - le_swap( name, name + len, name ); - ret = ofproxy( 0, (char *)name, NULL, NULL, NULL ); - le_swap( name, name + len, name ); - return ret; -} - -int ofw_getprop( int package, const char *name, void *buffer, int buflen ) { - int ret, len = strlen(name); - le_swap( name, name + len, name ); - le_swap( buffer, (char *)buffer + buflen, buffer ); - ret = ofproxy - ( 4, (void *)package, (char *)name, buffer, (void *)buflen ); - le_swap( buffer, (char *)buffer + buflen, buffer ); - le_swap( name, name + len, name ); - return ret; -} - -/* Since this is from external storage, it doesn't need swapping */ -int ofw_write( int handle, const char *data, int len ) { - int ret; - le_swap( data, data + len, data ); - ret = ofproxy - ( 8, (void *)handle, (char *)data, (void *)len, NULL ); - le_swap( data, data + len, data ); - return ret; -} - -/* Since this is from external storage, it doesn't need swapping */ -int ofw_read( int handle, const char *data, int len ) { - int ret; - - le_swap( data, data + len, data ); - ret = ofproxy - ( 12, (void *)handle, (char *)data, (void *)len, NULL ); - le_swap( data, data + len, data ); - - return ret; -} - -void ofw_exit() { - ofproxy( 16, NULL, NULL, NULL, NULL ); -} - -void ofw_dumpregs() { - ofproxy( 20, NULL, NULL, NULL, NULL ); -} - -void ofw_print_string( const char *str ) { - int len = strlen(str); - le_swap( (char *)str, str + len, (char *)str ); - ofproxy( 24, (void *)str, NULL, NULL, NULL ); - le_swap( (char *)str, str + len, (char *)str ); -} - -void ofw_print_number( int num ) { - ofproxy( 28, (void *)num, NULL, NULL, NULL ); -} - -int ofw_open( const char *name ) { - int ret, len; - - len = strlen(name); - le_swap( name, name + len, name ); - ret = ofproxy( 32, (char *)name, NULL, NULL, NULL ); - le_swap( name, name + len, name ); - return ret; -} - -int ofw_child( int package ) { - return ofproxy( 36, (void *)package, NULL, NULL, NULL ); -} - -int ofw_peer( int package ) { - return ofproxy( 40, (void *)package, NULL, NULL, NULL ); -} - -int ofw_seek( int handle, long long location ) { - return ofproxy( 44, (void *)handle, (void *)(int)(location >> 32), (void *)(int)location, NULL ); -} - void PpcPutChar( int ch ) { char buf[3]; if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; } diff --git a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild index ca61e7448ed..0fef874b74d 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild @@ -62,6 +62,7 @@ -fno-zero-initialized-in-bss -Os boot.s + ofw.c mach.c mboot.c diff --git a/reactos/boot/freeldr/freeldr/include/of.h b/reactos/boot/freeldr/freeldr/include/of.h index 445f6654dfe..3eb431f84df 100644 --- a/reactos/boot/freeldr/freeldr/include/of.h +++ b/reactos/boot/freeldr/freeldr/include/of.h @@ -6,20 +6,14 @@ #define REV(x) (((x)>>24)&0xff)|(((x)>>8)&0xff00)|(((x)<<24)&0xff000000)|(((x)<<8)&0xff0000) +#include "of_call.h" +#include + typedef int (*of_proxy) ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4 ); typedef long jmp_buf[100]; - extern of_proxy ofproxy; - -int ofw_finddevice( const char *name ); -int ofw_getprop( int package, const char *name, void *buffer, int size ); -int ofw_open( const char *name ); -int ofw_write( int handle, const char *buffer, int size ); -int ofw_read( int handle, const char *buffer, int size ); -void ofw_print_string(const char *); -void ofw_print_number(int); -void ofw_exit(); +extern void le_swap( void *begin, void *end, void *dest ); int setjmp( jmp_buf buf ); int longjmp( jmp_buf buf, int retval ); diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index c51f5518ba8..a0986e5fc91 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -2,7 +2,7 @@ # Real OFW functions to proxy finddevice 1 1 char* int open 1 1 int int -getprop 4 1 int char* int*:arg3 int int +getprop 4 1 int char* char*:arg3 int int write 3 1 int char*:arg2 int int read 3 1 int char*:arg2 int int exit 0 0 diff --git a/reactos/tools/ofw_interface/ofw_interface.mak b/reactos/tools/ofw_interface/ofw_interface.mak index 85f5a9c8f2b..265c27e841f 100644 --- a/reactos/tools/ofw_interface/ofw_interface.mak +++ b/reactos/tools/ofw_interface/ofw_interface.mak @@ -46,7 +46,7 @@ $(OFW_INTERFACE_INT_)ofw_interface.o: $(OFW_INTERFACE_BASE_)ofw_interface.cpp | $(ECHO_CC) ${host_gpp} $(OFW_INTERFACE_HOST_CFLAGS) -c $< -o $@ -$(OFW_SERVICE_FILES): $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT) +$(OFW_INTERFACE_SERVICE_FILES): $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT) $(ECHO_OFW) $(Q)$(OFW_INTERFACE_TARGET) \ $(OFW_INTERFACE_INPUT) \ From 15c645139d110634804a410fa7f919e537e74b9a Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 08:15:06 +0000 Subject: [PATCH 14/81] Add ofw generated object file. svn path=/branches/powerpc/; revision=22657 --- reactos/tools/ppc.lost+found/link-freeldr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr index 1b2b68b48be..56a2484d90c 100755 --- a/reactos/tools/ppc.lost+found/link-freeldr +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -1,8 +1,8 @@ #!/bin/sh export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin -ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a -objcopy -O binary freeldr.elf freeldr.tmp +ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a +objcopy -O binary --only-section=.text --only-section=.data --only-section=.bss freeldr.elf freeldr.tmp objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s ld -EB -Ttext 0xe00000 -e _begin -o ofwldr ofwboot.o ofwldr.payload From 0b3ce78bbe57308a0ba9d6bff64a7aba32e5d9b5 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 08:51:04 +0000 Subject: [PATCH 15/81] Forward functions verified working. svn path=/branches/powerpc/; revision=22658 --- reactos/tools/ofw_interface/calls.ofw | 4 ++-- reactos/tools/ofw_interface/ofw_interface.cpp | 2 +- reactos/tools/tools.mak | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index a0986e5fc91..5a7352e04bf 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -1,14 +1,14 @@ # Function Args Returns Types # Real OFW functions to proxy finddevice 1 1 char* int -open 1 1 int int +open 1 1 char* int getprop 4 1 int char* char*:arg3 int int write 3 1 int char*:arg2 int int read 3 1 int char*:arg2 int int exit 0 0 child 1 1 int int peer 1 1 int int -seek 3 1 int int int int +seek 2 1 int int int # Convenience functions that interact closely with OFW (written in BE asm) -dumpregs 0 0 -print_string 1 0 char* diff --git a/reactos/tools/ofw_interface/ofw_interface.cpp b/reactos/tools/ofw_interface/ofw_interface.cpp index fdb7a365bb4..80998c1a20d 100644 --- a/reactos/tools/ofw_interface/ofw_interface.cpp +++ b/reactos/tools/ofw_interface/ofw_interface.cpp @@ -34,7 +34,7 @@ std::string clip_eol( std::string in, const std::string &eol_marks ) { } int round_up( int x, int factor ) { - return (x + (factor - 1)) & (factor - 1); + return (x + (factor - 1)) & ~(factor - 1); } std::string c_type( const std::string &intype ) { diff --git a/reactos/tools/tools.mak b/reactos/tools/tools.mak index e991f06610d..e7b7c7e8a2d 100644 --- a/reactos/tools/tools.mak +++ b/reactos/tools/tools.mak @@ -52,6 +52,7 @@ include tools/gendib/gendib.mak include tools/mkhive/mkhive.mak include tools/nci/nci.mak include tools/rbuild/rbuild.mak +include tools/ofw_interface/ofw_interface.mak include tools/unicode/unicode.mak include tools/widl/widl.mak include tools/winebuild/winebuild.mak From 5ac23d52a380483965125c8471855ff08083aafd Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 08:56:20 +0000 Subject: [PATCH 16/81] Utility functions separated, simple test (register dump) svn path=/branches/powerpc/; revision=22659 --- .../boot/freeldr/bootsect/ofw_tests/ofwtest.s | 187 +++++++++ reactos/boot/freeldr/bootsect/ofw_util.s | 368 ++++++++++++++++++ 2 files changed, 555 insertions(+) create mode 100644 reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s create mode 100644 reactos/boot/freeldr/bootsect/ofw_util.s diff --git a/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s b/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s new file mode 100644 index 00000000000..131d20d5aff --- /dev/null +++ b/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s @@ -0,0 +1,187 @@ + .section .text + +_start: + .long 0xe00000 + 12 + .long 0 + .long 0 + + .globl ofw_functions_addr + .globl ofw_dumpregs + +ofw_functions_addr: + .long ofw_functions + + .globl _begin +_begin: + sync + isync + + lis %r1,stack@ha + addi %r1,%r1,stack@l + addi %r1,%r1,16384 - 0x10 + + /* Store ofw call addr */ + mr %r21,%r5 + lis %r8,_start@ha + addi %r7,%r8,ofw_call_addr - _start + stw %r21,0(%r7) + + bl ofw_dumpregs + +foo: + b foo + + .align 4 +call_freeldr: + /* Get the address of the functions list -- + * Note: + * Because of little endian switch we must use an even number of + * instructions here.. Pad with a nop if needed. */ + mfmsr %r10 + ori %r10,%r10,1 + mtmsr %r10 + + nop + + /* Note that this is little-endian from here on */ + blr + nop + + .align 4 + +call_ofw: + /* R3 has the function offset to call (n * 4) + * Other arg registers are unchanged. + * Note that these 4 instructions are in reverse order due to + * little-endian convention */ + andi. %r0,%r0,65534 + mfmsr %r0 + mtmsr %r0 + /* Now normal ordering resumes */ + subi %r1,%r1,0x100 + + stw %r8,4(%r1) + stw %r9,8(%r1) + stw %r10,12(%r1) + mflr %r8 + stw %r8,16(%r1) + + lis %r10,0xe00000@ha + add %r9,%r3,%r10 + lwz %r3,ofw_functions_addr - _start@l(%r9) + lwz %r3,0(%r3) + mtctr %r3 + + mr %r3,%r4 + mr %r4,%r5 + mr %r5,%r6 + mr %r6,%r7 + mr %r7,%r8 + + /* Goto the swapped function */ + bctrl + + lwz %r8,16(%r1) + mtlr %r8 + + lwz %r8,4(%r1) + lwz %r9,8(%r1) + lwz %r10,12(%r1) + + addi %r1,%r1,0x100 + /* Ok, go back to little endian */ + mfmsr %r0 + ori %r0,%r0,1 + mtmsr %r0 + + /* Note that this is little-endian from here on */ + blr + nop + +zero_registers: + xor %r2,%r2,%r2 + mr %r0,%r2 + mr %r3,%r2 + + mr %r4,%r2 + mr %r5,%r2 + mr %r6,%r2 + mr %r7,%r2 + + mr %r8,%r2 + mr %r9,%r2 + mr %r10,%r2 + mr %r11,%r2 + + mr %r12,%r2 + mr %r13,%r2 + mr %r14,%r2 + mr %r15,%r2 + + mr %r12,%r2 + mr %r13,%r2 + mr %r14,%r2 + mr %r15,%r2 + + mr %r16,%r2 + mr %r17,%r2 + mr %r18,%r2 + mr %r19,%r2 + + mr %r20,%r2 + mr %r21,%r2 + mr %r22,%r2 + mr %r23,%r2 + + mr %r24,%r2 + mr %r25,%r2 + mr %r26,%r2 + mr %r27,%r2 + + mr %r28,%r2 + mr %r29,%r2 + mr %r30,%r2 + mr %r31,%r2 + + blr + + .org 0x1000 +freeldr_banner: + .ascii "ReactOS OpenFirmware Boot Program\r\n\0" + +freeldr_halt: + .ascii "ReactOS OpenFirmware Boot Program Halting\r\n\0" + +freeldr_reg_init: + .ascii "r\0" +freeldr_reg_lr: + .ascii "lr \0" +freeldr_reg_cr: + .ascii "cr \0" +freeldr_reg_ctr: + .ascii "ctr\0" +freeldr_reg_msr: + .ascii "msr\0" + +ofw_memory_size: + .long 0 + .long 0 + .long 0 + .long 0 + +ofw_chosen_name: + .ascii "/chosen\0" + +ofw_stdout_name: + .ascii "stdout\0" + +ofw_memory_name: + .ascii "/memory@0\0" + +ofw_reg_name: + .ascii "reg\0" + + .org 0x2000 +stack: + .space 0x4000 + diff --git a/reactos/boot/freeldr/bootsect/ofw_util.s b/reactos/boot/freeldr/bootsect/ofw_util.s new file mode 100644 index 00000000000..1da50c9ec09 --- /dev/null +++ b/reactos/boot/freeldr/bootsect/ofw_util.s @@ -0,0 +1,368 @@ + .section .text +prim_strlen: + mr %r5,%r3 +prim_strlen_loop: + lbz %r4,0(%r3) + cmpi 0,0,%r4,0 + beq prim_strlen_done + addi %r3,%r3,1 + b prim_strlen_loop + +prim_strlen_done: + sub %r3,%r3,%r5 + blr + +copy_bits: + cmp 0,0,%r3,%r4 + beqlr + + lwz %r6,0(%r3) + stw %r6,0(%r5) + addi %r3,%r3,4 + addi %r5,%r5,4 + b copy_bits + +ofw_print_string: + /* Reserve some stack space */ + subi %r1,%r1,32 + + /* Save args */ + stw %r3,0(%r1) + + /* Save the lr, a scratch register */ + stw %r8,8(%r1) + mflr %r8 + stw %r8,12(%r1) + + /* Load the package name */ + lis %r3,0xe00000@ha + addi %r3,%r3,ofw_chosen_name - _start + + /* Fire */ + bl ofw_finddevice + + /* Load up for getprop */ + stw %r3,16(%r1) + + lis %r4,0xe00000@ha + addi %r4,%r4,ofw_stdout_name - _start + + addi %r5,%r1,20 + + li %r6,4 + + bl ofw_getprop + + /* Measure the string and remember the length */ + lwz %r3,0(%r1) + bl prim_strlen + mr %r5,%r3 + + lwz %r3,20(%r1) + lwz %r4,0(%r1) + + /* Write the string */ + bl ofw_write + + /* Return */ + lwz %r8,12(%r1) + mtlr %r8 + lwz %r8,8(%r1) + + addi %r1,%r1,32 + blr + + /* Print 8 hex digits representing a number in r3 */ +ofw_print_number: + subi %r1,%r1,32 + stw %r8,0(%r1) + mflr %r8 + stw %r8,4(%r1) + stw %r9,8(%r1) + + xor %r9,%r9,%r9 + stw %r9,12(%r1) + + /* Set up and, devide, shift */ + mr %r8,%r3 + lis %r6,0xf0000000@ha + lis %r7,0x10000000@ha + li %r9,8 + +ofw_number_loop: + nop + cmpi 0,0,%r9,0 + beq ofw_number_return + subi %r9,%r9,1 + + /* Body: isolate digit, divide, print */ + and %r5,%r6,%r8 + divwu %r4,%r5,%r7 + srwi %r6,%r6,4 + srwi %r7,%r7,4 + + nop + + cmpi 0,0,%r4,10 + bge ofw_number_letter + addi %r4,%r4,'0' + b ofw_number_digit_out + +ofw_number_letter: + addi %r4,%r4,'A' - 10 + +ofw_number_digit_out: + stb %r4,12(%r1) + addi %r3,%r1,12 + + stw %r6,16(%r1) + stw %r7,20(%r1) + stw %r8,24(%r1) + stw %r9,28(%r1) + + bl ofw_print_string + + lwz %r6,16(%r1) + lwz %r7,20(%r1) + lwz %r8,24(%r1) + lwz %r9,28(%r1) + + b ofw_number_loop + +ofw_number_return: + /* Return */ + lwz %r9,8(%r1) + lwz %r8,4(%r1) + mtlr %r8 + lwz %r8,0(%r1) + addi %r1,%r1,32 + blr + +ofw_print_eol: + subi %r1,%r1,16 + stw %r8,0(%r1) + mflr %r8 + stw %r8,4(%r1) + li %r4,0x0d0a + sth %r4,8(%r1) + xor %r4,%r4,%r4 + sth %r4,10(%r1) + addi %r3,%r1,8 + bl ofw_print_string + lwz %r8,4(%r1) + mtlr %r8 + lwz %r8,0(%r1) + addi %r1,%r1,16 + blr + +ofw_print_nothing: + subi %r1,%r1,16 + stw %r8,0(%r1) + mflr %r8 + stw %r8,4(%r1) + li %r4,0 + sth %r4,8(%r1) + xor %r4,%r4,%r4 + sth %r4,10(%r1) + addi %r3,%r1,8 + bl ofw_print_string + lwz %r8,4(%r1) + mtlr %r8 + lwz %r8,0(%r1) + addi %r1,%r1,16 + blr + +ofw_print_space: + subi %r1,%r1,16 + stw %r8,0(%r1) + mflr %r8 + stw %r8,4(%r1) + li %r4,0x2000 + sth %r4,8(%r1) + xor %r4,%r4,%r4 + sth %r4,10(%r1) + addi %r3,%r1,8 + bl ofw_print_string + lwz %r8,4(%r1) + mtlr %r8 + lwz %r8,0(%r1) + addi %r1,%r1,16 + blr + +ofw_dumpregs: + /* Construct ofw exit call */ + subi %r1,%r1,0xa0 + + stw %r0,0(%r1) + stw %r1,4(%r1) + stw %r2,8(%r1) + stw %r3,12(%r1) + + stw %r4,16(%r1) + stw %r5,20(%r1) + stw %r6,24(%r1) + stw %r7,28(%r1) + + stw %r8,32(%r1) + stw %r9,36(%r1) + stw %r10,40(%r1) + stw %r11,44(%r1) + + stw %r12,48(%r1) + stw %r13,52(%r1) + stw %r14,56(%r1) + stw %r15,60(%r1) + + stw %r16,64(%r1) + stw %r17,68(%r1) + stw %r18,72(%r1) + stw %r19,76(%r1) + + stw %r20,80(%r1) + stw %r21,84(%r1) + stw %r22,88(%r1) + stw %r23,92(%r1) + + stw %r24,96(%r1) + stw %r25,100(%r1) + stw %r26,104(%r1) + stw %r27,108(%r1) + + stw %r28,112(%r1) + stw %r29,116(%r1) + stw %r30,120(%r1) + stw %r31,124(%r1) + + mflr %r0 + stw %r0,128(%r1) + mfcr %r0 + stw %r0,132(%r1) + mfctr %r0 + stw %r0,136(%r1) + mfmsr %r0 + stw %r0,140(%r1) + + /* Count at zero */ + xor %r0,%r0,%r0 + stw %r0,144(%r1) + mr %r3,%r1 + stw %r3,148(%r1) + + /* Body, print the regname, then the register */ +ofw_register_loop: + lwz %r3,144(%r1) + cmpi 0,0,%r3,32 + beq ofw_register_special + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_init - _start + bl ofw_print_string + lwz %r3,144(%r1) + bl ofw_print_number + bl ofw_print_space + lwz %r3,144(%r1) + mulli %r3,%r3,4 + add %r3,%r1,%r3 + lwz %r3,0(%r3) + stw %r3,152(%r1) + bl ofw_print_number + lwz %r3,144(%r1) + addi %r3,%r3,1 + stw %r3,144(%r1) + + bl ofw_print_space + + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_init - _start + bl ofw_print_string + lwz %r3,144(%r1) + bl ofw_print_number + bl ofw_print_space + lwz %r3,144(%r1) + mulli %r3,%r3,4 + add %r3,%r1,%r3 + lwz %r3,0(%r3) + stw %r3,152(%r1) + bl ofw_print_number + lwz %r3,144(%r1) + addi %r3,%r3,1 + stw %r3,144(%r1) + + b done_dump + +dump_optional: + bl ofw_print_space + bl ofw_print_space + lwz %r3,152(%r1) + lwz %r3,0(%r3) + bl ofw_print_number + bl ofw_print_space + lwz %r3,152(%r1) + lwz %r3,4(%r3) + bl ofw_print_number + bl ofw_print_space + lwz %r3,152(%r1) + lwz %r3,8(%r3) + bl ofw_print_number + bl ofw_print_space + lwz %r3,152(%r1) + lwz %r3,12(%r3) + bl ofw_print_number + bl ofw_print_space +done_dump: + bl ofw_print_eol + b ofw_register_loop + +ofw_register_special: + /* LR */ + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_lr - _start + bl ofw_print_string + bl ofw_print_space + lwz %r3,128(%r1) + bl ofw_print_number + bl ofw_print_eol + + /* CR */ + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_cr - _start + bl ofw_print_string + bl ofw_print_space + lwz %r3,132(%r1) + bl ofw_print_number + bl ofw_print_eol + + /* CTR */ + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_ctr - _start + bl ofw_print_string + bl ofw_print_space + lwz %r3,136(%r1) + bl ofw_print_number + bl ofw_print_eol + + /* MSR */ + lis %r3,0xe00000@ha + addi %r3,%r3,freeldr_reg_msr - _start + bl ofw_print_string + bl ofw_print_space + lwz %r3,140(%r1) + bl ofw_print_number + bl ofw_print_eol + + /* Return */ + lwz %r0,128(%r1) + mtlr %r0 + + lwz %r0,0(%r1) + lwz %r2,8(%r1) + lwz %r3,12(%r1) + + lwz %r4,16(%r1) + lwz %r5,20(%r1) + lwz %r6,24(%r1) + lwz %r7,28(%r1) + + addi %r1,%r1,0xa0 + + blr + From d2af61537f467bc77fdbdfdf83410d49f4280da5 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 10:02:42 +0000 Subject: [PATCH 17/81] Fix some sillyness. Remove some cruft. svn path=/branches/powerpc/; revision=22661 --- reactos/boot/freeldr/bootsect/ofw_util.s | 100 +- reactos/boot/freeldr/bootsect/ofwboot.s | 1119 +--------------------- 2 files changed, 120 insertions(+), 1099 deletions(-) diff --git a/reactos/boot/freeldr/bootsect/ofw_util.s b/reactos/boot/freeldr/bootsect/ofw_util.s index 1da50c9ec09..036a9c6fc11 100644 --- a/reactos/boot/freeldr/bootsect/ofw_util.s +++ b/reactos/boot/freeldr/bootsect/ofw_util.s @@ -1,4 +1,76 @@ .section .text + + .globl ofw_functions_addr +ofw_functions_addr: + .long ofw_functions + + .align 4 +call_freeldr: + /* Get the address of the functions list -- + * Note: + * Because of little endian switch we must use an even number of + * instructions here.. Pad with a nop if needed. */ + mfmsr %r10 + ori %r10,%r10,1 + mtmsr %r10 + + nop + + /* Note that this is little-endian from here on */ + blr + nop + + .align 4 + +call_ofw: + /* R3 has the function offset to call (n * 4) + * Other arg registers are unchanged. + * Note that these 4 instructions are in reverse order due to + * little-endian convention */ + andi. %r0,%r0,65534 + mfmsr %r0 + mtmsr %r0 + /* Now normal ordering resumes */ + subi %r1,%r1,0x100 + + stw %r8,4(%r1) + stw %r9,8(%r1) + stw %r10,12(%r1) + mflr %r8 + stw %r8,16(%r1) + + lis %r10,0xe00000@ha + add %r9,%r3,%r10 + lwz %r3,ofw_functions_addr - _start@l(%r9) + lwz %r3,0(%r3) + mtctr %r3 + + mr %r3,%r4 + mr %r4,%r5 + mr %r5,%r6 + mr %r6,%r7 + mr %r7,%r8 + + /* Goto the swapped function */ + bctrl + + lwz %r8,16(%r1) + mtlr %r8 + + lwz %r8,4(%r1) + lwz %r9,8(%r1) + lwz %r10,12(%r1) + + addi %r1,%r1,0x100 + /* Ok, go back to little endian */ + mfmsr %r0 + ori %r0,%r0,1 + mtmsr %r0 + + /* Note that this is little-endian from here on */ + blr + nop + prim_strlen: mr %r5,%r3 prim_strlen_loop: @@ -14,7 +86,7 @@ prim_strlen_done: copy_bits: cmp 0,0,%r3,%r4 - beqlr + bgelr lwz %r6,0(%r3) stw %r6,0(%r5) @@ -366,3 +438,29 @@ ofw_register_special: blr +ofw_chosen_name: + .ascii "/chosen\0" + +ofw_stdout_name: + .ascii "stdout\0" + +ofw_memory_name: + .ascii "/memory@0\0" + +ofw_reg_name: + .ascii "reg\0" + +freeldr_reg_init: + .ascii "r\0" + +freeldr_reg_lr: + .ascii "lr \0" + +freeldr_reg_cr: + .ascii "cr \0" + +freeldr_reg_ctr: + .ascii "ctr\0" + +freeldr_reg_msr: + .ascii "msr\0" diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index 627d7658814..70a55075f59 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -1,5 +1,4 @@ .section .text - .globl setup_bats _start: .long 0xe00000 + 12 @@ -20,8 +19,6 @@ _begin: lis %r10,0xe00000@ha stw %r5,ofw_call_addr - _start@l(%r10) - bl setup_bats - lis %r3,0xe00000@ha addi %r3,%r3,freeldr_banner - _start @@ -29,6 +26,21 @@ _begin: bl ofw_print_eol + /* Claim enough bytes to place freeldr at 0x8000 */ + lis %r3,0x8000@ha + addi %r3,%r3,0x8000@l + + lis %r4,_binary_freeldr_tmp_end@ha + addi %r4,%r4,_binary_freeldr_tmp_end@l + lis %r5,_binary_freeldr_tmp_start@ha + addi %r5,%r5,_binary_freeldr_tmp_start@l + sub %r4,%r4,%r5 + + xor %r5,%r5,%r5 + li %r5,0x1000 + + bl ofw_claim + lis %r4,_binary_freeldr_tmp_end@ha addi %r4,%r4,_binary_freeldr_tmp_end@l lis %r3,_binary_freeldr_tmp_start@ha @@ -37,25 +49,23 @@ _begin: lis %r5,0x8000@ha addi %r5,%r5,0x8000@l - bl ofw_print_regs + bl ofw_dumpregs bl copy_bits bl zero_registers -/* bl setup_exc */ - /* Zero CTR */ mtcr %r31 - + lis %r3,0x8000@ha addi %r3,%r3,0x8000@l mtlr %r3 - - lis %r3,call_ofw@ha - addi %r3,%r3,call_ofw - _start - + + lis %r3,call_freeldr@ha + addi %r3,%r3,call_freeldr - _start + blr /* @@ -79,71 +89,6 @@ setup_bats: isync blr - .align 4 -call_freeldr: - /* Get the address of the functions list -- - * Note: - * Because of little endian switch we must use an even number of - * instructions here.. Pad with a nop if needed. */ - mfmsr %r10 - ori %r10,%r10,1 - mtmsr %r10 - - nop - - /* Note that this is little-endian from here on */ - blr - nop - - .align 4 -call_ofw: - /* R3 has the function offset to call (n * 4) - * Other arg registers are unchanged. - * Note that these 4 instructions are in reverse order due to - * little-endian convention */ - andi. %r0,%r0,65534 - mfmsr %r0 - mtmsr %r0 - /* Now normal ordering resumes */ - subi %r1,%r1,0x100 - - stw %r8,4(%r1) - stw %r9,8(%r1) - stw %r10,12(%r1) - mflr %r8 - stw %r8,16(%r1) - - lis %r10,0xe00000@ha - add %r9,%r3,%r10 - lwz %r3,ofw_functions - _start@l(%r9) - mtctr %r3 - - mr %r3,%r4 - mr %r4,%r5 - mr %r5,%r6 - mr %r6,%r7 - mr %r7,%r8 - - /* Goto the swapped function */ - bctrl - - lwz %r8,16(%r1) - mtlr %r8 - - lwz %r8,4(%r1) - lwz %r9,8(%r1) - lwz %r10,12(%r1) - - addi %r1,%r1,0x100 - /* Ok, go back to little endian */ - mfmsr %r0 - ori %r0,%r0,1 - mtmsr %r0 - - /* Note that this is little-endian from here on */ - blr - nop - zero_registers: xor %r2,%r2,%r2 mr %r0,%r2 @@ -191,961 +136,6 @@ zero_registers: blr -prim_strlen: - mr %r5,%r3 -prim_strlen_loop: - lbz %r4,0(%r3) - cmpi 0,0,%r4,0 - beq prim_strlen_done - addi %r3,%r3,1 - b prim_strlen_loop - -prim_strlen_done: - sub %r3,%r3,%r5 - blr - -copy_bits: - cmp 0,0,%r3,%r4 - beqlr - lwz %r6,0(%r3) - stw %r6,0(%r5) - addi %r3,%r3,4 - addi %r5,%r5,4 - b copy_bits - -ofw_print_string_hook: - bl ofw_print_number - bl ofw_exit - -ofw_print_string: - /* Reserve some stack space */ - subi %r1,%r1,32 - - /* Save args */ - stw %r3,0(%r1) - - /* Save the lr, a scratch register */ - stw %r8,8(%r1) - mflr %r8 - stw %r8,12(%r1) - - /* Load the package name */ - lis %r3,0xe00000@ha - addi %r3,%r3,ofw_chosen_name - _start - - /* Fire */ - bl ofw_finddevice - - /* Load up for getprop */ - stw %r3,16(%r1) - - lis %r4,0xe00000@ha - addi %r4,%r4,ofw_stdout_name - _start - - addi %r5,%r1,20 - - li %r6,4 - - bl ofw_getprop - - /* Measure the string and remember the length */ - lwz %r3,0(%r1) - bl prim_strlen - mr %r5,%r3 - - lwz %r3,20(%r1) - lwz %r4,0(%r1) - - /* Write the string */ - bl ofw_write - - /* Return */ - lwz %r8,12(%r1) - mtlr %r8 - lwz %r8,8(%r1) - - addi %r1,%r1,32 - blr - - /* Print 8 hex digits representing a number in r3 */ -ofw_print_number: - subi %r1,%r1,32 - stw %r8,0(%r1) - mflr %r8 - stw %r8,4(%r1) - stw %r9,8(%r1) - - xor %r9,%r9,%r9 - stw %r9,12(%r1) - - /* Set up and, devide, shift */ - mr %r8,%r3 - lis %r6,0xf0000000@ha - lis %r7,0x10000000@ha - li %r9,8 - -ofw_number_loop: - nop - cmpi 0,0,%r9,0 - beq ofw_number_return - subi %r9,%r9,1 - - /* Body: isolate digit, divide, print */ - and %r5,%r6,%r8 - divwu %r4,%r5,%r7 - srwi %r6,%r6,4 - srwi %r7,%r7,4 - - nop - - cmpi 0,0,%r4,10 - bge ofw_number_letter - addi %r4,%r4,'0' - b ofw_number_digit_out - -ofw_number_letter: - addi %r4,%r4,'A' - 10 - -ofw_number_digit_out: - stb %r4,12(%r1) - addi %r3,%r1,12 - - stw %r6,16(%r1) - stw %r7,20(%r1) - stw %r8,24(%r1) - stw %r9,28(%r1) - - bl ofw_print_string - - lwz %r6,16(%r1) - lwz %r7,20(%r1) - lwz %r8,24(%r1) - lwz %r9,28(%r1) - - b ofw_number_loop - -ofw_number_return: - /* Return */ - lwz %r9,8(%r1) - lwz %r8,4(%r1) - mtlr %r8 - lwz %r8,0(%r1) - addi %r1,%r1,32 - blr - -ofw_print_eol: - subi %r1,%r1,16 - stw %r8,0(%r1) - mflr %r8 - stw %r8,4(%r1) - li %r4,0x0d0a - sth %r4,8(%r1) - xor %r4,%r4,%r4 - sth %r4,10(%r1) - addi %r3,%r1,8 - bl ofw_print_string - lwz %r8,4(%r1) - mtlr %r8 - lwz %r8,0(%r1) - addi %r1,%r1,16 - blr - -ofw_print_nothing: - subi %r1,%r1,16 - stw %r8,0(%r1) - mflr %r8 - stw %r8,4(%r1) - li %r4,0 - sth %r4,8(%r1) - xor %r4,%r4,%r4 - sth %r4,10(%r1) - addi %r3,%r1,8 - bl ofw_print_string - lwz %r8,4(%r1) - mtlr %r8 - lwz %r8,0(%r1) - addi %r1,%r1,16 - blr - -ofw_print_space: - subi %r1,%r1,16 - stw %r8,0(%r1) - mflr %r8 - stw %r8,4(%r1) - li %r4,0x2000 - sth %r4,8(%r1) - xor %r4,%r4,%r4 - sth %r4,10(%r1) - addi %r3,%r1,8 - bl ofw_print_string - lwz %r8,4(%r1) - mtlr %r8 - lwz %r8,0(%r1) - addi %r1,%r1,16 - blr - -ofw_print_regs: - /* Construct ofw exit call */ - subi %r1,%r1,0xa0 - - stw %r0,0(%r1) - stw %r1,4(%r1) - stw %r2,8(%r1) - stw %r3,12(%r1) - - stw %r4,16(%r1) - stw %r5,20(%r1) - stw %r6,24(%r1) - stw %r7,28(%r1) - - stw %r8,32(%r1) - stw %r9,36(%r1) - stw %r10,40(%r1) - stw %r11,44(%r1) - - stw %r12,48(%r1) - stw %r13,52(%r1) - stw %r14,56(%r1) - stw %r15,60(%r1) - - stw %r16,64(%r1) - stw %r17,68(%r1) - stw %r18,72(%r1) - stw %r19,76(%r1) - - stw %r20,80(%r1) - stw %r21,84(%r1) - stw %r22,88(%r1) - stw %r23,92(%r1) - - stw %r24,96(%r1) - stw %r25,100(%r1) - stw %r26,104(%r1) - stw %r27,108(%r1) - - stw %r28,112(%r1) - stw %r29,116(%r1) - stw %r30,120(%r1) - stw %r31,124(%r1) - - mflr %r0 - stw %r0,128(%r1) - mfcr %r0 - stw %r0,132(%r1) - mfctr %r0 - stw %r0,136(%r1) - mfmsr %r0 - stw %r0,140(%r1) - - /* Count at zero */ - xor %r0,%r0,%r0 - stw %r0,144(%r1) - mr %r3,%r1 - stw %r3,148(%r1) - - /* Body, print the regname, then the register */ -ofw_register_loop: - lwz %r3,144(%r1) - cmpi 0,0,%r3,32 - beq ofw_register_special - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_reg_init - _start - bl ofw_print_string - lwz %r3,144(%r1) - bl ofw_print_number - bl ofw_print_space - lwz %r3,144(%r1) - mulli %r3,%r3,4 - add %r3,%r1,%r3 - lwz %r3,0(%r3) - stw %r3,152(%r1) - bl ofw_print_number - lwz %r3,144(%r1) - addi %r3,%r3,1 - stw %r3,144(%r1) - - bl ofw_print_space - - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_reg_init - _start - bl ofw_print_string - lwz %r3,144(%r1) - bl ofw_print_number - bl ofw_print_space - lwz %r3,144(%r1) - mulli %r3,%r3,4 - add %r3,%r1,%r3 - lwz %r3,0(%r3) - stw %r3,152(%r1) - bl ofw_print_number - lwz %r3,144(%r1) - addi %r3,%r3,1 - stw %r3,144(%r1) - - b done_dump - -dump_optional: - bl ofw_print_space - bl ofw_print_space - lwz %r3,152(%r1) - lwz %r3,0(%r3) - bl ofw_print_number - bl ofw_print_space - lwz %r3,152(%r1) - lwz %r3,4(%r3) - bl ofw_print_number - bl ofw_print_space - lwz %r3,152(%r1) - lwz %r3,8(%r3) - bl ofw_print_number - bl ofw_print_space - lwz %r3,152(%r1) - lwz %r3,12(%r3) - bl ofw_print_number - bl ofw_print_space -done_dump: - bl ofw_print_eol - b ofw_register_loop - -ofw_register_special: - /* LR */ - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_reg_lr - _start - bl ofw_print_string - bl ofw_print_space - lwz %r3,128(%r1) - bl ofw_print_number - bl ofw_print_eol - - /* CR */ - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_reg_cr - _start - bl ofw_print_string - bl ofw_print_space - lwz %r3,132(%r1) - bl ofw_print_number - bl ofw_print_eol - - /* CTR */ - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_reg_ctr - _start - bl ofw_print_string - bl ofw_print_space - lwz %r3,136(%r1) - bl ofw_print_number - bl ofw_print_eol - - /* MSR */ - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_reg_msr - _start - bl ofw_print_string - bl ofw_print_space - lwz %r3,140(%r1) - bl ofw_print_number - bl ofw_print_eol - - /* Return */ - lwz %r0,128(%r1) - mtlr %r0 - - lwz %r0,0(%r1) - lwz %r2,8(%r1) - lwz %r3,12(%r1) - - lwz %r4,16(%r1) - lwz %r5,20(%r1) - lwz %r6,24(%r1) - lwz %r7,28(%r1) - - addi %r1,%r1,0xa0 - - blr - -ofw_finddevice_hook: - subi %r1,%r1,32 - stw %r3,0(%r1) - mflr %r3 - stw %r3,4(%r1) - lwz %r3,0(%r1) - bl ofw_finddevice - stw %r3,0(%r1) - lwz %r3,4(%r1) - mtlr %r3 - lwz %r3,0(%r1) - addi %r1,%r1,32 - blr - -ofw_finddevice: - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,32 - - /* Store r8, r9, lr */ - stw %r8,20(%r1) - stw %r9,24(%r1) - mflr %r8 - stw %r8,28(%r1) - - /* Get finddevice name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_finddevice_name - _start - stw %r9,0(%r1) - - /* 1 Argument and 1 return */ - li %r9,1 - stw %r9,4(%r1) - stw %r9,8(%r1) - - stw %r3,12(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - lwz %r3,16(%r1) - - /* Restore registers */ - lwz %r8,28(%r1) - mtlr %r8 - lwz %r9,24(%r1) - lwz %r8,20(%r1) - - addi %r1,%r1,32 - - /* Return */ - blr - -ofw_open: - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,32 - - /* Store r8, r9, lr */ - stw %r8,20(%r1) - stw %r9,24(%r1) - mflr %r8 - stw %r8,28(%r1) - - /* Get open name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_open_name - _start - stw %r9,0(%r1) - - /* 1 Argument and 1 return */ - li %r9,1 - stw %r9,4(%r1) - stw %r9,8(%r1) - - stw %r3,12(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - lwz %r3,16(%r1) - - /* Restore registers */ - lwz %r8,28(%r1) - mtlr %r8 - lwz %r9,24(%r1) - lwz %r8,20(%r1) - - addi %r1,%r1,32 - - /* Return */ - blr - -ofw_getprop_hook: - /* Reserve stack space: - * 32 bytes for the ofw call - * 12 bytes for r8, r9, lr - */ - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,48 - - /* Store r8, r9, lr */ - stw %r8,32(%r1) - stw %r9,36(%r1) - mflr %r8 - stw %r8,40(%r1) - - /* Get getprop name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_getprop_name - _start - stw %r9,0(%r1) - - /* 4 Argument and 1 return */ - li %r9,4 - stw %r9,4(%r1) - li %r9,1 - stw %r9,8(%r1) - - stw %r3,12(%r1) /* Package */ - stw %r4,16(%r1) /* Property */ - stw %r5,20(%r1) /* Return buffer */ - stw %r6,24(%r1) /* Buffer size */ - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - /* Workaround to a wierd crash ... not sure what causes it. - * XXX investigate me */ - bl ofw_print_nothing - - /* Return */ - lwz %r3,28(%r1) - - /* Restore registers */ - lwz %r8,40(%r1) - mtlr %r8 - lwz %r9,36(%r1) - lwz %r8,32(%r1) - - addi %r1,%r1,48 - - /* Return */ - blr - -ofw_getprop: - /* Reserve stack space: - * 32 bytes for the ofw call - * 12 bytes for r8, r9, lr - */ - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,48 - - /* Store r8, r9, lr */ - stw %r8,32(%r1) - stw %r9,36(%r1) - mflr %r8 - stw %r8,40(%r1) - - /* Get getprop name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_getprop_name - _start - stw %r9,0(%r1) - - /* 4 Argument and 1 return */ - li %r9,4 - stw %r9,4(%r1) - li %r9,1 - stw %r9,8(%r1) - - stw %r3,12(%r1) /* Package */ - stw %r4,16(%r1) /* Property */ - stw %r5,20(%r1) /* Return buffer */ - stw %r6,24(%r1) /* Buffer size */ - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - /* Return */ - lwz %r3,28(%r1) - - /* Restore registers */ - lwz %r8,40(%r1) - - mtlr %r8 - lwz %r9,36(%r1) - lwz %r8,32(%r1) - - addi %r1,%r1,48 - - /* Return */ - blr - -ofw_write: - /* Reserve stack space: - * 28 bytes for the ofw call - * 12 bytes for r8, r9, lr - */ - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,48 - - nop - - /* Store r8, r9, lr */ - stw %r8,28(%r1) - stw %r9,32(%r1) - mflr %r8 - stw %r8,36(%r1) - - /* Get write name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_write_name - _start - stw %r9,0(%r1) - - /* 3 Arguments and 1 return */ - li %r9,3 - stw %r9,4(%r1) - li %r9,1 - stw %r9,8(%r1) - - stw %r3,12(%r1) - stw %r4,16(%r1) - stw %r5,20(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - /* Return */ - lwz %r3,24(%r1) - - /* Restore registers */ - lwz %r8,36(%r1) - mtlr %r8 - lwz %r9,32(%r1) - lwz %r8,28(%r1) - - addi %r1,%r1,48 - - /* Return */ - blr - -ofw_read: - /* Reserve stack space: - * 28 bytes for the ofw call - * 12 bytes for r8, r9, lr - */ - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,48 - - nop - - /* Store r8, r9, lr */ - stw %r8,28(%r1) - stw %r9,32(%r1) - mflr %r8 - stw %r8,36(%r1) - - /* Get read name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_read_name - _start - stw %r9,0(%r1) - - /* 3 Arguments and 1 return */ - li %r9,3 - stw %r9,4(%r1) - li %r9,1 - stw %r9,8(%r1) - - stw %r3,12(%r1) - stw %r4,16(%r1) - stw %r5,20(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - /* Return */ - lwz %r3,24(%r1) - - /* Restore registers */ - lwz %r8,36(%r1) - mtlr %r8 - lwz %r9,32(%r1) - lwz %r8,28(%r1) - - addi %r1,%r1,48 - - /* Return */ - blr - -ofw_exit: - lis %r3,0xe00000@ha - addi %r3,%r3,freeldr_halt - _start - - bl ofw_print_string -/* -ofw_exit_loop: - b ofw_exit_loop -*/ - /* Load the exit name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_exit_name - _start - stw %r9,0(%r1) - - /* Zero args, zero returns */ - xor %r9,%r9,%r9 - stw %r9,4(%r1) - stw %r9,8(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - mr %r3,%r1 - - /* Fire */ - blrl - /* No return from exit */ - -ofw_child: - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,32 - - /* Store r8, r9, lr */ - stw %r8,20(%r1) - stw %r9,24(%r1) - mflr %r8 - stw %r8,28(%r1) - - /* Get child name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_child_name - _start - stw %r9,0(%r1) - - /* 1 Argument and 1 return */ - li %r9,1 - stw %r9,4(%r1) - stw %r9,8(%r1) - - stw %r3,12(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - lwz %r3,16(%r1) - - /* Restore registers */ - lwz %r8,28(%r1) - mtlr %r8 - lwz %r9,24(%r1) - lwz %r8,20(%r1) - - addi %r1,%r1,32 - - /* Return */ - blr - -ofw_peer: - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,32 - - /* Store r8, r9, lr */ - stw %r8,20(%r1) - stw %r9,24(%r1) - mflr %r8 - stw %r8,28(%r1) - - /* Get peer name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_peer_name - _start - stw %r9,0(%r1) - - /* 1 Argument and 1 return */ - li %r9,1 - stw %r9,4(%r1) - stw %r9,8(%r1) - - stw %r3,12(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - lwz %r3,16(%r1) - - /* Restore registers */ - lwz %r8,28(%r1) - mtlr %r8 - lwz %r9,24(%r1) - lwz %r8,20(%r1) - - addi %r1,%r1,32 - - /* Return */ - blr - -ofw_seek: - /* Reserve stack space ... - * 20 bytes for the ofw call, - * r8, r9, and lr */ - subi %r1,%r1,32 - - /* Store r8, r9, lr */ - stw %r8,20(%r1) - stw %r9,24(%r1) - mflr %r8 - stw %r8,28(%r1) - - /* Get peer name */ - lis %r8,0xe00000@ha - addi %r9,%r8,ofw_seek_name - _start - stw %r9,0(%r1) - - /* 3 Arguments and 1 return */ - li %r9,3 - stw %r9,4(%r1) - li %r9,1 - stw %r9,8(%r1) - - stw %r3,12(%r1) - stw %r4,16(%r1) - stw %r5,20(%r1) - - /* Load up the call address */ - lwz %r9,ofw_call_addr - _start(%r8) - mtlr %r9 - - /* Set argument */ - mr %r3,%r1 - - /* Fire */ - blrl - - lwz %r3,16(%r1) - - /* Restore registers */ - lwz %r8,28(%r1) - mtlr %r8 - lwz %r9,24(%r1) - lwz %r8,20(%r1) - - addi %r1,%r1,32 - - /* Return */ - blr - - -setup_exc: - subi %r1,%r1,32 - - stw %r3,0(%r1) - mflr %r3 - stw %r3,4(%r1) - stw %r8,8(%r1) - stw %r9,12(%r1) - stw %r10,16(%r1) - stw %r12,20(%r1) - - lis %r8,0xe00000@ha - xor %r12,%r12,%r12 - addi %r12,%r12,0x300 - addi %r9,%r8,dsi_exc - _start - addi %r10,%r8,dsi_end - _start - -copy_loop: - cmp 0,0,%r9,%r10 - beq ret_setup_exc - - mr %r3,%r12 - bl ofw_print_number - bl ofw_print_space - - lwz %r3,0(%r9) - stw %r3,0(%r12) - - bl ofw_print_number - bl ofw_print_eol - - addi %r12,%r12,4 - addi %r9,%r9,4 - b copy_loop - -ret_setup_exc: - mfmsr %r12 - andi. %r12,%r12,0xffbf - mtmsr %r12 - - lwz %r12,20(%r1) - lwz %r10,16(%r1) - lwz %r9,12(%r1) - lwz %r8,8(%r1) - - lwz %r3,4(%r1) - mtlr %r3 - lwz %r3,0(%r1) - - blr - -dsi_exc: - subi %r1,%r1,16 - - stw %r0,0(%r1) - stw %r3,4(%r1) - - mfsrr0 %r3 - addi %r3,%r3,4 - mtsrr0 %r3 - - /* mfsrr1 %r3 */ - /* ori %r3,%r3,2 */ - /* mtsrr1 %r3 */ - - lwz %r3,4(%r1) - lwz %r0,0(%r1) - - addi %r1,%r1,16 - rfi -dsi_end: - .org 0x1000 freeldr_banner: .ascii "ReactOS OpenFirmware Boot Program\r\n\0" @@ -1153,79 +143,12 @@ freeldr_banner: freeldr_halt: .ascii "ReactOS OpenFirmware Boot Program Halting\r\n\0" -freeldr_reg_init: - .ascii "r\0" -freeldr_reg_lr: - .ascii "lr \0" -freeldr_reg_cr: - .ascii "cr \0" -freeldr_reg_ctr: - .ascii "ctr\0" -freeldr_reg_msr: - .ascii "msr\0" - -ofw_call_addr: - .long 0 - ofw_memory_size: .long 0 .long 0 .long 0 .long 0 -ofw_finddevice_name: - .ascii "finddevice\0" - -ofw_getprop_name: - .ascii "getprop\0" - -ofw_write_name: - .ascii "write\0" - -ofw_read_name: - .ascii "read\0" - -ofw_exit_name: - .ascii "exit\0" - -ofw_open_name: - .ascii "open\0" - -ofw_child_name: - .ascii "child\0" - -ofw_peer_name: - .ascii "peer\0" - -ofw_seek_name: - .ascii "seek\0" - -ofw_chosen_name: - .ascii "/chosen\0" - -ofw_stdout_name: - .ascii "stdout\0" - -ofw_memory_name: - .ascii "/memory@0\0" - -ofw_reg_name: - .ascii "reg\0" - -ofw_functions: - .long ofw_finddevice_hook - .long ofw_getprop_hook - .long ofw_write - .long ofw_read - .long ofw_exit - .long ofw_print_regs - .long ofw_print_string - .long ofw_print_number - .long ofw_open - .long ofw_child - .long ofw_peer - .long ofw_seek - .org 0x2000 stack: .space 0x4000 From df179d31117bb7e41dbb9b132807a63c204e3937 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 13:03:35 +0000 Subject: [PATCH 18/81] - LE Stubs fully correct and we can move freely between freeldr and ofwboot. - Small tweaking. - Added build for ppc-le2be, cause it's needed to mangle freeldr into a correct ofwboot payload. - Some cleaning in ofwboot. svn path=/branches/powerpc/; revision=22666 --- .../boot/freeldr/bootsect/ofw_tests/ofwtest.s | 154 ------------------ reactos/boot/freeldr/bootsect/ofw_util.s | 24 +-- reactos/boot/freeldr/bootsect/ofwboot.s | 31 +--- .../boot/freeldr/freeldr/arch/powerpc/boot.s | 2 +- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 4 +- reactos/boot/freeldr/freeldr/include/of.h | 2 +- reactos/tools/ofw_interface/calls.ofw | 10 ++ reactos/tools/ofw_interface/ofw_interface.cpp | 23 +-- reactos/tools/ppc-le2be.mak | 36 ++++ reactos/tools/ppc.lost+found/link-freeldr | 9 +- reactos/tools/tools.mak | 1 + 11 files changed, 82 insertions(+), 214 deletions(-) create mode 100644 reactos/tools/ppc-le2be.mak diff --git a/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s b/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s index 131d20d5aff..aa0108605ce 100644 --- a/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s +++ b/reactos/boot/freeldr/bootsect/ofw_tests/ofwtest.s @@ -5,12 +5,8 @@ _start: .long 0 .long 0 - .globl ofw_functions_addr .globl ofw_dumpregs -ofw_functions_addr: - .long ofw_functions - .globl _begin _begin: sync @@ -30,158 +26,8 @@ _begin: foo: b foo - - .align 4 -call_freeldr: - /* Get the address of the functions list -- - * Note: - * Because of little endian switch we must use an even number of - * instructions here.. Pad with a nop if needed. */ - mfmsr %r10 - ori %r10,%r10,1 - mtmsr %r10 - - nop - - /* Note that this is little-endian from here on */ - blr - nop - - .align 4 - -call_ofw: - /* R3 has the function offset to call (n * 4) - * Other arg registers are unchanged. - * Note that these 4 instructions are in reverse order due to - * little-endian convention */ - andi. %r0,%r0,65534 - mfmsr %r0 - mtmsr %r0 - /* Now normal ordering resumes */ - subi %r1,%r1,0x100 - - stw %r8,4(%r1) - stw %r9,8(%r1) - stw %r10,12(%r1) - mflr %r8 - stw %r8,16(%r1) - - lis %r10,0xe00000@ha - add %r9,%r3,%r10 - lwz %r3,ofw_functions_addr - _start@l(%r9) - lwz %r3,0(%r3) - mtctr %r3 - - mr %r3,%r4 - mr %r4,%r5 - mr %r5,%r6 - mr %r6,%r7 - mr %r7,%r8 - - /* Goto the swapped function */ - bctrl - - lwz %r8,16(%r1) - mtlr %r8 - - lwz %r8,4(%r1) - lwz %r9,8(%r1) - lwz %r10,12(%r1) - - addi %r1,%r1,0x100 - /* Ok, go back to little endian */ - mfmsr %r0 - ori %r0,%r0,1 - mtmsr %r0 - - /* Note that this is little-endian from here on */ - blr - nop - -zero_registers: - xor %r2,%r2,%r2 - mr %r0,%r2 - mr %r3,%r2 - - mr %r4,%r2 - mr %r5,%r2 - mr %r6,%r2 - mr %r7,%r2 - - mr %r8,%r2 - mr %r9,%r2 - mr %r10,%r2 - mr %r11,%r2 - - mr %r12,%r2 - mr %r13,%r2 - mr %r14,%r2 - mr %r15,%r2 - - mr %r12,%r2 - mr %r13,%r2 - mr %r14,%r2 - mr %r15,%r2 - - mr %r16,%r2 - mr %r17,%r2 - mr %r18,%r2 - mr %r19,%r2 - - mr %r20,%r2 - mr %r21,%r2 - mr %r22,%r2 - mr %r23,%r2 - - mr %r24,%r2 - mr %r25,%r2 - mr %r26,%r2 - mr %r27,%r2 - - mr %r28,%r2 - mr %r29,%r2 - mr %r30,%r2 - mr %r31,%r2 - - blr .org 0x1000 -freeldr_banner: - .ascii "ReactOS OpenFirmware Boot Program\r\n\0" - -freeldr_halt: - .ascii "ReactOS OpenFirmware Boot Program Halting\r\n\0" - -freeldr_reg_init: - .ascii "r\0" -freeldr_reg_lr: - .ascii "lr \0" -freeldr_reg_cr: - .ascii "cr \0" -freeldr_reg_ctr: - .ascii "ctr\0" -freeldr_reg_msr: - .ascii "msr\0" - -ofw_memory_size: - .long 0 - .long 0 - .long 0 - .long 0 - -ofw_chosen_name: - .ascii "/chosen\0" - -ofw_stdout_name: - .ascii "stdout\0" - -ofw_memory_name: - .ascii "/memory@0\0" - -ofw_reg_name: - .ascii "reg\0" - - .org 0x2000 stack: .space 0x4000 diff --git a/reactos/boot/freeldr/bootsect/ofw_util.s b/reactos/boot/freeldr/bootsect/ofw_util.s index 036a9c6fc11..d4abe5e726f 100644 --- a/reactos/boot/freeldr/bootsect/ofw_util.s +++ b/reactos/boot/freeldr/bootsect/ofw_util.s @@ -12,24 +12,23 @@ call_freeldr: * instructions here.. Pad with a nop if needed. */ mfmsr %r10 ori %r10,%r10,1 - mtmsr %r10 - nop + mtmsr %r10 /* Note that this is little-endian from here on */ blr nop .align 4 - call_ofw: /* R3 has the function offset to call (n * 4) * Other arg registers are unchanged. * Note that these 4 instructions are in reverse order due to * little-endian convention */ - andi. %r0,%r0,65534 - mfmsr %r0 - mtmsr %r0 + subi %r20,%r20,1 + mfmsr %r20 + mtmsr %r20 + nop /* Now normal ordering resumes */ subi %r1,%r1,0x100 @@ -40,10 +39,11 @@ call_ofw: stw %r8,16(%r1) lis %r10,0xe00000@ha - add %r9,%r3,%r10 - lwz %r3,ofw_functions_addr - _start@l(%r9) - lwz %r3,0(%r3) - mtctr %r3 + addi %r8,%r10,ofw_functions_addr@l + lwz %r9,0(%r8) + add %r8,%r3,%r9 + lwz %r9,0(%r8) + mtctr %r9 mr %r3,%r4 mr %r4,%r5 @@ -63,8 +63,12 @@ call_ofw: addi %r1,%r1,0x100 /* Ok, go back to little endian */ + + .align 4 mfmsr %r0 ori %r0,%r0,1 + + nop mtmsr %r0 /* Note that this is little-endian from here on */ diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index 70a55075f59..3e69c82ae75 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -49,10 +49,8 @@ _begin: lis %r5,0x8000@ha addi %r5,%r5,0x8000@l - bl ofw_dumpregs - + bl ofw_dumpregs bl copy_bits - bl zero_registers /* Zero CTR */ @@ -63,32 +61,11 @@ _begin: mtlr %r3 - lis %r3,call_freeldr@ha - addi %r3,%r3,call_freeldr - _start + lis %r3,call_ofw@ha + addi %r3,%r3,call_ofw - _start - blr + b call_freeldr -/* - * lifted from ppc/boot/openfirmware/misc.S - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation ; either version - * 2 of the License, or (at your option) any later version. - */ - -/* - * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to - * the address given as the 1st argument. - */ -setup_bats: - xor 3,3,3 - - sync - isync - blr - zero_registers: xor %r2,%r2,%r2 mr %r0,%r2 diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s index a507daafab4..30c1f1c3e18 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s @@ -1,3 +1,3 @@ .extern PpcInit _start: - b PpcInit+4 + b PpcInit diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 674a4b4ac0d..90895d2b4ad 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -280,10 +280,12 @@ void PpcInit( of_proxy the_ofproxy ) { int len; ofproxy = the_ofproxy; + ofw_print_string("Made it into freeldr LE code ... bootstrap complete\n"); + chosen_package = ofw_finddevice( "/chosen" ); ofw_getprop( chosen_package, "stdin", - &stdin_handle, sizeof(stdin_handle) ); + (char *)&stdin_handle, sizeof(stdin_handle) ); stdin_handle = REV(stdin_handle); diff --git a/reactos/boot/freeldr/freeldr/include/of.h b/reactos/boot/freeldr/freeldr/include/of.h index 3eb431f84df..22170c971df 100644 --- a/reactos/boot/freeldr/freeldr/include/of.h +++ b/reactos/boot/freeldr/freeldr/include/of.h @@ -10,7 +10,7 @@ #include typedef int (*of_proxy) - ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4 ); + ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5 ); typedef long jmp_buf[100]; extern of_proxy ofproxy; extern void le_swap( void *begin, void *end, void *dest ); diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index 5a7352e04bf..2300f0632e4 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -9,6 +9,16 @@ exit 0 0 child 1 1 int int peer 1 1 int int seek 2 1 int int int +# MMU methods +# claim (virt size align -- base) +claim 3 1 int int int int +# release (virt size --) +release 2 0 int int +# map (plo phi virt size mode --) +map 5 0 int int int int int +unmap 2 0 int int +modify 3 0 int int int +translate 4 1 int int int int int # Convenience functions that interact closely with OFW (written in BE asm) -dumpregs 0 0 -print_string 1 0 char* diff --git a/reactos/tools/ofw_interface/ofw_interface.cpp b/reactos/tools/ofw_interface/ofw_interface.cpp index 80998c1a20d..495bb8e03ff 100644 --- a/reactos/tools/ofw_interface/ofw_interface.cpp +++ b/reactos/tools/ofw_interface/ofw_interface.cpp @@ -134,17 +134,15 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { for( i = 0; i < args; i++ ) { if( need_swap(argtypes[i]) ) { - std::string len; + le_stub << "\tint len" << i << " = "; if( have_len(argtypes[i]).size() ) - len = have_len(argtypes[i]); + le_stub << have_len(argtypes[i]) << ";\n"; else { - std::ostringstream oss; - oss << "strlen(arg" << i << ")"; - len = oss.str(); + le_stub << "strlen(arg" << i << ");\n"; } le_stub << "\tle_swap(" << "arg" << i << "," - << "arg" << i << "+" << len << "," + << "arg" << i << "+len" << i << "," << "arg" << i << ");\n"; } } @@ -154,7 +152,7 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { le_stub << "ofproxy(" << (wrapper.ctindex * 4); - for( i = 0; i < 4; i++ ) { + for( i = 0; i < 5; i++ ) { if( i < args ) le_stub << ",(void *)arg" << i; else le_stub << ",NULL"; } @@ -163,17 +161,9 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { for( i = args-1; i >= 0; i-- ) { if( need_swap(argtypes[i]) ) { - std::string len; - if( have_len(argtypes[i]).size() ) - len = have_len(argtypes[i]); - else { - std::ostringstream oss; - oss << "strlen(arg" << i << ")"; - len = oss.str(); - } le_stub << "\tle_swap(" << "arg" << i << "," - << "arg" << i << "+" << len << "," + << "arg" << i << "+len" << i << "," << "arg" << i << ");\n"; } } @@ -242,6 +232,7 @@ int main( int argc, char **argv ) { out << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n" << "\t.section .text\n" + << "\t.align 4\n" << "\t.globl _start\n" << "\t.globl ofw_call_addr\n" << "ofw_call_addr:\n" diff --git a/reactos/tools/ppc-le2be.mak b/reactos/tools/ppc-le2be.mak new file mode 100644 index 00000000000..1a32f1505e7 --- /dev/null +++ b/reactos/tools/ppc-le2be.mak @@ -0,0 +1,36 @@ +PPC_LE2BE_BASE = $(TOOLS_BASE) +PPC_LE2BE_BASE_ = $(PPC_LE2BE_BASE)$(SEP) + +PPC_LE2BE_INT = $(INTERMEDIATE_)$(PPC_LE2BE_BASE) +PPC_LE2BE_INT_ = $(PPC_LE2BE_INT)$(SEP) +PPC_LE2BE_OUT = $(OUTPUT_)$(PPC_LE2BE_BASE) +PPC_LE2BE_OUT_ = $(PPC_LE2BE_OUT)$(SEP) + +PPC_LE2BE_TARGET = \ + $(EXEPREFIX)$(PPC_LE2BE_OUT_)ppc-le2be$(EXEPOSTFIX) + +PPC_LE2BE_SOURCES = \ + $(PPC_LE2BE_BASE_)ppc-le2be.c + +PPC_LE2BE_OBJECTS = \ + $(addprefix $(INTERMEDIATE_), $(PPC_LE2BE_SOURCES:.c=.o)) + +PPC_LE2BE_HOST_CFLAGS = $(TOOLS_CFLAGS) + +PPC_LE2BE_HOST_LFLAGS = $(TOOLS_LFLAGS) + +.PHONY: ppc-le2be +ppc-le2be: $(PPC_LE2BE_TARGET) + +$(PPC_LE2BE_TARGET): $(PPC_LE2BE_OBJECTS) | $(PPC_LE2BE_OUT) + $(ECHO_LD) + ${host_gcc} $(PPC_LE2BE_OBJECTS) $(PPC_LE2BE_HOST_LFLAGS) -o $@ + +$(PPC_LE2BE_INT_)ppc-le2be.o: $(PPC_LE2BE_BASE_)ppc-le2be.c | $(PPC_LE2BE_INT) + $(ECHO_CC) + ${host_gcc} $(PPC_LE2BE_HOST_CFLAGS) -c $< -o $@ + +.PHONY: ppc-le2be_clean +ppc-le2be_clean: + -@$(rm) $(PPC_LE2BE_TARGET) $(PPC_LE2BE_OBJECTS) 2>$(NUL) +clean: ppc-le2be_clean diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr index 56a2484d90c..e52feb49aa3 100755 --- a/reactos/tools/ppc.lost+found/link-freeldr +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -1,8 +1,9 @@ -#!/bin/sh +#!/bin/sh -v export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a -objcopy -O binary --only-section=.text --only-section=.data --only-section=.bss freeldr.elf freeldr.tmp +objcopy -O binary --only-section=.text --only-section=.data --only-section=.bss freeldr.elf freeldr.tmp.le +output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload -reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s -ld -EB -Ttext 0xe00000 -e _begin -o ofwldr ofwboot.o ofwldr.payload +reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s boot/freeldr/bootsect/ofw_util.s boot/freeldr/bootsect/ofw.s +ld -EB -Ttext 0xe00000 -Tdata 0xe17000 -e _begin -o ofwldr ofwboot.o ofwldr.payload diff --git a/reactos/tools/tools.mak b/reactos/tools/tools.mak index e7b7c7e8a2d..05642f4ef96 100644 --- a/reactos/tools/tools.mak +++ b/reactos/tools/tools.mak @@ -53,6 +53,7 @@ include tools/mkhive/mkhive.mak include tools/nci/nci.mak include tools/rbuild/rbuild.mak include tools/ofw_interface/ofw_interface.mak +include tools/ppc-le2be.mak include tools/unicode/unicode.mak include tools/widl/widl.mak include tools/winebuild/winebuild.mak From ada2c0684ccf431543f0a283c4a1a6e1713303c0 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 27 Jun 2006 23:47:38 +0000 Subject: [PATCH 19/81] Working up to it. We get the first banner. svn path=/branches/powerpc/; revision=22669 --- reactos/boot/freeldr/freeldr/freeldr_arch.rbuild | 3 +++ reactos/tools/ppc.lost+found/link-freeldr | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild index 0fef874b74d..d89713d604a 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild @@ -61,6 +61,9 @@ -fno-inline -fno-zero-initialized-in-bss -Os + -fPIC + -mno-toc + -meabi boot.s ofw.c mach.c diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr index e52feb49aa3..296c1566317 100755 --- a/reactos/tools/ppc.lost+found/link-freeldr +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -2,7 +2,7 @@ export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a -objcopy -O binary --only-section=.text --only-section=.data --only-section=.bss freeldr.elf freeldr.tmp.le +objcopy -O binary freeldr.elf freeldr.tmp.le output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s boot/freeldr/bootsect/ofw_util.s boot/freeldr/bootsect/ofw.s From 87b0390e5521894b614a8da9df8dd0f3d5f44f88 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 28 Jun 2006 01:14:23 +0000 Subject: [PATCH 20/81] Woot. We're deep into freeldr. Printf is working, etc. Forgot .bss. TODO: retrieve .bss size in build step. svn path=/branches/powerpc/; revision=22670 --- reactos/boot/freeldr/bootsect/ofwboot.s | 2 ++ reactos/boot/freeldr/freeldr/arch/powerpc/mach.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index 3e69c82ae75..62ced40d7de 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -34,7 +34,9 @@ _begin: addi %r4,%r4,_binary_freeldr_tmp_end@l lis %r5,_binary_freeldr_tmp_start@ha addi %r5,%r5,_binary_freeldr_tmp_start@l + /* Make sufficient room for .bss */ sub %r4,%r4,%r5 + addi %r4,%r4,0x6000 xor %r5,%r5,%r5 li %r5,0x1000 diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 90895d2b4ad..7c5c733f398 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -284,14 +284,26 @@ void PpcInit( of_proxy the_ofproxy ) { chosen_package = ofw_finddevice( "/chosen" ); + ofw_print_string("Chosen package: "); + ofw_print_number(chosen_package); + ofw_print_string("\n"); + ofw_getprop( chosen_package, "stdin", (char *)&stdin_handle, sizeof(stdin_handle) ); - stdin_handle = REV(stdin_handle); + ofw_print_string("ofw_getprop done\n"); + + /* stdin_handle = REV(stdin_handle); */ + + ofw_print_string("Populating MachVtbl: "); + ofw_print_number((int)&MachVtbl); + ofw_print_string("\n"); MachVtbl.ConsPutChar = PpcPutChar; MachVtbl.ConsKbHit = PpcConsKbHit; MachVtbl.ConsGetCh = PpcConsGetCh; + + ofw_print_string("About to do printf\n"); printf( "stdin_handle is %x\n", stdin_handle ); From 6fa7ef7aecc78f35cfa8df8c90d765eac5e370a6 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 28 Jun 2006 22:26:04 +0000 Subject: [PATCH 21/81] Fixed actual bug in freeldr printf. Probably used to depend on a bug in _itoa, which was later made compliant. I'm guessing that this went unnoticed because nobody used freeldr's printf very often. svn path=/branches/powerpc/; revision=22680 --- reactos/boot/freeldr/freeldr/ui/tui.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/ui/tui.c b/reactos/boot/freeldr/freeldr/ui/tui.c index 8b80f3eab05..ed6ad7bd78a 100644 --- a/reactos/boot/freeldr/freeldr/ui/tui.c +++ b/reactos/boot/freeldr/freeldr/ui/tui.c @@ -22,6 +22,8 @@ PVOID TextVideoBuffer = NULL; extern BOOLEAN UiDrawTime; extern BOOLEAN UiMinimal; +extern void ofw_print_string(const char *); +extern void ofw_print_number(int x); /* * printf() - prints formatted text to stdout @@ -43,19 +45,20 @@ int printf(const char *format, ... ) { switch (c = *(format++)) { - case 'd': case 'u': case 'x': - if (c == 'x') - *_itoa(va_arg(ap, unsigned long), str, 16) = 0; - else - *_itoa(va_arg(ap, unsigned long), str, 10) = 0; + case 'd': case 'u': case 'x': { + unsigned long x = va_arg(ap, unsigned long); + if (c == 'x') + _itoa(x, str, 16); + else + _itoa(x, str, 10); ptr = str; while (*ptr) { - MachConsPutChar(*(ptr++)); + MachConsPutChar(*(ptr++)); } - break; + } break; case 'c': MachConsPutChar((va_arg(ap,int))&0xff); break; From d763a47abc36ab98a63adfe7d67d8f8c863a91a6 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 28 Jun 2006 22:55:52 +0000 Subject: [PATCH 22/81] Claim a workspace using openfirmware. svn path=/branches/powerpc/; revision=22681 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 7c5c733f398..60f1a6f6339 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -20,6 +20,8 @@ #include "machine.h" #include "of.h" +#define TOTAL_HEAP_NEEDED (16 * 1024 * 1024) /* 16 megs */ + extern void BootMain( char * ); extern char *GetFreeLoaderVersionString(); of_proxy ofproxy; @@ -162,24 +164,38 @@ VOID PpcVideoSync() { VOID PpcVideoPrepareForReactOS() { printf( "PrepareForReactOS\n"); } -/* XXX FIXME: - * According to the linux people (this is backed up by my own experience), - * the memory object in older ofw does not do getprop right. - * - * The "right" way is to probe the pci bridge. *sigh* +/* + * Get memory the proper openfirmware way */ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize ) { - printf("GetMemoryMap(chosen=%x)\n", chosen_package); + int i, memhandle, returned, total = 0, num_mem = 0; + int memdata[256]; - BiosMemoryMap[0].Type = MEMTYPE_USABLE; - BiosMemoryMap[0].BaseAddress = 0; - BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */ + ofw_getprop(chosen_package, "memory", + (char *)&memhandle, sizeof(memhandle)); + returned = ofw_getprop(memhandle, "available", + (char *)memdata, sizeof(memdata)); - printf( "Returning memory map (%dk total)\n", - (int)BiosMemoryMap[0].Length / 1024 ); + /* We need to leave some for open firmware. Let's claim up to 16 megs + * for now */ - return 1; + for( i = 0; i < returned / sizeof(int) && !num_mem; i += 2 ) { + BiosMemoryMap[num_mem].Type = MEMTYPE_USABLE; + BiosMemoryMap[num_mem].BaseAddress = memdata[i]; + BiosMemoryMap[num_mem].Length = memdata[i+1]; + if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED ) { + BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED; + ofw_claim(BiosMemoryMap[num_mem].BaseAddress, + BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */ + total += BiosMemoryMap[0].Length; + num_mem++; + } + } + + printf( "Returning memory map (%dk total)\n", total / 1024 ); + + return num_mem; } /* Strategy: @@ -284,27 +300,15 @@ void PpcInit( of_proxy the_ofproxy ) { chosen_package = ofw_finddevice( "/chosen" ); - ofw_print_string("Chosen package: "); - ofw_print_number(chosen_package); - ofw_print_string("\n"); - ofw_getprop( chosen_package, "stdin", (char *)&stdin_handle, sizeof(stdin_handle) ); - ofw_print_string("ofw_getprop done\n"); - /* stdin_handle = REV(stdin_handle); */ - ofw_print_string("Populating MachVtbl: "); - ofw_print_number((int)&MachVtbl); - ofw_print_string("\n"); - MachVtbl.ConsPutChar = PpcPutChar; MachVtbl.ConsKbHit = PpcConsKbHit; MachVtbl.ConsGetCh = PpcConsGetCh; - ofw_print_string("About to do printf\n"); - printf( "stdin_handle is %x\n", stdin_handle ); MachVtbl.VideoClearScreen = PpcVideoClearScreen; From f04af18b2a516c8286302d91e3964d79938e8d27 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 29 Jun 2006 11:07:46 +0000 Subject: [PATCH 23/81] Added method call interface, mmu translation methods. svn path=/branches/powerpc/; revision=22687 --- reactos/tools/ofw_interface/calls.ofw | 10 +- reactos/tools/ofw_interface/ofw_interface.cpp | 165 +++++++++++++----- 2 files changed, 126 insertions(+), 49 deletions(-) diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index 2300f0632e4..31f1b8d0bd8 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -14,12 +14,12 @@ seek 2 1 int int int claim 3 1 int int int int # release (virt size --) release 2 0 int int -# map (plo phi virt size mode --) -map 5 0 int int int int int -unmap 2 0 int int -modify 3 0 int int int -translate 4 1 int int int int int +# Declare the call-method BE function ++call-method 0 0 # Convenience functions that interact closely with OFW (written in BE asm) -dumpregs 0 0 -print_string 1 0 char* -print_number 1 0 int +# MMU Methods +@phys2virt!translate 4 1 int int int int&0 int +@virt2phys!translate 2 1 int int&1 int diff --git a/reactos/tools/ofw_interface/ofw_interface.cpp b/reactos/tools/ofw_interface/ofw_interface.cpp index 495bb8e03ff..1ecf0221933 100644 --- a/reactos/tools/ofw_interface/ofw_interface.cpp +++ b/reactos/tools/ofw_interface/ofw_interface.cpp @@ -7,7 +7,7 @@ class ofw_wrappers { public: - int base, ctindex; + int base, ctindex, method_ctindex; std::string functions; std::string names; std::string calltable; @@ -15,6 +15,49 @@ public: std::string of_call; }; +class vartype { +public: + vartype( const std::string &typestr ) { + size_t amp = typestr.find('&'); + size_t col = typestr.find(':'); + if( amp != std::string::npos ) { + if( col > amp && col != std::string::npos ) + lit_value = typestr.substr(amp+1,col-amp+1); + else lit_value = typestr.substr(amp+1); + } + if( col != std::string::npos ) { + if( amp > col && amp != std::string::npos ) + len = typestr.substr(col+1,amp-col+1); + else len = typestr.substr(col+1); + } + + if( amp != std::string::npos && amp < col ) col = amp; + if( col == std::string::npos ) col = typestr.size(); + c_type = typestr.substr(0,col); + } + + vartype( const vartype &other ) + : c_type(other.c_type), + len(other.len), + lit_value(other.lit_value) { + } + + vartype &operator = ( const vartype &other ) { + c_type = other.c_type; + len = other.len; + lit_value = other.lit_value; + return *this; + } + + bool need_swap() const { + return c_type.find('*') != std::string::npos; + } + + std::string c_type; + std::string len; + std::string lit_value; +}; + std::string uppercase( const std::string &toucase ) { std::vector ucase_work(toucase.size()); for( size_t i = 0; i < toucase.size(); i++ ) { @@ -37,45 +80,57 @@ int round_up( int x, int factor ) { return (x + (factor - 1)) & ~(factor - 1); } -std::string c_type( const std::string &intype ) { - size_t colon = intype.find(':'); - if( colon != std::string::npos ) return intype.substr(0,colon); - else if( intype.size() ) return intype; - else return "void"; -} - -std::string have_len( const std::string &intype ) { - size_t colon = intype.find(':'); - if( colon != std::string::npos ) return intype.substr(colon+1); - else return ""; -} - -bool need_swap( const std::string &intype ) { - return intype.find('*') != std::string::npos; -} - void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { std::istringstream iss(line); - bool make_function = true; - std::string name, argtype, rettype, c_rettype; - std::vector argtypes; - int args, rets, i, local_offset, total_stack; + bool make_function = true, method_call = false, make_stub = true, comma; + std::string name, nametext, argtype, rettype; + std::vector argtypes; + int args, rets, i, local_offset, total_stack, userarg_start = 0; + size_t f; std::ostringstream function, ct_csource, le_stub, of_call; iss >> name >> args >> rets; if( !name.size() ) return; + + if( (f = name.find('!')) != std::string::npos ) { + nametext = name.substr(f+1); + name = name.substr(0,f); + } if( name[0] == '-' ) { name = name.substr(1); make_function = false; } + if( name[0] == '+' ) { + name = name.substr(1); + make_stub = false; + } + if( name[0] == '@' ) { + name = name.substr(1); + method_call = true; + make_function = false; + } + + if( !nametext.size() ) nametext = name; + + for( i = 1; i < (int)name.size(); i++ ) + if( name[i] == '-' ) name[i] = '_'; + + if( nametext == "call-method" ) + wrapper.method_ctindex = wrapper.ctindex; for( i = 0; i < args; i++ ) { iss >> argtype; - argtypes.push_back(argtype); + argtypes.push_back(vartype(argtype)); + } + + if( method_call ) { + userarg_start = 1; + args += 2; } iss >> rettype; + if( !rettype.size() ) rettype = "void"; local_offset = (3 + rets + args) * 4; total_stack = round_up(12 + local_offset, 16); @@ -118,25 +173,42 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { << "\taddi %r1,%r1," << total_stack << "\n" << "\tblr\n"; - c_rettype = c_type(rettype); + if( method_call ) { + argtypes.insert(argtypes.begin(),vartype("int")); + argtypes.insert(argtypes.begin(),vartype("char*")); + } - le_stub << c_rettype << " ofw_" << name << "("; - for( i = 0; i < args; i++ ) { - if( i ) le_stub << ","; - le_stub << c_type(argtypes[i]) << " arg" << i; + le_stub << rettype << " ofw_" << name << "("; + + comma = false; + for( i = userarg_start; i < args; i++ ) { + if( !argtypes[i].lit_value.size() ) { + if( !comma ) comma = true; else le_stub << ","; + le_stub << argtypes[i].c_type << " arg" << i; + } } le_stub << ")"; of_call << le_stub.str() << ";\n"; le_stub << " {\n"; - if( c_rettype != "void" ) - le_stub << "\t" << c_rettype << " ret;\n"; + if( rettype != "void" ) + le_stub << "\t" << rettype << " ret;\n"; + + if( method_call ) { + le_stub << "\tchar arg0[" + << round_up(nametext.size()+1,8) + << "] = \"" << nametext << "\";\n"; + } for( i = 0; i < args; i++ ) { - if( need_swap(argtypes[i]) ) { + if( argtypes[i].lit_value.size() ) { + le_stub << "\t" << argtypes[i].c_type << " arg" << i << " = " + << argtypes[i].lit_value << ";\n"; + } + if( argtypes[i].need_swap() ) { le_stub << "\tint len" << i << " = "; - if( have_len(argtypes[i]).size() ) - le_stub << have_len(argtypes[i]) << ";\n"; + if( argtypes[i].len.size() ) + le_stub << argtypes[i].len << ";\n"; else { le_stub << "strlen(arg" << i << ");\n"; } @@ -148,11 +220,12 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { } le_stub << "\t"; - if( c_rettype != "void" ) le_stub << "ret = (" << c_rettype << ")"; + if( rettype != "void" ) le_stub << "ret = (" << rettype << ")"; - le_stub << "ofproxy(" << (wrapper.ctindex * 4); + le_stub << "ofproxy(" << + (method_call ? (wrapper.method_ctindex * 4) : (wrapper.ctindex * 4)); - for( i = 0; i < 5; i++ ) { + for( i = 0; i < 6; i++ ) { if( i < args ) le_stub << ",(void *)arg" << i; else le_stub << ",NULL"; } @@ -160,7 +233,7 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { le_stub << ");\n"; for( i = args-1; i >= 0; i-- ) { - if( need_swap(argtypes[i]) ) { + if( argtypes[i].need_swap() ) { le_stub << "\tle_swap(" << "arg" << i << "," << "arg" << i << "+len" << i << "," @@ -168,17 +241,21 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) { } } - if( c_rettype != "void" ) + if( rettype != "void" ) le_stub << "\treturn ret;\n"; le_stub << "}\n"; if( make_function ) wrapper.functions += function.str(); - wrapper.le_stubs += le_stub.str(); - wrapper.of_call += of_call.str(); - wrapper.names += name + "_ofw_name:\n\t.asciz \"" + name + "\"\n"; - wrapper.calltable += std::string("\t.long ofw_") + name + "\n"; - wrapper.ctindex++; + if( make_stub ) { + wrapper.le_stubs += le_stub.str(); + wrapper.of_call += of_call.str(); + } + if( !method_call ) { + wrapper.names += name + "_ofw_name:\n\t.asciz \"" + nametext + "\"\n"; + wrapper.calltable += std::string("\t.long ofw_") + name + "\n"; + wrapper.ctindex++; + } } int main( int argc, char **argv ) { @@ -239,7 +316,7 @@ int main( int argc, char **argv ) { << "\t.long 0\n" << "\n/* Function Wrappers */\n\n" << wrappers.functions - << "\t/* Function Names */\n\n" + << "\n/* Function Names */\n\n" << wrappers.names << "\n/* Function Call Table for Freeldr */\n\n" << "ofw_functions:\n" From 746211fbde3c98ca5f508480b8b9b1036ec8aec0 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 29 Aug 2006 06:28:13 +0000 Subject: [PATCH 24/81] Fixed support for disk and filesystem. We're reading files normally. Now working on display modes and character input. svn path=/branches/powerpc/; revision=23764 --- reactos/boot/freeldr/bootsect/ofw_util.s | 3 +- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 37 +++++++++++++++---- reactos/boot/freeldr/freeldr/fs/fs.c | 13 +++++++ reactos/boot/freeldr/freeldr/include/arch.h | 6 +++ reactos/boot/freeldr/freeldr/include/of.h | 2 +- reactos/tools/ofw_interface/calls.ofw | 2 +- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/reactos/boot/freeldr/bootsect/ofw_util.s b/reactos/boot/freeldr/bootsect/ofw_util.s index d4abe5e726f..7e0aa840bc2 100644 --- a/reactos/boot/freeldr/bootsect/ofw_util.s +++ b/reactos/boot/freeldr/bootsect/ofw_util.s @@ -50,7 +50,8 @@ call_ofw: mr %r5,%r6 mr %r6,%r7 mr %r7,%r8 - + mr %r8,%r9 + /* Goto the swapped function */ bctrl diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 60f1a6f6339..c2097a07be1 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -169,11 +169,16 @@ VOID PpcVideoPrepareForReactOS() { */ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize ) { - int i, memhandle, returned, total = 0, num_mem = 0; + int i, memhandle, mmuhandle, returned, total = 0, num_mem = 0; int memdata[256]; + printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize); + ofw_getprop(chosen_package, "memory", (char *)&memhandle, sizeof(memhandle)); + ofw_getprop(chosen_package, "mmu", + (char *)&mmuhandle, sizeof(mmuhandle)); + returned = ofw_getprop(memhandle, "available", (char *)memdata, sizeof(memdata)); @@ -188,6 +193,10 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED; ofw_claim(BiosMemoryMap[num_mem].BaseAddress, BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */ + printf("virt2phys(%x)->%x\n", + BiosMemoryMap[num_mem].BaseAddress, + ofw_virt2phys + (mmuhandle, BiosMemoryMap[num_mem].BaseAddress)); total += BiosMemoryMap[0].Length; num_mem++; } @@ -237,7 +246,7 @@ BOOLEAN PpcDiskBootingFromFloppy(VOID) { } BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber, - ULONG SectorCount, PVOID Buffer ) { + ULONG SectorCount, PVOID Buffer ) { int rlen = 0; if( part_handle == -1 ) { @@ -254,11 +263,13 @@ BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber, return FALSE; } - if( ofw_seek( part_handle, SectorNumber * 512 ) ) { - printf("Seek to %x failed\n", SectorNumber * 512); + if( ofw_seek( part_handle, + (ULONG)(SectorNumber >> 25), + (ULONG)((SectorNumber * 512) & 0xffffffff) ) ) { + printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512)); return FALSE; } - rlen = ofw_read( part_handle, Buffer, SectorCount * 512 ); + rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) ); return rlen > 0; } @@ -293,15 +304,25 @@ VOID PpcHwDetect() { typedef unsigned int uint32_t; void PpcInit( of_proxy the_ofproxy ) { - int len; + int len, stdin_handle_chosen; ofproxy = the_ofproxy; - ofw_print_string("Made it into freeldr LE code ... bootstrap complete\n"); + ofw_print_string("Freeldr PowerPC Init\n"); chosen_package = ofw_finddevice( "/chosen" ); + ofw_print_string("Freeldr: chosen_package is "); + ofw_print_number(chosen_package); + ofw_print_string("\n"); + ofw_getprop( chosen_package, "stdin", - (char *)&stdin_handle, sizeof(stdin_handle) ); + (char *)&stdin_handle_chosen, sizeof(stdin_handle_chosen) ); + + ofw_print_string("Freeldr: stdin_handle is "); + ofw_print_number(stdin_handle_chosen); + ofw_print_string("\n"); + + stdin_handle = stdin_handle_chosen; /* stdin_handle = REV(stdin_handle); */ diff --git a/reactos/boot/freeldr/freeldr/fs/fs.c b/reactos/boot/freeldr/freeldr/fs/fs.c index f4595a637df..f7116b9bca0 100644 --- a/reactos/boot/freeldr/freeldr/fs/fs.c +++ b/reactos/boot/freeldr/freeldr/fs/fs.c @@ -27,6 +27,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////// ULONG FsType = 0; // Type of filesystem on boot device, set by FsOpenVolume() +PVOID FsStaticBufferDisk = 0, FsStaticBufferData = 0; ///////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS @@ -51,8 +52,20 @@ static BOOLEAN FsOpenVolume(ULONG DriveNumber, ULONGLONG StartSector, ULONGLONG { CHAR ErrorText[80]; + printf("FsOpenVolume: (disk=%d,start=%d,count=%d,type=%d)\n", + DriveNumber, StartSector, SectorCount, Type); + FsType = Type; + if( !FsStaticBufferDisk ) + FsStaticBufferDisk = MmAllocateMemory( 0x20000 ); + if( !FsStaticBufferDisk ) + { + FileSystemError("could not allocate filesystem static buffer"); + return FALSE; + } + FsStaticBufferData = ((PCHAR)FsStaticBufferDisk) + 0x10000; + switch (FsType) { case FS_FAT: diff --git a/reactos/boot/freeldr/freeldr/include/arch.h b/reactos/boot/freeldr/freeldr/include/arch.h index 037f1cf4310..c92c4c91e56 100644 --- a/reactos/boot/freeldr/freeldr/include/arch.h +++ b/reactos/boot/freeldr/freeldr/include/arch.h @@ -34,11 +34,17 @@ #define STACK16ADDR 0x7000 /* The 16-bit stack top will be at 0000:7000 */ #define STACK32ADDR 0x78000 /* The 32-bit stack top will be at 7000:8000, or 0x78000 */ +#ifdef _M_IX86 #define BIOSCALLBUFFER 0x78000 /* Buffer to store temporary data for any Int386() call */ #define BIOSCALLBUFSEGMENT 0x7800 /* Buffer to store temporary data for any Int386() call */ #define BIOSCALLBUFOFFSET 0x0000 /* Buffer to store temporary data for any Int386() call */ #define FILESYSBUFFER 0x80000 /* Buffer to store file system data (e.g. cluster buffer for FAT) */ #define DISKREADBUFFER 0x90000 /* Buffer to store data read in from the disk via the BIOS */ +#elif defined(_M_PPC) +extern PVOID FsStaticBufferDisk, FsStaticBufferData; +#define DISKREADBUFFER FsStaticBufferDisk +#define FILESYSBUFFER FsStaticBufferData +#endif /* Makes "x" a global variable or label */ #define EXTERN(x) .global x; x: diff --git a/reactos/boot/freeldr/freeldr/include/of.h b/reactos/boot/freeldr/freeldr/include/of.h index 22170c971df..8f967556025 100644 --- a/reactos/boot/freeldr/freeldr/include/of.h +++ b/reactos/boot/freeldr/freeldr/include/of.h @@ -10,7 +10,7 @@ #include typedef int (*of_proxy) - ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5 ); + ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6 ); typedef long jmp_buf[100]; extern of_proxy ofproxy; extern void le_swap( void *begin, void *end, void *dest ); diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index 31f1b8d0bd8..4bbab90241b 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -8,7 +8,7 @@ read 3 1 int char*:arg2 int int exit 0 0 child 1 1 int int peer 1 1 int int -seek 2 1 int int int +seek 3 1 int int int int # MMU methods # claim (virt size align -- base) claim 3 1 int int int int From 47acc19039b0c8b3c815bbcba264c87055048d1e Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 29 Aug 2006 07:16:16 +0000 Subject: [PATCH 25/81] Menu displays. Need stdin/hid objects. svn path=/branches/powerpc/; revision=23765 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index c2097a07be1..4d301dcb95f 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -30,6 +30,7 @@ static int chosen_package, stdin_handle, part_handle = -1; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; +char *video_mem = 0; void le_swap( void *start_addr_v, void *end_addr_v, @@ -107,26 +108,29 @@ void PpcVideoClearScreen( UCHAR Attr ) { ofw_print_string("ClearScreen\n"); } -VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) { - printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" ); - return VideoGraphicsMode; -} - -/* FIXME: Query */ VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) { - ofw_print_string("GetDisplaySize\n"); - *Width = 640; - *Height = 480; - *Depth = 8; + //ofw_print_string("GetDisplaySize\n"); + *Width = 80; + *Height = 25; + *Depth = 16; + //printf("GetDisplaySize(%d,%d,%d)\n", *Width, *Height, *Depth); } ULONG PpcVideoGetBufferSize() { ULONG Width, Height, Depth; - ofw_print_string("PpcVideoGetBufferSize\n"); + //ofw_print_string("PpcVideoGetBufferSize\n"); PpcVideoGetDisplaySize( &Width, &Height, &Depth ); return Width * Height * Depth / 8; } +VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) { + //printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" ); + if( Init && !video_mem ) { + video_mem = MmAllocateMemory( PpcVideoGetBufferSize() ); + } + return VideoTextMode; +} + VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) { printf("SetTextCursorPosition(%d,%d)\n", X,Y); } @@ -140,7 +144,22 @@ VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) { } VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) { - printf( "CopyOffScreenBufferToVRAM(%x)\n", Buffer ); + int i,j; + ULONG w,h,d; + PCHAR ChBuf = Buffer; + int offset = 0; + + PpcVideoGetDisplaySize( &w, &h, &d ); + + for( i = 0; i < h; i++ ) { + for( j = 0; j < w; j++ ) { + offset = (j * 2) + (i * w * 2); + if( ChBuf[offset] != video_mem[offset] ) { + video_mem[offset] = ChBuf[offset]; + PpcVideoPutChar(ChBuf[offset],0,j+1,i+1); + } + } + } } BOOLEAN PpcVideoIsPaletteFixed() { @@ -294,7 +313,7 @@ ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) { VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second ) { - printf("RTCGeturrentDateTime\n"); + //printf("RTCGeturrentDateTime\n"); } VOID PpcHwDetect() { From e0ee404d0304597580a52ac149751315f26b9b22 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 29 Aug 2006 15:50:53 +0000 Subject: [PATCH 26/81] Make sure writes to video_mem are not optimized away svn path=/branches/powerpc/; revision=23782 --- reactos/boot/freeldr/freeldr/arch/powerpc/mach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 4d301dcb95f..86678e2f0af 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -30,7 +30,7 @@ static int chosen_package, stdin_handle, part_handle = -1; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; -char *video_mem = 0; +volatile char *video_mem = 0; void le_swap( void *start_addr_v, void *end_addr_v, From f6811c33e78c7aec1de0412bfe6e5838766bd867 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 31 Aug 2006 08:01:30 +0000 Subject: [PATCH 27/81] Some intermediate work. We start loading the kernel now. Working on early boot memory mapping. We'll rely heavily on open firmware until we're on our own page table. svn path=/branches/powerpc/; revision=23835 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 64 ++- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 507 ++++++------------ 2 files changed, 237 insertions(+), 334 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 86678e2f0af..272ad5762d5 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -25,7 +25,7 @@ extern void BootMain( char * ); extern char *GetFreeLoaderVersionString(); of_proxy ofproxy; -void *PageDirectoryStart, *PageDirectoryEnd; +void *PageDirectoryStart, *PageDirectoryEnd, *mem_base = 0; static int chosen_package, stdin_handle, part_handle = -1; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; @@ -95,7 +95,7 @@ int PpcFindDevice( int depth, int parent, char *devname, int *nth ) { } BOOLEAN PpcConsKbHit() { - return TRUE; + return FALSE; } int PpcConsGetCh() { @@ -193,6 +193,14 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize); + if( mem_base ) { + BiosMemoryMap[0].Type = MEMTYPE_USABLE; + BiosMemoryMap[0].BaseAddress = (ULONG)mem_base; + BiosMemoryMap[0].Length = TOTAL_HEAP_NEEDED; + printf("[cached] returning 1 element\n"); + return 1; + } + ofw_getprop(chosen_package, "memory", (char *)&memhandle, sizeof(memhandle)); ofw_getprop(chosen_package, "mmu", @@ -207,8 +215,10 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, for( i = 0; i < returned / sizeof(int) && !num_mem; i += 2 ) { BiosMemoryMap[num_mem].Type = MEMTYPE_USABLE; BiosMemoryMap[num_mem].BaseAddress = memdata[i]; + mem_base = (void *)memdata[i]; BiosMemoryMap[num_mem].Length = memdata[i+1]; - if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED ) { + if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED && + total < TOTAL_HEAP_NEEDED ) { BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED; ofw_claim(BiosMemoryMap[num_mem].BaseAddress, BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */ @@ -248,7 +258,14 @@ BOOLEAN PpcDiskGetSystemVolume( char *SystemPath, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType ) { - return FALSE; + char *remain = strchr(SystemPath, '\\'); + if( remain ) { + strcpy( RemainingPath, remain+1 ); + } else { + RemainingPath[0] = 0; + } + *Device = 0; + return PpcDiskGetBootVolume(DriveNumber, StartSector, SectorCount, FsType); } BOOLEAN PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) { @@ -320,6 +337,44 @@ VOID PpcHwDetect() { printf("PpcHwDetect\n"); } +BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) { + CHAR BootPath[256]; + ULONG PartitionNumber; + ULONG DriveNumber; + PARTITION_TABLE_ENTRY PartEntry; + char *p; + + if (!DissectArcPath(SystemPath, BootPath, &DriveNumber, &PartitionNumber)) + { + return FALSE; + } + + if (0 != PartitionNumber) + { + return TRUE; + } + + if (! DiskGetActivePartitionEntry(DriveNumber, + &PartEntry, + &PartitionNumber) || + PartitionNumber < 1 || 9 < PartitionNumber) + { + return FALSE; + } + + p = SystemPath; + while ('\0' != *p && 0 != _strnicmp(p, "partition(", 10)) { + p++; + } + p = strchr(p, ')'); + if (NULL == p || '0' != *(p - 1)) { + return FALSE; + } + *(p - 1) = '0' + PartitionNumber; + + return TRUE; +} + typedef unsigned int uint32_t; void PpcInit( of_proxy the_ofproxy ) { @@ -368,6 +423,7 @@ void PpcInit( of_proxy the_ofproxy ) { MachVtbl.GetMemoryMap = PpcGetMemoryMap; + MachVtbl.DiskNormalizeSystemPath = PpcDiskNormalizeSystemPath; MachVtbl.DiskGetBootVolume = PpcDiskGetBootVolume; MachVtbl.DiskGetSystemVolume = PpcDiskGetSystemVolume; MachVtbl.DiskGetBootPath = PpcDiskGetBootPath; diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 4e17e0a2718..374b633191c 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -1,59 +1,68 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: Freeloader - * FILE: boot/freeldr/freeldr/multiboot.c - * PURPOSE: ReactOS Loader - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2005 Alex Ionescu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include + +#include #define NDEBUG #include -int xstrnicmp( const char *a, const char *b, int n ) { - while( n-- && *a && (*a++ == *b++) ); - return *a - *b; -} - -/* Base Addres of Kernel in Physical Memory */ -#define KERNEL_BASE_PHYS 0x200000 +static PVOID KernelMemory = 0; /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ #define PFN_SHIFT 12 /* Bits to shift to convert a Virtual Address into an Offset in the Page Directory */ -#define PDE_SHIFT 20 +#define PDE_SHIFT 22 #define PDE_SHIFT_PAE 18 - + /* Converts a Relative Address read from the Kernel into a Physical Address */ -#define RaToPa(p) \ - (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS) - +ULONG RaToPa(ULONG p) { + return ofw_virt2phys((ULONG)(p + KernelMemory), 1); +} + /* Converts a Phsyical Address Pointer into a Page Frame Number */ #define PaPtrToPfn(p) \ (((ULONG_PTR)&p) >> PFN_SHIFT) - + /* Converts a Phsyical Address into a Page Frame Number */ #define PaToPfn(p) \ ((p) >> PFN_SHIFT) -#define STARTUP_BASE 0xF0000000 -#define HYPERSPACE_BASE 0xF0800000 +#define STARTUP_BASE 0xC0000000 +#define HYPERSPACE_BASE 0xC0400000 +#define HYPERSPACE_PAE_BASE 0xC0800000 #define APIC_BASE 0xFEC00000 #define KPCR_BASE 0xFF000000 - + #define LowMemPageTableIndex 0 -#define StartupPageTableIndex (STARTUP_BASE >> 20) / sizeof(HARDWARE_PTE_X86) -#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 20) / sizeof(HARDWARE_PTE_X86) -#define KpcrPageTableIndex (KPCR_BASE >> 20) / sizeof(HARDWARE_PTE_X86) -#define ApicPageTableIndex (APIC_BASE >> 20) / sizeof(HARDWARE_PTE_X86) +#define StartupPageTableIndex (STARTUP_BASE >> 22) +#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 22) +#define KpcrPageTableIndex (KPCR_BASE >> 22) +#define ApicPageTableIndex (APIC_BASE >> 22) #define LowMemPageTableIndexPae 0 #define StartupPageTableIndexPae (STARTUP_BASE >> 21) -#define HyperspacePageTableIndexPae (HYPERSPACE_BASE >> 21) +#define HyperspacePageTableIndexPae (HYPERSPACE_PAE_BASE >> 21) #define KpcrPageTableIndexPae (KPCR_BASE >> 21) #define ApicPageTableIndexPae (APIC_BASE >> 21) @@ -64,7 +73,7 @@ int xstrnicmp( const char *a, const char *b, int n ) { ULONG_PTR NextModuleBase = 0; /* Currently Opened Module */ -VOID *CurrentModule = NULL; +PLOADER_MODULE CurrentModule = NULL; /* Unrelocated Kernel Base in Virtual Memory */ ULONG_PTR KernelBase; @@ -78,7 +87,7 @@ ULONG_PTR KernelEntry; /* FUNCTIONS *****************************************************************/ /*++ - * FrLdrStartup + * FrLdrStartup * INTERNAL * * Prepares the system for loading the Kernel. @@ -96,21 +105,34 @@ ULONG_PTR KernelEntry; VOID NTAPI FrLdrStartup(ULONG Magic) -{ -#if 0 - /* Disable Interrupts */ - KeArchDisableInterrupts(); - - /* Re-initalize EFLAGS */ - KeArchEraseFlags(); - - /* Initialize the page directory */ - FrLdrSetupPageDirectory(); -#endif +{ } /*++ - * FrLdrGetKernelBase + * FrLdrSetupPae + * INTERNAL + * + * Configures PAE on a MP System, and sets the PDBR if it's supported, or if + * the system is UP. + * + * Params: + * Magic - Multiboot Magic + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +VOID +FASTCALL +FrLdrSetupPae(ULONG Magic) +{ +} + +/*++ + * FrLdrGetKernelBase * INTERNAL * * Gets the Kernel Base to use. @@ -125,36 +147,59 @@ FrLdrStartup(ULONG Magic) * will be used by the Kernel. * *--*/ -VOID +static VOID FASTCALL FrLdrGetKernelBase(VOID) { PCHAR p; - + + /* Set KernelBase */ + LoaderBlock.KernelBase = KernelBase; + /* Read Command Line */ p = (PCHAR)LoaderBlock.CommandLine; while ((p = strchr(p, '/')) != NULL) { - + /* Find "/3GB" */ - if (!xstrnicmp(p + 1, "3GB", 3)) { - + if (!_strnicmp(p + 1, "3GB", 3)) { + /* Make sure there's nothing following it */ if (p[4] == ' ' || p[4] == 0) { - + /* Use 3GB */ - KernelBase = 0xC0000000; + KernelBase = 0xE0000000; + LoaderBlock.KernelBase = 0xC0000000; } } p++; } - - /* Set KernelBase */ - LoaderBlock.KernelBase = KernelBase; } /*++ - * FrLdrSetupPageDirectory + * FrLdrGetPaeMode + * INTERNAL + * + * Determines whether PAE mode shoudl be enabled or not. + * + * Params: + * None. + * + * Returns: + * None. + * + * Remarks: + * None. + * + *--*/ +VOID +FASTCALL +FrLdrGetPaeMode(VOID) +{ +} + +/*++ + * FrLdrSetupPageDirectory * INTERNAL * * Sets up the ReactOS Startup Page Directory. @@ -174,199 +219,10 @@ VOID FASTCALL FrLdrSetupPageDirectory(VOID) { -#if 0 - PPAGE_DIRECTORY_X86 PageDir; - PPAGE_DIRECTORY_TABLE_X64 PageDirTablePae; - PPAGE_DIRECTORY_X64 PageDirPae; - ULONG KernelPageTableIndex; - ULONG i; - - if (PaeModeEnabled) { - - /* Get the Kernel Table Index */ - KernelPageTableIndex = (KernelBase >> 21); - - /* Get the Startup Page Directory Table */ - PageDirTablePae = (PPAGE_DIRECTORY_TABLE_X64)&startup_pagedirectorytable_pae; - - /* Get the Startup Page Directory */ - PageDirPae = (PPAGE_DIRECTORY_X64)&startup_pagedirectory_pae; - - /* Set the Startup page directory table */ - for (i = 0; i < 4; i++) - { - PageDirTablePae->Pde[i].Valid = 1; - PageDirTablePae->Pde[i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i; - } - - /* Set up the Low Memory PDE */ - for (i = 0; i < 2; i++) - { - PageDirPae->Pde[LowMemPageTableIndexPae + i].Valid = 1; - PageDirPae->Pde[LowMemPageTableIndexPae + i].Write = 1; - PageDirPae->Pde[LowMemPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(lowmem_pagetable_pae) + i; - } - - /* Set up the Kernel PDEs */ - for (i = 0; i < 3; i++) - { - PageDirPae->Pde[KernelPageTableIndex + i].Valid = 1; - PageDirPae->Pde[KernelPageTableIndex + i].Write = 1; - PageDirPae->Pde[KernelPageTableIndex + i].PageFrameNumber = PaPtrToPfn(kernel_pagetable_pae) + i; - } - - /* Set up the Startup PDE */ - for (i = 0; i < 4; i++) - { - PageDirPae->Pde[StartupPageTableIndexPae + i].Valid = 1; - PageDirPae->Pde[StartupPageTableIndexPae + i].Write = 1; - PageDirPae->Pde[StartupPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i; - } - - /* Set up the Hyperspace PDE */ - for (i = 0; i < 2; i++) - { - PageDirPae->Pde[HyperspacePageTableIndexPae + i].Valid = 1; - PageDirPae->Pde[HyperspacePageTableIndexPae + i].Write = 1; - PageDirPae->Pde[HyperspacePageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable_pae) + i; - } - - /* Set up the Apic PDE */ - for (i = 0; i < 2; i++) - { - PageDirPae->Pde[ApicPageTableIndexPae + i].Valid = 1; - PageDirPae->Pde[ApicPageTableIndexPae + i].Write = 1; - PageDirPae->Pde[ApicPageTableIndexPae + i].PageFrameNumber = PaPtrToPfn(apic_pagetable_pae) + i; - } - - /* Set up the KPCR PDE */ - PageDirPae->Pde[KpcrPageTableIndexPae].Valid = 1; - PageDirPae->Pde[KpcrPageTableIndexPae].Write = 1; - PageDirPae->Pde[KpcrPageTableIndexPae].PageFrameNumber = PaPtrToPfn(kpcr_pagetable_pae); - - /* Set up Low Memory PTEs */ - PageDirPae = (PPAGE_DIRECTORY_X64)&lowmem_pagetable_pae; - for (i=0; i<1024; i++) { - - PageDirPae->Pde[i].Valid = 1; - PageDirPae->Pde[i].Write = 1; - PageDirPae->Pde[i].Owner = 1; - PageDirPae->Pde[i].PageFrameNumber = i; - } - - /* Set up Kernel PTEs */ - PageDirPae = (PPAGE_DIRECTORY_X64)&kernel_pagetable_pae; - for (i=0; i<1536; i++) { - - PageDirPae->Pde[i].Valid = 1; - PageDirPae->Pde[i].Write = 1; - PageDirPae->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS) + i; - } - - /* Set up APIC PTEs */ - PageDirPae = (PPAGE_DIRECTORY_X64)&apic_pagetable_pae; - PageDirPae->Pde[0].Valid = 1; - PageDirPae->Pde[0].Write = 1; - PageDirPae->Pde[0].CacheDisable = 1; - PageDirPae->Pde[0].WriteThrough = 1; - PageDirPae->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE); - PageDirPae->Pde[0x200].Valid = 1; - PageDirPae->Pde[0x200].Write = 1; - PageDirPae->Pde[0x200].CacheDisable = 1; - PageDirPae->Pde[0x200].WriteThrough = 1; - PageDirPae->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS); - - /* Set up KPCR PTEs */ - PageDirPae = (PPAGE_DIRECTORY_X64)&kpcr_pagetable_pae; - PageDirPae->Pde[0].Valid = 1; - PageDirPae->Pde[0].Write = 1; - PageDirPae->Pde[0].PageFrameNumber = 1; - - } else { - - /* Get the Kernel Table Index */ - KernelPageTableIndex = (KernelBase >> PDE_SHIFT) / sizeof(HARDWARE_PTE_X86); - - /* Get the Startup Page Directory */ - PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory; - - /* Set up the Low Memory PDE */ - PageDir->Pde[LowMemPageTableIndex].Valid = 1; - PageDir->Pde[LowMemPageTableIndex].Write = 1; - PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable); - - /* Set up the Kernel PDEs */ - PageDir->Pde[KernelPageTableIndex].Valid = 1; - PageDir->Pde[KernelPageTableIndex].Write = 1; - PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable); - PageDir->Pde[KernelPageTableIndex + 1].Valid = 1; - PageDir->Pde[KernelPageTableIndex + 1].Write = 1; - PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096); - - /* Set up the Startup PDE */ - PageDir->Pde[StartupPageTableIndex].Valid = 1; - PageDir->Pde[StartupPageTableIndex].Write = 1; - PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory); - - /* Set up the Hyperspace PDE */ - PageDir->Pde[HyperspacePageTableIndex].Valid = 1; - PageDir->Pde[HyperspacePageTableIndex].Write = 1; - PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable); - - /* Set up the Apic PDE */ - PageDir->Pde[ApicPageTableIndex].Valid = 1; - PageDir->Pde[ApicPageTableIndex].Write = 1; - PageDir->Pde[ApicPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable); - - /* Set up the KPCR PDE */ - PageDir->Pde[KpcrPageTableIndex].Valid = 1; - PageDir->Pde[KpcrPageTableIndex].Write = 1; - PageDir->Pde[KpcrPageTableIndex].PageFrameNumber = PaPtrToPfn(kpcr_pagetable); - - /* Set up Low Memory PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable; - for (i=0; i<1024; i++) { - - PageDir->Pde[i].Valid = 1; - PageDir->Pde[i].Write = 1; - PageDir->Pde[i].Owner = 1; - PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE); - } - - /* Set up Kernel PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable; - for (i=0; i<1536; i++) { - - PageDir->Pde[i].Valid = 1; - PageDir->Pde[i].Write = 1; - PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE); - } - - /* Set up APIC PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable; - PageDir->Pde[0].Valid = 1; - PageDir->Pde[0].Write = 1; - PageDir->Pde[0].CacheDisable = 1; - PageDir->Pde[0].WriteThrough = 1; - PageDir->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE); - PageDir->Pde[0x200].Valid = 1; - PageDir->Pde[0x200].Write = 1; - PageDir->Pde[0x200].CacheDisable = 1; - PageDir->Pde[0x200].WriteThrough = 1; - PageDir->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS); - - /* Set up KPCR PTEs */ - PageDir = (PPAGE_DIRECTORY_X86)&kpcr_pagetable; - PageDir->Pde[0].Valid = 1; - PageDir->Pde[0].Write = 1; - PageDir->Pde[0].PageFrameNumber = 1; - } - return; -#endif } /*++ - * FrLdrMapKernel + * FrLdrMapKernel * INTERNAL * * Maps the Kernel into memory, does PE Section Mapping, initalizes the @@ -386,7 +242,6 @@ BOOLEAN NTAPI FrLdrMapKernel(FILE *KernelImage) { -#if 0 PIMAGE_DOS_HEADER ImageHeader; PIMAGE_NT_HEADERS NtHeader; PIMAGE_SECTION_HEADER Section; @@ -395,7 +250,7 @@ FrLdrMapKernel(FILE *KernelImage) ULONG_PTR SourceSection; ULONG_PTR TargetSection; ULONG SectionSize; - LONG i; + INT i; PIMAGE_DATA_DIRECTORY RelocationDDir; PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; ULONG Count; @@ -407,10 +262,10 @@ FrLdrMapKernel(FILE *KernelImage) /* Allocate 1024 bytes for PE Header */ ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024); - + /* Make sure it was succesful */ if (ImageHeader == NULL) { - + return FALSE; } @@ -424,94 +279,97 @@ FrLdrMapKernel(FILE *KernelImage) /* Now read the MZ header to get the offset to the PE Header */ NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew); - + /* Get Kernel Base */ - KernelBase = NtHeader->OptionalHeader.ImageBase; + KernelBase = NtHeader->OptionalHeader.ImageBase; FrLdrGetKernelBase(); - + + printf("About to do RaToPa(%x)\n", + NtHeader->OptionalHeader.AddressOfEntryPoint); /* Save Entrypoint */ KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); - + printf("RaToPa -> %x\n", KernelEntry); + /* Save the Image Size */ ImageSize = NtHeader->OptionalHeader.SizeOfImage; - + /* Free the Header */ MmFreeMemory(ImageHeader); /* Set the file pointer to zero */ FsSetFilePointer(KernelImage, 0); + /* Allocate kernel memory */ + KernelMemory = MmAllocateMemory(ImageSize); + /* Load the file image */ - FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS); - + FsReadFile(KernelImage, ImageSize, NULL, KernelMemory); + /* Reload the NT Header */ - NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew); - + NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KernelMemory + ImageHeader->e_lfanew); + /* Load the first section */ Section = IMAGE_FIRST_SECTION(NtHeader); SectionCount = NtHeader->FileHeader.NumberOfSections - 1; - + /* Now go to the last section */ Section += SectionCount; - - /* Walk each section backwards */ - for (i=SectionCount; i >= 0; i--, Section--) { - - /* Get the disk location and the memory location, and the size */ + + /* Walk each section backwards */ + for (i=(INT)SectionCount; i >= 0; i--, Section--) { + + /* Get the disk location and the memory location, and the size */ SourceSection = RaToPa(Section->PointerToRawData); TargetSection = RaToPa(Section->VirtualAddress); SectionSize = Section->SizeOfRawData; - + /* If the section is already mapped correctly, go to the next */ if (SourceSection == TargetSection) continue; - + /* Load it into memory */ memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize); - + /* Check for unitilizated data */ if (Section->SizeOfRawData < Section->Misc.VirtualSize) { - + /* Zero it out */ - memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData), + memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData), 0, Section->Misc.VirtualSize - Section->SizeOfRawData); } } - + /* Get the Relocation Data Directory */ RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; - + /* Get the Relocation Section Start and End*/ - RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress); + RelocationDir = (PIMAGE_BASE_RELOCATION)(KernelMemory + RelocationDDir->VirtualAddress); RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); - + /* Calculate Difference between Real Base and Compiled Base*/ - Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;; - + Delta = KernelBase - NtHeader->OptionalHeader.ImageBase; + /* Determine how far we shoudl relocate */ - MaxAddress = KERNEL_BASE_PHYS + ImageSize; - + MaxAddress = (ULONG)KernelMemory + ImageSize; + /* Relocate until we've processed all the blocks */ while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { - + /* See how many Relocation Blocks we have */ Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - + /* Calculate the Address of this Directory */ - Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress; - + Address = (ULONG)KernelMemory + RelocationDir->VirtualAddress; + /* Calculate the Offset of the Type */ TypeOffset = (PUSHORT)(RelocationDir + 1); - for (i = 0; i < Count; i++) { - + for (i = 0; i < (INT)Count; i++) { + ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF)); - /* Don't relocate after the end of the loaded driver */ - if ((ULONG_PTR)ShortPtr >= MaxAddress) break; - switch (*TypeOffset >> 12) { - + case IMAGE_REL_BASED_ABSOLUTE: break; @@ -528,65 +386,63 @@ FrLdrMapKernel(FILE *KernelImage) *LongPtr += Delta; break; } - + TypeOffset++; } - + /* Move to the next Relocation Table */ RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); } - + /* Increase the next Load Base */ - NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE); + NextModuleBase = ROUND_UP((ULONG)KernelMemory + ImageSize, PAGE_SIZE); /* Return Success */ -#endif return TRUE; } ULONG_PTR NTAPI -FrLdrLoadModule(FILE *ModuleImage, - LPCSTR ModuleName, +FrLdrLoadModule(FILE *ModuleImage, + LPCSTR ModuleName, PULONG ModuleSize) { -#if 0 ULONG LocalModuleSize; - PFRLDR_MODULE ModuleData; + PLOADER_MODULE ModuleData; LPSTR NameBuffer; LPSTR TempName; /* Get current module data structure and module name string array */ - ModuleData = &multiboot_modules[LoaderBlock.ModsCount]; - + ModuleData = &reactos_modules[LoaderBlock.ModsCount]; + /* Get only the Module Name */ do { - + TempName = strchr(ModuleName, '\\'); - + if(TempName) { ModuleName = TempName + 1; } } while(TempName); - NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount]; + NameBuffer = reactos_module_strings[LoaderBlock.ModsCount]; /* Get Module Size */ LocalModuleSize = FsGetFileSize(ModuleImage); - + /* Fill out Module Data Structure */ - ModuleData->ModuleStart = NextModuleBase; - ModuleData->ModuleEnd = NextModuleBase + LocalModuleSize; - + ModuleData->ModStart = NextModuleBase; + ModuleData->ModEnd = NextModuleBase + LocalModuleSize; + /* Save name */ strcpy(NameBuffer, ModuleName); - ModuleData->ModuleName = NameBuffer; + ModuleData->String = (ULONG_PTR)NameBuffer; /* Load the file image */ FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase); /* Move to next memory block and increase Module Count */ - NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE); + NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE); LoaderBlock.ModsCount++; /* Return Module Size if required */ @@ -594,63 +450,55 @@ FrLdrLoadModule(FILE *ModuleImage, *ModuleSize = LocalModuleSize; } - return(ModuleData->ModuleStart); -#else - return 0; -#endif + return(ModuleData->ModStart); } ULONG_PTR NTAPI FrLdrCreateModule(LPCSTR ModuleName) { -#if 0 - PFRLDR_MODULE ModuleData; + PLOADER_MODULE ModuleData; LPSTR NameBuffer; /* Get current module data structure and module name string array */ - ModuleData = &multiboot_modules[LoaderBlock.ModsCount]; - NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount]; + ModuleData = &reactos_modules[LoaderBlock.ModsCount]; + NameBuffer = reactos_module_strings[LoaderBlock.ModsCount]; /* Set up the structure */ - ModuleData->ModuleStart = NextModuleBase; - ModuleData->ModuleEnd = -1; - + ModuleData->ModStart = NextModuleBase; + ModuleData->ModEnd = -1; + /* Copy the name */ strcpy(NameBuffer, ModuleName); - ModuleData->ModuleName = NameBuffer; + ModuleData->String = (ULONG_PTR)NameBuffer; /* Set the current Module */ CurrentModule = ModuleData; /* Return Module Base Address */ - return(ModuleData->ModuleStart); -#else - return 0; -#endif + return(ModuleData->ModStart); } BOOLEAN NTAPI -FrLdrCloseModule(ULONG_PTR ModuleBase, +FrLdrCloseModule(ULONG_PTR ModuleBase, ULONG ModuleSize) { -#if 0 - PFRLDR_MODULE ModuleData = CurrentModule; + PLOADER_MODULE ModuleData = CurrentModule; /* Make sure a module is opened */ if (ModuleData) { - + /* Make sure this is the right module and that it hasn't been closed */ - if ((ModuleBase == ModuleData->ModuleStart) && (ModuleData->ModuleEnd == -1)) { - + if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) { + /* Close the Module */ - ModuleData->ModuleEnd = ModuleData->ModuleStart + ModuleSize; + ModuleData->ModEnd = ModuleData->ModStart + ModuleSize; /* Set the next Module Base and increase the number of modules */ - NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE); + NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE); LoaderBlock.ModsCount++; - + /* Close the currently opened module */ CurrentModule = NULL; @@ -660,6 +508,5 @@ FrLdrCloseModule(ULONG_PTR ModuleBase, } /* Failure path */ -#endif return(FALSE); } From f5f3faa9f20521c309bcd1ddefd2b851b7496528 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 1 Sep 2006 06:53:49 +0000 Subject: [PATCH 28/81] Adding methods to inquire about virtual memory setup. svn path=/branches/powerpc/; revision=23858 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 127 +++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 272ad5762d5..5d22bf54eff 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -35,7 +35,8 @@ volatile char *video_mem = 0; void le_swap( void *start_addr_v, void *end_addr_v, void *target_addr_v ) { - long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8), + long + *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8), *end_addr = (long *)ROUND_UP((long)end_addr_v,8), *target_addr = (long *)ROUND_DOWN((long)target_addr_v,8); long tmp; @@ -377,8 +378,114 @@ BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) { typedef unsigned int uint32_t; +int GetMSR() { + register int res asm ("r3"); + __asm__("mfmsr 3"); + return res; +} + +int GetSR(int n) { + register int res asm ("r3"); + switch( n ) { + case 0: + __asm__("mfsr 3,0"); + break; + case 1: + __asm__("mfsr 3,1"); + break; + case 2: + __asm__("mfsr 3,2"); + break; + case 3: + __asm__("mfsr 3,3"); + break; + case 4: + __asm__("mfsr 3,4"); + break; + case 5: + __asm__("mfsr 3,5"); + break; + case 6: + __asm__("mfsr 3,6"); + break; + case 7: + __asm__("mfsr 3,7"); + break; + case 8: + __asm__("mfsr 3,8"); + break; + case 9: + __asm__("mfsr 3,9"); + break; + case 10: + __asm__("mfsr 3,10"); + break; + case 11: + __asm__("mfsr 3,11"); + break; + case 12: + __asm__("mfsr 3,12"); + break; + case 13: + __asm__("mfsr 3,13"); + break; + case 14: + __asm__("mfsr 3,14"); + break; + case 15: + __asm__("mfsr 3,15"); + break; + } + return res; +} + +void GetBat( int bat, int inst, int *batHi, int *batLo ) { + register int bh asm("r3"), bl asm("r4"); + if( inst ) { + switch( bat ) { + case 0: + __asm__("mfibatu 3,0"); + __asm__("mfibatl 4,0"); + break; + case 1: + __asm__("mfibatu 3,1"); + __asm__("mfibatl 4,1"); + break; + case 2: + __asm__("mfibatu 3,2"); + __asm__("mfibatl 4,2"); + break; + case 3: + __asm__("mfibatu 3,3"); + __asm__("mfibatl 4,3"); + break; + } + } else { + switch( bat ) { + case 0: + __asm__("mfdbatu 3,0"); + __asm__("mfdbatl 4,0"); + break; + case 1: + __asm__("mfdbatu 3,1"); + __asm__("mfdbatl 4,1"); + break; + case 2: + __asm__("mfdbatu 3,2"); + __asm__("mfdbatl 4,2"); + break; + case 3: + __asm__("mfdbatu 3,3"); + __asm__("mfdbatl 4,3"); + break; + } + } + *batHi = bh; + *batLo = bl; +} + void PpcInit( of_proxy the_ofproxy ) { - int len, stdin_handle_chosen; + int i, len, stdin_handle_chosen, bathi, batlo; ofproxy = the_ofproxy; ofw_print_string("Freeldr PowerPC Init\n"); @@ -405,6 +512,22 @@ void PpcInit( of_proxy the_ofproxy ) { MachVtbl.ConsGetCh = PpcConsGetCh; printf( "stdin_handle is %x\n", stdin_handle ); + /* List MMU Status */ + printf("MSR %x\n", GetMSR()); + + for( i = 0; i < 16; i++ ) { + printf("SR%d %x\n", i, GetSR(i)); + } + + for( i = 0; i < 4; i++ ) { + GetBat( i, 0, &bathi, &batlo ); + printf("DBAT%d %x:%x\n", i, bathi, batlo); + } + + for( i = 0; i < 4; i++ ) { + GetBat( i, 1, &bathi, &batlo ); + printf("IBAT%d %x:%x\n", i, bathi, batlo); + } MachVtbl.VideoClearScreen = PpcVideoClearScreen; MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode; From 62f408e7e604e24cba0da2ea573f6905bb493df0 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 1 Sep 2006 09:46:44 +0000 Subject: [PATCH 29/81] Most of an implementation of page lookup for PPC. Written for understanding and also to provide a way to inspect virtual to phyiscal translations. We should and will do this with ofw most of the time, but we'll have to do it ourselves in the delicate time before jumping to ntoskrnl. svn path=/branches/powerpc/; revision=23861 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 5d22bf54eff..0d1a20e33bf 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -384,6 +384,20 @@ int GetMSR() { return res; } +int GetPhys( int addr ) { + register int res asm ("r3"); + __asm__("mfmsr 5\n\t" + "mr 4,5\n\t" + "xor 1,1,1\n\t" + "addi 1,1,-1\n\t" + "xori 1,1,0x10\n\t" + "and 5,1,5\n\t" + "mtmsr 5\n\t" + "lwz 3,0(3)\n\t" + "mtmsr 4"); + return res; +} + int GetSR(int n) { register int res asm ("r3"); switch( n ) { @@ -484,6 +498,75 @@ void GetBat( int bat, int inst, int *batHi, int *batLo ) { *batLo = bl; } +int GetSDR1() { + register int res asm("r3"); + __asm__("mfsdr1 3"); + return res; +} + +int BatHit( int bath, int batl, int virt ) { + return (virt & 0xfffc0000) == (bath & 0xfffc0000); +} + +int BatTranslate( int bath, int batl, int virt ) { + return (virt & 0x3ffff) | (batl & 0xfffc0000); +} + +/* translate address */ +int virt2phys( int virt, int inst ) { + int msr = GetMSR(); + int txmask = inst ? 0x20 : 0x10; + if( msr & txmask ) { + int i, bath, batl, sr, sdr1, physbase, vahi, valo; + int npteg, hash, ptegaddr, hashmask, ptehi, ptelo; + int vsid, pteh; + for( i = 0; i < 4; i++ ) { + GetBat( i, inst, &bath, &batl ); + if( BatHit( bath, batl, virt ) ) { + return BatTranslate( bath, batl, virt ); + } + } + + sr = GetSR( virt >> 28 ); + vsid = sr & 0xfffffff; + valo = (vsid << 28) | (virt & 0xfffffff); + if( sr & 0x80000000 ) + return valo; + + sdr1 = GetSDR1(); + + physbase = sdr1 & ~0xffff; + vahi = vsid >> 4; + npteg = ((sdr1 & 0x1ff) << 10); + hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); + + hashmask = ((sdr1 & 0xffff) << 12) | 0x3ff; + + for( pteh = 0; pteh < 0xff; pteh += 64, hash ^= ~0 ) { + ptegaddr = ((hashmask & hash) * 64) + physbase; + + for( i = 0; i < 8; i++ ) { + int ptevsid, pteapi; + + ptehi = GetPhys( ptegaddr + (i * 8) ); + ptelo = GetPhys( ptegaddr + (i * 8) + 4 ); + ptevsid = (ptehi >> 8) & 0x7fffff; + pteapi = ptehi & 0x3f; + + //printf("pte[%d] @ %x = %x:%x\n", + //i, ptegaddr + (i * 8), ptehi, ptelo); + + if( (ptehi & 64) != pteh ) continue; + if( ptevsid != (vsid & 0x7fffff) ) continue; + if( pteapi != ((virt >> 22) & 0x3f) ) continue; + + return (ptelo & 0xfffff000) | (virt & 0xfff); + } + } + return -1; + } else return virt; +} + void PpcInit( of_proxy the_ofproxy ) { int i, len, stdin_handle_chosen, bathi, batlo; ofproxy = the_ofproxy; @@ -529,6 +612,9 @@ void PpcInit( of_proxy the_ofproxy ) { printf("IBAT%d %x:%x\n", i, bathi, batlo); } + printf("virt2phys (0x8000,I) -> %x\n", virt2phys(0x8000,1)); + printf("virt2phys (0xe00000,D) -> %x\n", virt2phys(0x60000000,0)); + MachVtbl.VideoClearScreen = PpcVideoClearScreen; MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode; MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize; From 3cc6a119fba5bfe56843fd6738e4f16b9b1eaa33 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 3 Sep 2006 03:37:20 +0000 Subject: [PATCH 30/81] Fixed, separated mmu related functions. We now get correct translations in every case. fat.c: workaround for now. Need to figure out why the fs is b0rked. svn path=/branches/powerpc/; revision=23893 --- reactos/boot/freeldr/bootsect/ofwboot.s | 13 ++ .../boot/freeldr/freeldr/arch/powerpc/mach.c | 217 +----------------- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 17 +- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 193 ++++++++++++++++ .../boot/freeldr/freeldr/arch/powerpc/mmu.h | 14 ++ .../boot/freeldr/freeldr/freeldr_arch.rbuild | 1 + reactos/boot/freeldr/freeldr/fs/fat.c | 6 +- reactos/tools/ppc.lost+found/link-freeldr | 2 +- 8 files changed, 240 insertions(+), 223 deletions(-) create mode 100644 reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c create mode 100644 reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index 62ced40d7de..ff49c6582ef 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -28,6 +28,19 @@ _begin: /* Claim enough bytes to place freeldr at 0x8000 */ lis %r3,0x8000@ha + li %r3,0x8000@l + + lis %r4,_binary_freeldr_tmp_end@ha + addi %r4,%r4,_binary_freeldr_tmp_end@l + lis %r5,_binary_freeldr_tmp_start@ha + addi %r5,%r5,_binary_freeldr_tmp_start@l + sub %r4,%r4,%r5 + li %r5,0x1000 + + bl ofw_claim + + /* Now copy freeldr */ + lis %r3,0x8000@ha addi %r3,%r3,0x8000@l lis %r4,_binary_freeldr_tmp_end@ha diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 0d1a20e33bf..b0f13420815 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -19,6 +19,7 @@ #include "freeldr.h" #include "machine.h" #include "of.h" +#include "mmu.h" #define TOTAL_HEAP_NEEDED (16 * 1024 * 1024) /* 16 megs */ @@ -223,10 +224,6 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED; ofw_claim(BiosMemoryMap[num_mem].BaseAddress, BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */ - printf("virt2phys(%x)->%x\n", - BiosMemoryMap[num_mem].BaseAddress, - ofw_virt2phys - (mmuhandle, BiosMemoryMap[num_mem].BaseAddress)); total += BiosMemoryMap[0].Length; num_mem++; } @@ -378,197 +375,8 @@ BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) { typedef unsigned int uint32_t; -int GetMSR() { - register int res asm ("r3"); - __asm__("mfmsr 3"); - return res; -} - -int GetPhys( int addr ) { - register int res asm ("r3"); - __asm__("mfmsr 5\n\t" - "mr 4,5\n\t" - "xor 1,1,1\n\t" - "addi 1,1,-1\n\t" - "xori 1,1,0x10\n\t" - "and 5,1,5\n\t" - "mtmsr 5\n\t" - "lwz 3,0(3)\n\t" - "mtmsr 4"); - return res; -} - -int GetSR(int n) { - register int res asm ("r3"); - switch( n ) { - case 0: - __asm__("mfsr 3,0"); - break; - case 1: - __asm__("mfsr 3,1"); - break; - case 2: - __asm__("mfsr 3,2"); - break; - case 3: - __asm__("mfsr 3,3"); - break; - case 4: - __asm__("mfsr 3,4"); - break; - case 5: - __asm__("mfsr 3,5"); - break; - case 6: - __asm__("mfsr 3,6"); - break; - case 7: - __asm__("mfsr 3,7"); - break; - case 8: - __asm__("mfsr 3,8"); - break; - case 9: - __asm__("mfsr 3,9"); - break; - case 10: - __asm__("mfsr 3,10"); - break; - case 11: - __asm__("mfsr 3,11"); - break; - case 12: - __asm__("mfsr 3,12"); - break; - case 13: - __asm__("mfsr 3,13"); - break; - case 14: - __asm__("mfsr 3,14"); - break; - case 15: - __asm__("mfsr 3,15"); - break; - } - return res; -} - -void GetBat( int bat, int inst, int *batHi, int *batLo ) { - register int bh asm("r3"), bl asm("r4"); - if( inst ) { - switch( bat ) { - case 0: - __asm__("mfibatu 3,0"); - __asm__("mfibatl 4,0"); - break; - case 1: - __asm__("mfibatu 3,1"); - __asm__("mfibatl 4,1"); - break; - case 2: - __asm__("mfibatu 3,2"); - __asm__("mfibatl 4,2"); - break; - case 3: - __asm__("mfibatu 3,3"); - __asm__("mfibatl 4,3"); - break; - } - } else { - switch( bat ) { - case 0: - __asm__("mfdbatu 3,0"); - __asm__("mfdbatl 4,0"); - break; - case 1: - __asm__("mfdbatu 3,1"); - __asm__("mfdbatl 4,1"); - break; - case 2: - __asm__("mfdbatu 3,2"); - __asm__("mfdbatl 4,2"); - break; - case 3: - __asm__("mfdbatu 3,3"); - __asm__("mfdbatl 4,3"); - break; - } - } - *batHi = bh; - *batLo = bl; -} - -int GetSDR1() { - register int res asm("r3"); - __asm__("mfsdr1 3"); - return res; -} - -int BatHit( int bath, int batl, int virt ) { - return (virt & 0xfffc0000) == (bath & 0xfffc0000); -} - -int BatTranslate( int bath, int batl, int virt ) { - return (virt & 0x3ffff) | (batl & 0xfffc0000); -} - -/* translate address */ -int virt2phys( int virt, int inst ) { - int msr = GetMSR(); - int txmask = inst ? 0x20 : 0x10; - if( msr & txmask ) { - int i, bath, batl, sr, sdr1, physbase, vahi, valo; - int npteg, hash, ptegaddr, hashmask, ptehi, ptelo; - int vsid, pteh; - for( i = 0; i < 4; i++ ) { - GetBat( i, inst, &bath, &batl ); - if( BatHit( bath, batl, virt ) ) { - return BatTranslate( bath, batl, virt ); - } - } - - sr = GetSR( virt >> 28 ); - vsid = sr & 0xfffffff; - valo = (vsid << 28) | (virt & 0xfffffff); - if( sr & 0x80000000 ) - return valo; - - sdr1 = GetSDR1(); - - physbase = sdr1 & ~0xffff; - vahi = vsid >> 4; - npteg = ((sdr1 & 0x1ff) << 10); - hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); - - hashmask = ((sdr1 & 0xffff) << 12) | 0x3ff; - - for( pteh = 0; pteh < 0xff; pteh += 64, hash ^= ~0 ) { - ptegaddr = ((hashmask & hash) * 64) + physbase; - - for( i = 0; i < 8; i++ ) { - int ptevsid, pteapi; - - ptehi = GetPhys( ptegaddr + (i * 8) ); - ptelo = GetPhys( ptegaddr + (i * 8) + 4 ); - ptevsid = (ptehi >> 8) & 0x7fffff; - pteapi = ptehi & 0x3f; - - //printf("pte[%d] @ %x = %x:%x\n", - //i, ptegaddr + (i * 8), ptehi, ptelo); - - if( (ptehi & 64) != pteh ) continue; - if( ptevsid != (vsid & 0x7fffff) ) continue; - if( pteapi != ((virt >> 22) & 0x3f) ) continue; - - return (ptelo & 0xfffff000) | (virt & 0xfff); - } - } - return -1; - } else return virt; -} - void PpcInit( of_proxy the_ofproxy ) { - int i, len, stdin_handle_chosen, bathi, batlo; + int len, stdin_handle_chosen; ofproxy = the_ofproxy; ofw_print_string("Freeldr PowerPC Init\n"); @@ -595,25 +403,8 @@ void PpcInit( of_proxy the_ofproxy ) { MachVtbl.ConsGetCh = PpcConsGetCh; printf( "stdin_handle is %x\n", stdin_handle ); - /* List MMU Status */ - printf("MSR %x\n", GetMSR()); - - for( i = 0; i < 16; i++ ) { - printf("SR%d %x\n", i, GetSR(i)); - } - - for( i = 0; i < 4; i++ ) { - GetBat( i, 0, &bathi, &batlo ); - printf("DBAT%d %x:%x\n", i, bathi, batlo); - } - - for( i = 0; i < 4; i++ ) { - GetBat( i, 1, &bathi, &batlo ); - printf("IBAT%d %x:%x\n", i, bathi, batlo); - } - - printf("virt2phys (0x8000,I) -> %x\n", virt2phys(0x8000,1)); - printf("virt2phys (0xe00000,D) -> %x\n", virt2phys(0x60000000,0)); + printf("virt2phys (0xe00000,D) -> %x\n", PpcVirt2phys(0xe00000,0)); + printf("virt2phys (0xe01000,D) -> %x\n", PpcVirt2phys(0xe01000,0)); MachVtbl.VideoClearScreen = PpcVideoClearScreen; MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode; diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 374b633191c..f0c9c652aef 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -19,8 +19,8 @@ */ #include - #include +#include "mmu.h" #define NDEBUG #include @@ -37,7 +37,7 @@ static PVOID KernelMemory = 0; /* Converts a Relative Address read from the Kernel into a Physical Address */ ULONG RaToPa(ULONG p) { - return ofw_virt2phys((ULONG)(p + KernelMemory), 1); + return PpcVirt2phys((ULONG)(KernelMemory) + p, 0); } /* Converts a Phsyical Address Pointer into a Page Frame Number */ @@ -284,12 +284,6 @@ FrLdrMapKernel(FILE *KernelImage) KernelBase = NtHeader->OptionalHeader.ImageBase; FrLdrGetKernelBase(); - printf("About to do RaToPa(%x)\n", - NtHeader->OptionalHeader.AddressOfEntryPoint); - /* Save Entrypoint */ - KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); - printf("RaToPa -> %x\n", KernelEntry); - /* Save the Image Size */ ImageSize = NtHeader->OptionalHeader.SizeOfImage; @@ -302,6 +296,13 @@ FrLdrMapKernel(FILE *KernelImage) /* Allocate kernel memory */ KernelMemory = MmAllocateMemory(ImageSize); + /* Save Entrypoint */ + KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint); + printf("RaToPa(%x + %x) -> %x\n", + KernelMemory, + NtHeader->OptionalHeader.AddressOfEntryPoint, + KernelEntry); + /* Load the file image */ FsReadFile(KernelImage, ImageSize, NULL, KernelMemory); diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c new file mode 100644 index 00000000000..beca13d0a9a --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -0,0 +1,193 @@ +#include +#include "mmu.h" + +inline int GetMSR() { + register int res asm ("r3"); + __asm__("mfmsr 3"); + return res; +} + +__asm__("\t.globl GetPhys\n" + "GetPhys:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ + "mtmsr 5\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +inline int GetSR(int n) { + register int res asm ("r3"); + switch( n ) { + case 0: + __asm__("mfsr 3,0"); + break; + case 1: + __asm__("mfsr 3,1"); + break; + case 2: + __asm__("mfsr 3,2"); + break; + case 3: + __asm__("mfsr 3,3"); + break; + case 4: + __asm__("mfsr 3,4"); + break; + case 5: + __asm__("mfsr 3,5"); + break; + case 6: + __asm__("mfsr 3,6"); + break; + case 7: + __asm__("mfsr 3,7"); + break; + case 8: + __asm__("mfsr 3,8"); + break; + case 9: + __asm__("mfsr 3,9"); + break; + case 10: + __asm__("mfsr 3,10"); + break; + case 11: + __asm__("mfsr 3,11"); + break; + case 12: + __asm__("mfsr 3,12"); + break; + case 13: + __asm__("mfsr 3,13"); + break; + case 14: + __asm__("mfsr 3,14"); + break; + case 15: + __asm__("mfsr 3,15"); + break; + } + return res; +} + +inline void GetBat( int bat, int inst, int *batHi, int *batLo ) { + register int bh asm("r3"), bl asm("r4"); + if( inst ) { + switch( bat ) { + case 0: + __asm__("mfibatu 3,0"); + __asm__("mfibatl 4,0"); + break; + case 1: + __asm__("mfibatu 3,1"); + __asm__("mfibatl 4,1"); + break; + case 2: + __asm__("mfibatu 3,2"); + __asm__("mfibatl 4,2"); + break; + case 3: + __asm__("mfibatu 3,3"); + __asm__("mfibatl 4,3"); + break; + } + } else { + switch( bat ) { + case 0: + __asm__("mfdbatu 3,0"); + __asm__("mfdbatl 4,0"); + break; + case 1: + __asm__("mfdbatu 3,1"); + __asm__("mfdbatl 4,1"); + break; + case 2: + __asm__("mfdbatu 3,2"); + __asm__("mfdbatl 4,2"); + break; + case 3: + __asm__("mfdbatu 3,3"); + __asm__("mfdbatl 4,3"); + break; + } + } + *batHi = bh; + *batLo = bl; +} + +inline int GetSDR1() { + register int res asm("r3"); + __asm__("mfsdr1 3"); + return res; +} + +inline int BatHit( int bath, int batl, int virt ) { + int mask = 0xfffe0000 & ~((batl & 0x3f) << 17); + return (batl & 0x40) && ((virt & mask) == (bath & mask)); +} + +inline int BatTranslate( int bath, int batl, int virt ) { + return (virt & 0x007fffff) | (batl & 0xfffe0000); +} + +/* translate address */ +int PpcVirt2phys( int virt, int inst ) { + int msr = GetMSR(); + int txmask = inst ? 0x20 : 0x10; + int i, bath, batl, sr, sdr1, physbase, vahi, valo; + int npteg, hash, hashmask, ptehi, ptelo, ptegaddr; + int vsid, pteh, ptevsid, pteapi; + + if( msr & txmask ) { + sr = GetSR( virt >> 28 ); + vsid = sr & 0xfffffff; + vahi = vsid >> 4; + valo = (vsid << 28) | (virt & 0xfffffff); + if( sr & 0x80000000 ) { + return valo; + } + + for( i = 0; i < 4; i++ ) { + GetBat( i, inst, &bath, &batl ); + if( BatHit( bath, batl, virt ) ) { + return BatTranslate( bath, batl, virt ); + } + } + + sdr1 = GetSDR1(); + + physbase = sdr1 & ~0xffff; + hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; + hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); + npteg = hashmask + 1; + + for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) { + ptegaddr = ((hashmask & hash) * 64) + physbase; + + for( i = 0; i < 8; i++ ) { + ptehi = GetPhys( ptegaddr + (i * 8) ); + ptelo = GetPhys( ptegaddr + (i * 8) + 4 ); + + ptevsid = (ptehi >> 7) & 0xffffff; + pteapi = ptehi & 0x3f; + + if( (ptehi & 64) != pteh ) continue; + if( ptevsid != (vsid & 0xffffff) ) continue; + if( pteapi != ((virt >> 22) & 0x3f) ) continue; + + return (ptelo & 0xfffff000) | (virt & 0xfff); + } + } + return -1; + } else { + return virt; + } +} diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h new file mode 100644 index 00000000000..76734016c2f --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h @@ -0,0 +1,14 @@ +#ifndef FREELDR_MMU_H +#define FREELDR_MMU_H + +int GetMSR(); +int GetPhys( int addr ); +int GetSR(int n); +void GetBat( int bat, int inst, int *batHi, int *batLo ); +int GetSDR1(); +int BatHit( int bath, int batl, int virt ); +int BatTranslate( int bath, int batl, int virt ); +/* translate address */ +int PpcVirt2phys( int virt, int inst ); + +#endif/*FREELDR_MMU_H*/ diff --git a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild index d89713d604a..17b8140d1f9 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild @@ -66,6 +66,7 @@ -meabi boot.s ofw.c + mmu.c mach.c mboot.c diff --git a/reactos/boot/freeldr/freeldr/fs/fat.c b/reactos/boot/freeldr/freeldr/fs/fat.c index c3e2744542d..efe765e3366 100644 --- a/reactos/boot/freeldr/freeldr/fs/fat.c +++ b/reactos/boot/freeldr/freeldr/fs/fat.c @@ -431,7 +431,11 @@ BOOLEAN FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySi // if (DirEntry->FileName[0] == '\0') { - return FALSE; + /* A workaround for something I see ... there are + * zero entries in the middle of the dir. This is + * probably a bug in the way the fat fs was made. + */ + continue; //return FALSE; } // diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr index 296c1566317..63af41d41a1 100755 --- a/reactos/tools/ppc.lost+found/link-freeldr +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -1,7 +1,7 @@ #!/bin/sh -v export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin -ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a +ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a objcopy -O binary freeldr.elf freeldr.tmp.le output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload From 8741dcaf301fbac27de43c3f9024ac40d0c29ac4 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 4 Sep 2006 06:27:18 +0000 Subject: [PATCH 31/81] Removed junk. svn path=/branches/powerpc/; revision=23908 --- reactos/ntoskrnl/ntoskrnl.rbuild | 5 ----- 1 file changed, 5 deletions(-) diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 8b7b860a306..777b0ca4b1f 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -78,11 +78,6 @@ irq.c - - - ppc_irq.c - - cacheman.c copy.c From 8c90909c24c0c066c9e87fbc71c158cd8082fd4a Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 4 Sep 2006 06:38:37 +0000 Subject: [PATCH 32/81] Link ntoskrnl. svn path=/branches/powerpc/; revision=23909 --- reactos/lib/rtl/bit.c | 41 - reactos/lib/rtl/bitmap.c | 979 --------------------- reactos/tools/ppc.lost+found/link-ntoskrnl | 173 +++- 3 files changed, 172 insertions(+), 1021 deletions(-) delete mode 100644 reactos/lib/rtl/bitmap.c diff --git a/reactos/lib/rtl/bit.c b/reactos/lib/rtl/bit.c index be7008831b1..b2687326ac5 100644 --- a/reactos/lib/rtl/bit.c +++ b/reactos/lib/rtl/bit.c @@ -13,45 +13,4 @@ /* FUNCTIONS ****************************************************************/ -/* - * @implemented - */ -CCHAR NTAPI -RtlFindLeastSignificantBit(IN ULONGLONG Set) -{ - int i; - - if (Set == 0ULL) - return -1; - - for (i = 0; i < 64; i++) - { - if (Set & (1 << i)) - return (CCHAR)i; - } - - return -1; -} - - -/* - * @implemented - */ -CCHAR NTAPI -RtlFindMostSignificantBit(IN ULONGLONG Set) -{ - int i; - - if (Set == 0ULL) - return -1; - - for (i = 63; i >= 0; i--) - { - if (Set & (1 << i)) - return (CCHAR)i; - } - - return -1; -} - /* EOF */ diff --git a/reactos/lib/rtl/bitmap.c b/reactos/lib/rtl/bitmap.c deleted file mode 100644 index 584bfcf1660..00000000000 --- a/reactos/lib/rtl/bitmap.c +++ /dev/null @@ -1,979 +0,0 @@ -/* COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/rtl/bitmap.c - * PURPOSE: Bitmap functions - * PROGRAMMER: Eric Kohl - */ - -/* INCLUDES *****************************************************************/ - -#include - -#define NDEBUG -#include - -/* MACROS *******************************************************************/ - -/* Bits set from LSB to MSB; used as mask for runs < 8 bits */ -static const BYTE NTDLL_maskBits[8] = { 0, 1, 3, 7, 15, 31, 63, 127 }; - -/* Number of set bits for each value of a nibble; used for counting */ -static const BYTE NTDLL_nibbleBitCount[16] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 -}; - -/* First set bit in a nibble; used for determining least significant bit */ -static const BYTE NTDLL_leastSignificant[16] = { - 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Last set bit in a nibble; used for determining most significant bit */ -static const signed char NTDLL_mostSignificant[16] = { - -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 -}; - -/* PRIVATE FUNCTIONS *********************************************************/ - -static -int -NTDLL_RunSortFn(const void *lhs, - const void *rhs) -{ - if (((const RTL_BITMAP_RUN*)lhs)->NumberOfBits > ((const RTL_BITMAP_RUN*)rhs)->NumberOfBits) - return -1; - return 1; -} - -static -ULONG -WINAPI -NTDLL_FindRuns(PRTL_BITMAP lpBits, - PRTL_BITMAP_RUN lpSeries, - ULONG ulCount, - BOOLEAN bLongest, - ULONG (*fn)(PRTL_BITMAP,ULONG,PULONG)) -{ - BOOL bNeedSort = ulCount > 1 ? TRUE : FALSE; - ULONG ulPos = 0, ulRuns = 0; - - if (!ulCount) - return ~0U; - - while (ulPos < lpBits->SizeOfBitMap) - { - /* Find next set/clear run */ - ULONG ulSize, ulNextPos = fn(lpBits, ulPos, &ulSize); - - if (ulNextPos == ~0U) - break; - - if (bLongest && ulRuns == ulCount) - { - /* Sort runs with shortest at end, if they are out of order */ - if (bNeedSort) - qsort(lpSeries, ulRuns, sizeof(RTL_BITMAP_RUN), NTDLL_RunSortFn); - - /* Replace last run if this one is bigger */ - if (ulSize > lpSeries[ulRuns - 1].NumberOfBits) - { - lpSeries[ulRuns - 1].StartingIndex = ulNextPos; - lpSeries[ulRuns - 1].NumberOfBits = ulSize; - - /* We need to re-sort the array, _if_ we didn't leave it sorted */ - if (ulRuns > 1 && ulSize > lpSeries[ulRuns - 2].NumberOfBits) - bNeedSort = TRUE; - } - } - else - { - /* Append to found runs */ - lpSeries[ulRuns].StartingIndex = ulNextPos; - lpSeries[ulRuns].NumberOfBits = ulSize; - ulRuns++; - - if (!bLongest && ulRuns == ulCount) - break; - } - ulPos = ulNextPos + ulSize; - } - return ulRuns; -} - -static -ULONG -NTDLL_FindSetRun(PRTL_BITMAP lpBits, - ULONG ulStart, - PULONG lpSize) -{ - LPBYTE lpOut; - ULONG ulFoundAt = 0, ulCount = 0; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - while (1) - { - /* Check bits in first byte */ - const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; - const BYTE bFirst = *lpOut & bMask; - - if (bFirst) - { - /* Have a set bit in first byte */ - if (bFirst != bMask) - { - /* Not every bit is set */ - ULONG ulOffset; - - if (bFirst & 0x0f) - ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; - else - ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; - ulStart += ulOffset; - ulFoundAt = ulStart; - for (;ulOffset < 8; ulOffset++) - { - if (!(bFirst & (1 << ulOffset))) - { - *lpSize = ulCount; - return ulFoundAt; /* Set from start, but not until the end */ - } - ulCount++; - ulStart++; - } - /* Set to the end - go on to count further bits */ - lpOut++; - break; - } - /* every bit from start until the end of the byte is set */ - ulFoundAt = ulStart; - ulCount = 8 - (ulStart & 7); - ulStart = (ulStart & ~7u) + 8; - lpOut++; - break; - } - ulStart = (ulStart & ~7u) + 8; - lpOut++; - if (ulStart >= lpBits->SizeOfBitMap) - return ~0U; - } - - /* Count blocks of 8 set bits */ - while (*lpOut == 0xff) - { - ulCount += 8; - ulStart += 8; - if (ulStart >= lpBits->SizeOfBitMap) - { - *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); - return ulFoundAt; - } - lpOut++; - } - - /* Count remaining contiguous bits, if any */ - if (*lpOut & 1) - { - ULONG ulOffset = 0; - - for (;ulOffset < 7u; ulOffset++) - { - if (!(*lpOut & (1 << ulOffset))) - break; - ulCount++; - } - } - *lpSize = ulCount; - return ulFoundAt; -} - -static -ULONG -NTDLL_FindClearRun(PRTL_BITMAP lpBits, - ULONG ulStart, - PULONG lpSize) -{ - LPBYTE lpOut; - ULONG ulFoundAt = 0, ulCount = 0; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - while (1) - { - /* Check bits in first byte */ - const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; - const BYTE bFirst = (~*lpOut) & bMask; - - if (bFirst) - { - /* Have a clear bit in first byte */ - if (bFirst != bMask) - { - /* Not every bit is clear */ - ULONG ulOffset; - - if (bFirst & 0x0f) - ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; - else - ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; - ulStart += ulOffset; - ulFoundAt = ulStart; - for (;ulOffset < 8; ulOffset++) - { - if (!(bFirst & (1 << ulOffset))) - { - *lpSize = ulCount; - return ulFoundAt; /* Clear from start, but not until the end */ - } - ulCount++; - ulStart++; - } - /* Clear to the end - go on to count further bits */ - lpOut++; - break; - } - /* Every bit from start until the end of the byte is clear */ - ulFoundAt = ulStart; - ulCount = 8 - (ulStart & 7); - ulStart = (ulStart & ~7u) + 8; - lpOut++; - break; - } - ulStart = (ulStart & ~7u) + 8; - lpOut++; - if (ulStart >= lpBits->SizeOfBitMap) - return ~0U; - } - - /* Count blocks of 8 clear bits */ - while (!*lpOut) - { - ulCount += 8; - ulStart += 8; - if (ulStart >= lpBits->SizeOfBitMap) - { - *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); - return ulFoundAt; - } - lpOut++; - } - - /* Count remaining contiguous bits, if any */ - if (!(*lpOut & 1)) - { - ULONG ulOffset = 0; - - for (;ulOffset < 7u; ulOffset++) - { - if (*lpOut & (1 << ulOffset)) - break; - ulCount++; - } - } - *lpSize = ulCount; - return ulFoundAt; -} - -/* FUNCTIONS ****************************************************************/ - -/* - * @implemented - */ -VOID -NTAPI -RtlInitializeBitMap(IN PRTL_BITMAP BitMapHeader, - IN PULONG BitMapBuffer, - IN ULONG SizeOfBitMap) -{ - /* Setup the bitmap header */ - BitMapHeader->SizeOfBitMap = SizeOfBitMap; - BitMapHeader->Buffer = BitMapBuffer; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -RtlAreBitsClear(IN PRTL_BITMAP BitMapHeader, - IN ULONG StartingIndex, - IN ULONG Length) -{ - LPBYTE lpOut; - ULONG ulRemainder; - - if (!BitMapHeader || !Length || - StartingIndex >= BitMapHeader->SizeOfBitMap || - Length > BitMapHeader->SizeOfBitMap - StartingIndex) - return FALSE; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); - - /* Check bits in first byte, if StartingIndex isn't a byte boundary */ - if (StartingIndex & 7) - { - if (Length > 7) - { - /* Check from start bit to the end of the byte */ - if (*lpOut & ((0xff << (StartingIndex & 7)) & 0xff)) - return FALSE; - lpOut++; - Length -= (8 - (StartingIndex & 7)); - } - else - { - /* Check from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[Length] << (StartingIndex & 7); - - if (*lpOut & (initialWord & 0xff)) - return FALSE; - if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8))) - return FALSE; - return TRUE; - } - } - - /* Check bits in blocks of 8 bytes */ - ulRemainder = Length & 7; - Length >>= 3; - while (Length--) - { - if (*lpOut++) - return FALSE; - } - - /* Check remaining bits, if any */ - if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder]) - return FALSE; - return TRUE; -} - - -/* - * @implemented - */ -BOOLEAN NTAPI -RtlAreBitsSet(PRTL_BITMAP BitMapHeader, - ULONG StartingIndex, - ULONG Length) -{ - LPBYTE lpOut; - ULONG ulRemainder; - - - if (!BitMapHeader || !Length || - StartingIndex >= BitMapHeader->SizeOfBitMap || - Length > BitMapHeader->SizeOfBitMap - StartingIndex) - return FALSE; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); - - /* Check bits in first byte, if StartingIndex isn't a byte boundary */ - if (StartingIndex & 7) - { - if (Length > 7) - { - /* Check from start bit to the end of the byte */ - if ((*lpOut & - ((0xff << (StartingIndex & 7))) & 0xff) != ((0xff << (StartingIndex & 7) & 0xff))) - return FALSE; - lpOut++; - Length -= (8 - (StartingIndex & 7)); - } - else - { - /* Check from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[Length] << (StartingIndex & 7); - - if ((*lpOut & (initialWord & 0xff)) != (initialWord & 0xff)) - return FALSE; - if ((initialWord & 0xff00) && - ((lpOut[1] & (initialWord >> 8)) != (initialWord >> 8))) - return FALSE; - return TRUE; - } - } - - /* Check bits in blocks of 8 bytes */ - ulRemainder = Length & 7; - Length >>= 3; - while (Length--) - { - if (*lpOut++ != 0xff) - return FALSE; - } - - /* Check remaining bits, if any */ - if (ulRemainder && - (*lpOut & NTDLL_maskBits[ulRemainder]) != NTDLL_maskBits[ulRemainder]) - return FALSE; - return TRUE; -} - - -/* - * @implemented - */ -VOID NTAPI -RtlClearAllBits(IN OUT PRTL_BITMAP BitMapHeader) -{ - memset(BitMapHeader->Buffer, 0, ((BitMapHeader->SizeOfBitMap + 31) & ~31) >> 3); -} - -/* - * @implemented - */ -VOID -NTAPI -RtlClearBit(PRTL_BITMAP BitMapHeader, - ULONG BitNumber) -{ - PULONG Ptr; - - if (BitNumber >= BitMapHeader->SizeOfBitMap) return; - - Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); - *Ptr &= ~(1 << (BitNumber % 32)); -} - -/* - * @implemented - */ -VOID -NTAPI -RtlClearBits(IN PRTL_BITMAP BitMapHeader, - IN ULONG StartingIndex, - IN ULONG NumberToClear) -{ - LPBYTE lpOut; - - if (!BitMapHeader || !NumberToClear || - StartingIndex >= BitMapHeader->SizeOfBitMap || - NumberToClear > BitMapHeader->SizeOfBitMap - StartingIndex) - return; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); - - /* Clear bits in first byte, if StartingIndex isn't a byte boundary */ - if (StartingIndex & 7) - { - if (NumberToClear > 7) - { - /* Clear from start bit to the end of the byte */ - *lpOut++ &= ~(0xff << (StartingIndex & 7)); - NumberToClear -= (8 - (StartingIndex & 7)); - } - else - { - /* Clear from the start bit, possibly into the next byte also */ - USHORT initialWord = ~(NTDLL_maskBits[NumberToClear] << (StartingIndex & 7)); - - *lpOut++ &= (initialWord & 0xff); - *lpOut &= (initialWord >> 8); - return; - } - } - - /* Clear bits (in blocks of 8) on whole byte boundaries */ - if (NumberToClear >> 3) - { - memset(lpOut, 0, NumberToClear >> 3); - lpOut = lpOut + (NumberToClear >> 3); - } - - /* Clear remaining bits, if any */ - if (NumberToClear & 0x7) - *lpOut &= ~NTDLL_maskBits[NumberToClear & 0x7]; -} - - -/* - * @implemented - */ -ULONG NTAPI -RtlFindClearBits(PRTL_BITMAP BitMapHeader, - ULONG NumberToFind, - ULONG HintIndex) -{ - ULONG ulPos, ulEnd; - - if (!BitMapHeader || !NumberToFind || NumberToFind > BitMapHeader->SizeOfBitMap) - return ~0U; - - ulEnd = BitMapHeader->SizeOfBitMap; - - if (HintIndex + NumberToFind > BitMapHeader->SizeOfBitMap) - HintIndex = 0; - - ulPos = HintIndex; - - while (ulPos < ulEnd) - { - /* FIXME: This could be made a _lot_ more efficient */ - if (RtlAreBitsClear(BitMapHeader, ulPos, NumberToFind)) - return ulPos; - - /* Start from the beginning if we hit the end and started from HintIndex */ - if (ulPos == ulEnd - 1 && HintIndex) - { - ulEnd = HintIndex; - ulPos = HintIndex = 0; - } - else - ulPos++; - } - return ~0U; -} - - - - - - - -/* - * @implemented - */ -ULONG NTAPI -RtlFindClearRuns(PRTL_BITMAP BitMapHeader, - PRTL_BITMAP_RUN RunArray, - ULONG SizeOfRunArray, - BOOLEAN LocateLongestRuns) -{ - return NTDLL_FindRuns(BitMapHeader, RunArray, SizeOfRunArray, LocateLongestRuns, NTDLL_FindClearRun); -} - - -/* - * @unimplemented - */ -ULONG NTAPI -RtlFindLastBackwardRunClear(IN PRTL_BITMAP BitMapHeader, - IN ULONG FromIndex, - IN PULONG StartingRunIndex) -{ - UNIMPLEMENTED; - return 0; -} - -/* - * @implemented - */ -ULONG NTAPI -RtlFindNextForwardRunClear(IN PRTL_BITMAP BitMapHeader, - IN ULONG FromIndex, - IN PULONG StartingRunIndex) -{ - ULONG ulSize = 0; - - if (BitMapHeader && FromIndex < BitMapHeader->SizeOfBitMap && StartingRunIndex) - *StartingRunIndex = NTDLL_FindClearRun(BitMapHeader, FromIndex, &ulSize); - - return ulSize; -} - -/* - * @implemented - */ -ULONG NTAPI -RtlFindFirstRunSet(IN PRTL_BITMAP BitMapHeader, - IN PULONG StartingIndex) -{ - ULONG Size; - ULONG Index; - ULONG Count; - PULONG Ptr; - ULONG Mask; - - Size = BitMapHeader->SizeOfBitMap; - if (*StartingIndex > Size) - { - *StartingIndex = (ULONG)-1; - return 0; - } - - Index = *StartingIndex; - Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32); - Mask = 1 << (Index & 0x1F); - - /* Skip clear bits */ - for (; Index < Size && ~*Ptr & Mask; Index++) - { - Mask <<= 1; - - if (Mask == 0) - { - Mask = 1; - Ptr++; - } - } - - /* Return index of first set bit */ - if (Index >= Size) - { - *StartingIndex = (ULONG)-1; - return 0; - } - else - { - *StartingIndex = Index; - } - - /* Count set bits */ - for (Count = 0; Index < Size && *Ptr & Mask; Index++) - { - Count++; - Mask <<= 1; - - if (Mask == 0) - { - Mask = 1; - Ptr++; - } - } - - return Count; -} - - -/* - * @implemented - */ -ULONG NTAPI -RtlFindLongestRunClear(PRTL_BITMAP BitMapHeader, - PULONG StartingIndex) -{ - RTL_BITMAP_RUN br; - - if (RtlFindClearRuns(BitMapHeader, &br, 1, TRUE) == 1) - { - if (StartingIndex) - *StartingIndex = br.StartingIndex; - return br.NumberOfBits; - } - return 0; -} - - -/* - * @implemented - */ -ULONG NTAPI -RtlFindLongestRunSet(PRTL_BITMAP BitMapHeader, - PULONG StartingIndex) -{ - RTL_BITMAP_RUN br; - - if (NTDLL_FindRuns(BitMapHeader, &br, 1, TRUE, NTDLL_FindSetRun) == 1) - { - if (StartingIndex) - *StartingIndex = br.StartingIndex; - return br.NumberOfBits; - } - return 0; -} - - -/* - * @implemented - */ -ULONG NTAPI -RtlFindSetBits(PRTL_BITMAP BitMapHeader, - ULONG NumberToFind, - ULONG HintIndex) -{ - ULONG ulPos, ulEnd; - - if (!BitMapHeader || !NumberToFind || NumberToFind > BitMapHeader->SizeOfBitMap) - return ~0U; - - ulEnd = BitMapHeader->SizeOfBitMap; - - if (HintIndex + NumberToFind > BitMapHeader->SizeOfBitMap) - HintIndex = 0; - - ulPos = HintIndex; - - while (ulPos < ulEnd) - { - /* FIXME: This could be made a _lot_ more efficient */ - if (RtlAreBitsSet(BitMapHeader, ulPos, NumberToFind)) - return ulPos; - - /* Start from the beginning if we hit the end and had a hint */ - if (ulPos == ulEnd - 1 && HintIndex) - { - ulEnd = HintIndex; - ulPos = HintIndex = 0; - } - else - ulPos++; - } - return ~0U; -} - - -/* - * @implemented - */ -ULONG NTAPI -RtlFindSetBitsAndClear(PRTL_BITMAP BitMapHeader, - ULONG NumberToFind, - ULONG HintIndex) -{ - ULONG ulPos; - - ulPos = RtlFindSetBits(BitMapHeader, NumberToFind, HintIndex); - if (ulPos != ~0U) - RtlClearBits(BitMapHeader, ulPos, NumberToFind); - return ulPos; -} - - - - - -/* - * @implemented - */ -ULONG NTAPI -RtlNumberOfSetBits(PRTL_BITMAP BitMapHeader) -{ - ULONG ulSet = 0; - - if (BitMapHeader) - { - LPBYTE lpOut = (BYTE *)BitMapHeader->Buffer; - ULONG Length, ulRemainder; - BYTE bMasked; - - Length = BitMapHeader->SizeOfBitMap >> 3; - ulRemainder = BitMapHeader->SizeOfBitMap & 0x7; - - while (Length--) - { - ulSet += NTDLL_nibbleBitCount[*lpOut >> 4]; - ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf]; - lpOut++; - } - - bMasked = *lpOut & NTDLL_maskBits[ulRemainder]; - ulSet += NTDLL_nibbleBitCount[bMasked >> 4]; - ulSet += NTDLL_nibbleBitCount[bMasked & 0xf]; - } - return ulSet; -} - - -/* - * @implemented - */ -VOID NTAPI -RtlSetAllBits(IN OUT PRTL_BITMAP BitMapHeader) -{ - memset(BitMapHeader->Buffer, 0xff, ((BitMapHeader->SizeOfBitMap + 31) & ~31) >> 3); -} - - -/* - * @implemented - */ -VOID NTAPI -RtlSetBit(PRTL_BITMAP BitMapHeader, - ULONG BitNumber) -{ - PULONG Ptr; - - if (BitNumber >= BitMapHeader->SizeOfBitMap) - return; - - Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); - - *Ptr |= (1 << (BitNumber % 32)); -} - - -/* - * @implemented - */ -VOID NTAPI -RtlSetBits(PRTL_BITMAP BitMapHeader, - ULONG StartingIndex, - ULONG NumberToSet) -{ - LPBYTE lpOut; - - if (!BitMapHeader || !NumberToSet || - StartingIndex >= BitMapHeader->SizeOfBitMap || - NumberToSet > BitMapHeader->SizeOfBitMap - StartingIndex) - return; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); - - /* Set bits in first byte, if StartingIndex isn't a byte boundary */ - if (StartingIndex & 7) - { - if (NumberToSet > 7) - { - /* Set from start bit to the end of the byte */ - *lpOut++ |= 0xff << (StartingIndex & 7); - NumberToSet -= (8 - (StartingIndex & 7)); - } - else - { - /* Set from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[NumberToSet] << (StartingIndex & 7); - - *lpOut++ |= (initialWord & 0xff); - *lpOut |= (initialWord >> 8); - return; - } - } - - /* Set bits up to complete byte count */ - if (NumberToSet >> 3) - { - memset(lpOut, 0xff, NumberToSet >> 3); - lpOut = lpOut + (NumberToSet >> 3); - } - - /* Set remaining bits, if any */ - *lpOut |= NTDLL_maskBits[NumberToSet & 0x7]; -} - - -/* - * @implemented - */ -BOOLEAN NTAPI -RtlTestBit(PRTL_BITMAP BitMapHeader, - ULONG BitNumber) -{ - PULONG Ptr; - - if (BitNumber >= BitMapHeader->SizeOfBitMap) - return FALSE; - - Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); - - return (*Ptr & (1 << (BitNumber % 32))); -} - -/* - * @implemented - */ -ULONG NTAPI -RtlFindFirstRunClear(PRTL_BITMAP BitMapHeader, - PULONG StartingIndex) -{ - return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex); -} - -/* - * @implemented - */ -ULONG NTAPI -RtlNumberOfClearBits(PRTL_BITMAP BitMapHeader) -{ - - if (BitMapHeader) - return BitMapHeader->SizeOfBitMap - RtlNumberOfSetBits(BitMapHeader); - return 0; -} - -/* - * @implemented - */ -ULONG NTAPI -RtlFindClearBitsAndSet(PRTL_BITMAP BitMapHeader, - ULONG NumberToFind, - ULONG HintIndex) -{ - ULONG ulPos; - - ulPos = RtlFindClearBits(BitMapHeader, NumberToFind, HintIndex); - if (ulPos != ~0U) - RtlSetBits(BitMapHeader, ulPos, NumberToFind); - return ulPos; -} - -/* - * @implemented - */ -CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong) -{ - signed char ret = 32; - DWORD dw; - - if (!(dw = (ulLong >> 32))) - { - ret = 0; - dw = (DWORD)ulLong; - } - if (dw & 0xffff0000) - { - dw >>= 16; - ret += 16; - } - if (dw & 0xff00) - { - dw >>= 8; - ret += 8; - } - if (dw & 0xf0) - { - dw >>= 4; - ret += 4; - } - return ret + NTDLL_mostSignificant[dw]; -} - -/* - * @implemented - */ -CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong) -{ - signed char ret = 0; - DWORD dw; - - if (!(dw = (DWORD)ulLong)) - { - ret = 32; - if (!(dw = ulLong >> 32)) return -1; - } - if (!(dw & 0xffff)) - { - dw >>= 16; - ret += 16; - } - if (!(dw & 0xff)) - { - dw >>= 8; - ret += 8; - } - if (!(dw & 0x0f)) - { - dw >>= 4; - ret += 4; - } - return ret + NTDLL_leastSignificant[dw & 0x0f]; -} - -/* EOF */ diff --git a/reactos/tools/ppc.lost+found/link-ntoskrnl b/reactos/tools/ppc.lost+found/link-ntoskrnl index 905b6ecf5d4..eeacb95ef8d 100755 --- a/reactos/tools/ppc.lost+found/link-ntoskrnl +++ b/reactos/tools/ppc.lost+found/link-ntoskrnl @@ -1,3 +1,174 @@ #!/bin/sh -xv -reactos-powerpc-gcc --begin-group -v -Wl,--subsystem,native -Wl,--entry,NtProcessStartup -Wl,--image-base,0x80000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe obj-ppc/ntoskrnl/ke/powerpc/main_asm.o obj-ppc/ntoskrnl/ke/apc.o obj-ppc/ntoskrnl/ke/bug.o obj-ppc/ntoskrnl/ke/clock.o obj-ppc/ntoskrnl/ke/device.o obj-ppc/ntoskrnl/ke/dpc.o obj-ppc/ntoskrnl/ke/event.o obj-ppc/ntoskrnl/ke/exception.o obj-ppc/ntoskrnl/ke/gate.o obj-ppc/ntoskrnl/ke/gmutex.o obj-ppc/ntoskrnl/ke/ipi.o obj-ppc/ntoskrnl/ke/kqueue.o obj-ppc/ntoskrnl/ke/kthread.o obj-ppc/ntoskrnl/ke/main.o obj-ppc/ntoskrnl/ke/mutex.o obj-ppc/ntoskrnl/ke/process.o obj-ppc/ntoskrnl/ke/profile.o obj-ppc/ntoskrnl/ke/queue.o obj-ppc/ntoskrnl/ke/sem.o obj-ppc/ntoskrnl/ke/spinlock.o obj-ppc/ntoskrnl/ke/timer.o obj-ppc/ntoskrnl/ke/usercall.o obj-ppc/ntoskrnl/ke/wait.o obj-ppc/ntoskrnl/cc/cacheman.o obj-ppc/ntoskrnl/cc/copy.o obj-ppc/ntoskrnl/cc/fs.o obj-ppc/ntoskrnl/cc/mdl.o obj-ppc/ntoskrnl/cc/pin.o obj-ppc/ntoskrnl/cc/view.o obj-ppc/ntoskrnl/cm/import.o obj-ppc/ntoskrnl/cm/ntfunc.o obj-ppc/ntoskrnl/cm/regfile.o obj-ppc/ntoskrnl/cm/registry.o obj-ppc/ntoskrnl/cm/regobj.o obj-ppc/ntoskrnl/dbgk/dbgkutil.o obj-ppc/ntoskrnl/dbgk/debug.o obj-ppc/ntoskrnl/ex/atom.o obj-ppc/ntoskrnl/ex/callback.o obj-ppc/ntoskrnl/ex/dbgctrl.o obj-ppc/ntoskrnl/ex/error.o obj-ppc/ntoskrnl/ex/event.o obj-ppc/ntoskrnl/ex/evtpair.o obj-ppc/ntoskrnl/ex/fmutex.o obj-ppc/ntoskrnl/ex/handle.o obj-ppc/ntoskrnl/ex/init.o obj-ppc/ntoskrnl/ex/lookas.o obj-ppc/ntoskrnl/ex/mutant.o obj-ppc/ntoskrnl/ex/power.o obj-ppc/ntoskrnl/ex/pushlock.o obj-ppc/ntoskrnl/ex/profile.o obj-ppc/ntoskrnl/ex/resource.o obj-ppc/ntoskrnl/ex/rundown.o obj-ppc/ntoskrnl/ex/sem.o obj-ppc/ntoskrnl/ex/sysinfo.o obj-ppc/ntoskrnl/ex/time.o obj-ppc/ntoskrnl/ex/timer.o obj-ppc/ntoskrnl/ex/uuid.o obj-ppc/ntoskrnl/ex/win32k.o obj-ppc/ntoskrnl/ex/work.o obj-ppc/ntoskrnl/ex/zone.o obj-ppc/ntoskrnl/ex/zw.o obj-ppc/ntoskrnl/fs/context.o obj-ppc/ntoskrnl/fs/fastio.o obj-ppc/ntoskrnl/fs/filelock.o obj-ppc/ntoskrnl/fs/mcb.o obj-ppc/ntoskrnl/fs/name.o obj-ppc/ntoskrnl/fs/notify.o obj-ppc/ntoskrnl/fs/oplock.o obj-ppc/ntoskrnl/fs/pool.o obj-ppc/ntoskrnl/fs/tunnel.o obj-ppc/ntoskrnl/fs/unc.o obj-ppc/ntoskrnl/fs/util.o obj-ppc/ntoskrnl/inbv/inbv.o obj-ppc/ntoskrnl/io/adapter.o obj-ppc/ntoskrnl/io/arcname.o obj-ppc/ntoskrnl/io/bootlog.o obj-ppc/ntoskrnl/io/controller.o obj-ppc/ntoskrnl/io/device.o obj-ppc/ntoskrnl/io/deviface.o obj-ppc/ntoskrnl/io/disk.o obj-ppc/ntoskrnl/io/driver.o obj-ppc/ntoskrnl/io/efi.o obj-ppc/ntoskrnl/io/error.o obj-ppc/ntoskrnl/io/event.o obj-ppc/ntoskrnl/io/fs.o obj-ppc/ntoskrnl/io/iocomp.o obj-ppc/ntoskrnl/io/iomgr.o obj-ppc/ntoskrnl/io/iowork.o obj-ppc/ntoskrnl/io/irp.o obj-ppc/ntoskrnl/io/irq.o obj-ppc/ntoskrnl/io/mdl.o obj-ppc/ntoskrnl/io/plugplay.o obj-ppc/ntoskrnl/io/pnpdma.o obj-ppc/ntoskrnl/io/pnpmgr.o obj-ppc/ntoskrnl/io/pnpnotify.o obj-ppc/ntoskrnl/io/pnpreport.o obj-ppc/ntoskrnl/io/pnproot.o obj-ppc/ntoskrnl/io/rawfs.o obj-ppc/ntoskrnl/io/remlock.o obj-ppc/ntoskrnl/io/resource.o obj-ppc/ntoskrnl/io/share.o obj-ppc/ntoskrnl/io/symlink.o obj-ppc/ntoskrnl/io/timer.o obj-ppc/ntoskrnl/io/vpb.o obj-ppc/ntoskrnl/io/wmi.o obj-ppc/ntoskrnl/io/file.o obj-ppc/ntoskrnl/kd/wrappers/bochs.o obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o obj-ppc/ntoskrnl/kd/kdinit.o obj-ppc/ntoskrnl/kd/kdio.o obj-ppc/ntoskrnl/kd/kdmain.o obj-ppc/ntoskrnl/ldr/loader.o obj-ppc/ntoskrnl/ldr/rtl.o obj-ppc/ntoskrnl/lpc/close.o obj-ppc/ntoskrnl/lpc/complete.o obj-ppc/ntoskrnl/lpc/connect.o obj-ppc/ntoskrnl/lpc/create.o obj-ppc/ntoskrnl/lpc/listen.o obj-ppc/ntoskrnl/lpc/port.o obj-ppc/ntoskrnl/lpc/query.o obj-ppc/ntoskrnl/lpc/queue.o obj-ppc/ntoskrnl/lpc/receive.o obj-ppc/ntoskrnl/lpc/reply.o obj-ppc/ntoskrnl/lpc/send.o obj-ppc/ntoskrnl/mm/anonmem.o obj-ppc/ntoskrnl/mm/aspace.o obj-ppc/ntoskrnl/mm/balance.o obj-ppc/ntoskrnl/mm/cont.o obj-ppc/ntoskrnl/mm/drvlck.o obj-ppc/ntoskrnl/mm/freelist.o obj-ppc/ntoskrnl/mm/iospace.o obj-ppc/ntoskrnl/mm/kmap.o obj-ppc/ntoskrnl/mm/marea.o obj-ppc/ntoskrnl/mm/mdl.o obj-ppc/ntoskrnl/mm/mm.o obj-ppc/ntoskrnl/mm/process.o obj-ppc/ntoskrnl/mm/mminit.o obj-ppc/ntoskrnl/mm/mpw.o obj-ppc/ntoskrnl/mm/ncache.o obj-ppc/ntoskrnl/mm/npool.o obj-ppc/ntoskrnl/mm/pagefile.o obj-ppc/ntoskrnl/mm/pageop.o obj-ppc/ntoskrnl/mm/pager.o obj-ppc/ntoskrnl/mm/pagfault.o obj-ppc/ntoskrnl/mm/paging.o obj-ppc/ntoskrnl/mm/pe.o obj-ppc/ntoskrnl/mm/physical.o obj-ppc/ntoskrnl/mm/pool.o obj-ppc/ntoskrnl/mm/ppool.o obj-ppc/ntoskrnl/mm/region.o obj-ppc/ntoskrnl/mm/rmap.o obj-ppc/ntoskrnl/mm/section.o obj-ppc/ntoskrnl/mm/verifier.o obj-ppc/ntoskrnl/mm/virtual.o obj-ppc/ntoskrnl/mm/wset.o obj-ppc/ntoskrnl/mm/elf32.o obj-ppc/ntoskrnl/mm/elf64.o obj-ppc/ntoskrnl/ob/obdir.o obj-ppc/ntoskrnl/ob/obinit.o obj-ppc/ntoskrnl/ob/obhandle.o obj-ppc/ntoskrnl/ob/obname.o obj-ppc/ntoskrnl/ob/oblife.o obj-ppc/ntoskrnl/ob/obref.o obj-ppc/ntoskrnl/ob/sdcache.o obj-ppc/ntoskrnl/ob/symlink.o obj-ppc/ntoskrnl/po/power.o obj-ppc/ntoskrnl/ps/debug.o obj-ppc/ntoskrnl/ps/idle.o obj-ppc/ntoskrnl/ps/job.o obj-ppc/ntoskrnl/ps/kill.o obj-ppc/ntoskrnl/ps/locale.o obj-ppc/ntoskrnl/ps/notify.o obj-ppc/ntoskrnl/ps/process.o obj-ppc/ntoskrnl/ps/psmgr.o obj-ppc/ntoskrnl/ps/query.o obj-ppc/ntoskrnl/ps/quota.o obj-ppc/ntoskrnl/ps/security.o obj-ppc/ntoskrnl/ps/suspend.o obj-ppc/ntoskrnl/ps/thread.o obj-ppc/ntoskrnl/ps/win32.o obj-ppc/ntoskrnl/rtl/libsupp.o obj-ppc/ntoskrnl/rtl/misc.o obj-ppc/ntoskrnl/rtl/nls.o obj-ppc/ntoskrnl/rtl/regio.o obj-ppc/ntoskrnl/rtl/strtok.o obj-ppc/ntoskrnl/se/access.o obj-ppc/ntoskrnl/se/acl.o obj-ppc/ntoskrnl/se/audit.o obj-ppc/ntoskrnl/se/lsa.o obj-ppc/ntoskrnl/se/luid.o obj-ppc/ntoskrnl/se/priv.o obj-ppc/ntoskrnl/se/sd.o obj-ppc/ntoskrnl/se/semgr.o obj-ppc/ntoskrnl/se/sid.o obj-ppc/ntoskrnl/se/token.o obj-ppc/ntoskrnl/ntoskrnl.coff obj-ppc/ntoskrnl/kdbg/kdb_symbols.o obj-ppc/lib/drivers/csq/csq.a obj-ppc/hal/hal/libhal.a obj-ppc/lib/kjs/kjs.a obj-ppc/lib/pseh/pseh.a obj-ppc/lib/rtl/rtl.a obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/wdmguid/wdmguid.a -nostartfiles -nostdlib -lgcc -g --end-group +reactos-powerpc-ld \ + -v \ + --subsystem native \ + --entry NtProcessStartup \ + --image-base 0x80000000 \ + --file-alignment 0x1000 \ + --section-alignment 0x1000 \ + -nostartfiles -shared \ + ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe \ + obj-ppc/ntoskrnl/ke/powerpc/main_asm.o \ + obj-ppc/ntoskrnl/ke/apc.o \ + obj-ppc/ntoskrnl/ke/bug.o \ + obj-ppc/ntoskrnl/ke/clock.o \ + obj-ppc/ntoskrnl/ke/device.o \ + obj-ppc/ntoskrnl/ke/dpc.o \ + obj-ppc/ntoskrnl/ke/event.o \ + obj-ppc/ntoskrnl/ke/exception.o \ + obj-ppc/ntoskrnl/ke/gate.o \ + obj-ppc/ntoskrnl/ke/gmutex.o \ + obj-ppc/ntoskrnl/ke/ipi.o \ + obj-ppc/ntoskrnl/ke/kqueue.o \ + obj-ppc/ntoskrnl/ke/kthread.o \ + obj-ppc/ntoskrnl/ke/mutex.o \ + obj-ppc/ntoskrnl/ke/process.o \ + obj-ppc/ntoskrnl/ke/profile.o \ + obj-ppc/ntoskrnl/ke/queue.o \ + obj-ppc/ntoskrnl/ke/sem.o \ + obj-ppc/ntoskrnl/ke/spinlock.o \ + obj-ppc/ntoskrnl/ke/timer.o \ + obj-ppc/ntoskrnl/ke/usercall.o \ + obj-ppc/ntoskrnl/ke/wait.o \ + obj-ppc/ntoskrnl/cc/cacheman.o \ + obj-ppc/ntoskrnl/cc/copy.o \ + obj-ppc/ntoskrnl/cc/fs.o \ + obj-ppc/ntoskrnl/cc/mdl.o \ + obj-ppc/ntoskrnl/cc/pin.o \ + obj-ppc/ntoskrnl/cc/view.o \ + obj-ppc/ntoskrnl/cm/import.o \ + obj-ppc/ntoskrnl/cm/ntfunc.o \ + obj-ppc/ntoskrnl/cm/regfile.o \ + obj-ppc/ntoskrnl/cm/registry.o \ + obj-ppc/ntoskrnl/cm/regobj.o \ + obj-ppc/ntoskrnl/dbgk/dbgkutil.o \ + obj-ppc/ntoskrnl/dbgk/debug.o \ + obj-ppc/ntoskrnl/ex/atom.o \ + obj-ppc/ntoskrnl/ex/callback.o \ + obj-ppc/ntoskrnl/ex/dbgctrl.o \ + obj-ppc/ntoskrnl/ex/error.o \ + obj-ppc/ntoskrnl/ex/event.o \ + obj-ppc/ntoskrnl/ex/evtpair.o \ + obj-ppc/ntoskrnl/ex/fmutex.o \ + obj-ppc/ntoskrnl/ex/handle.o \ + obj-ppc/ntoskrnl/ex/init.o \ + obj-ppc/ntoskrnl/ex/lookas.o \ + obj-ppc/ntoskrnl/ex/mutant.o \ + obj-ppc/ntoskrnl/ex/power.o \ + obj-ppc/ntoskrnl/ex/pushlock.o \ + obj-ppc/ntoskrnl/ex/profile.o \ + obj-ppc/ntoskrnl/ex/resource.o \ + obj-ppc/ntoskrnl/ex/rundown.o \ + obj-ppc/ntoskrnl/ex/sem.o \ + obj-ppc/ntoskrnl/ex/sysinfo.o \ + obj-ppc/ntoskrnl/ex/time.o \ + obj-ppc/ntoskrnl/ex/timer.o \ + obj-ppc/ntoskrnl/ex/uuid.o \ + obj-ppc/ntoskrnl/ex/win32k.o \ + obj-ppc/ntoskrnl/ex/work.o \ + obj-ppc/ntoskrnl/ex/zone.o \ + obj-ppc/ntoskrnl/ex/zw.o \ + obj-ppc/ntoskrnl/fs/context.o \ + obj-ppc/ntoskrnl/fs/fastio.o \ + obj-ppc/ntoskrnl/fs/filelock.o \ + obj-ppc/ntoskrnl/fs/mcb.o \ + obj-ppc/ntoskrnl/fs/name.o \ + obj-ppc/ntoskrnl/fs/notify.o \ + obj-ppc/ntoskrnl/fs/oplock.o \ + obj-ppc/ntoskrnl/fs/pool.o \ + obj-ppc/ntoskrnl/fs/tunnel.o \ + obj-ppc/ntoskrnl/fs/unc.o \ + obj-ppc/ntoskrnl/fs/util.o \ + obj-ppc/ntoskrnl/inbv/inbv.o \ + obj-ppc/ntoskrnl/io/iomgr/*.o \ + obj-ppc/ntoskrnl/io/pnpmgr/*.o \ + obj-ppc/ntoskrnl/kd/wrappers/bochs.o \ + obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o \ + obj-ppc/ntoskrnl/kd/kdinit.o \ + obj-ppc/ntoskrnl/kd/kdio.o \ + obj-ppc/ntoskrnl/kd/kdmain.o \ + obj-ppc/ntoskrnl/ldr/loader.o \ + obj-ppc/ntoskrnl/ldr/rtl.o \ + obj-ppc/ntoskrnl/lpc/close.o \ + obj-ppc/ntoskrnl/lpc/complete.o \ + obj-ppc/ntoskrnl/lpc/connect.o \ + obj-ppc/ntoskrnl/lpc/create.o \ + obj-ppc/ntoskrnl/lpc/listen.o \ + obj-ppc/ntoskrnl/lpc/port.o \ + obj-ppc/ntoskrnl/lpc/query.o \ + obj-ppc/ntoskrnl/lpc/queue.o \ + obj-ppc/ntoskrnl/lpc/receive.o \ + obj-ppc/ntoskrnl/lpc/reply.o \ + obj-ppc/ntoskrnl/lpc/send.o \ + obj-ppc/ntoskrnl/mm/anonmem.o \ + obj-ppc/ntoskrnl/mm/aspace.o \ + obj-ppc/ntoskrnl/mm/balance.o \ + obj-ppc/ntoskrnl/mm/cont.o \ + obj-ppc/ntoskrnl/mm/drvlck.o \ + obj-ppc/ntoskrnl/mm/freelist.o \ + obj-ppc/ntoskrnl/mm/iospace.o \ + obj-ppc/ntoskrnl/mm/kmap.o \ + obj-ppc/ntoskrnl/mm/marea.o \ + obj-ppc/ntoskrnl/mm/mdl.o \ + obj-ppc/ntoskrnl/mm/mm.o \ + obj-ppc/ntoskrnl/mm/process.o \ + obj-ppc/ntoskrnl/mm/mminit.o \ + obj-ppc/ntoskrnl/mm/mpw.o \ + obj-ppc/ntoskrnl/mm/ncache.o \ + obj-ppc/ntoskrnl/mm/npool.o \ + obj-ppc/ntoskrnl/mm/pagefile.o \ + obj-ppc/ntoskrnl/mm/pageop.o \ + obj-ppc/ntoskrnl/mm/pager.o \ + obj-ppc/ntoskrnl/mm/pagfault.o \ + obj-ppc/ntoskrnl/mm/paging.o \ + obj-ppc/ntoskrnl/mm/pe.o \ + obj-ppc/ntoskrnl/mm/physical.o \ + obj-ppc/ntoskrnl/mm/pool.o \ + obj-ppc/ntoskrnl/mm/ppool.o \ + obj-ppc/ntoskrnl/mm/region.o \ + obj-ppc/ntoskrnl/mm/rmap.o \ + obj-ppc/ntoskrnl/mm/section.o \ + obj-ppc/ntoskrnl/mm/verifier.o \ + obj-ppc/ntoskrnl/mm/virtual.o \ + obj-ppc/ntoskrnl/mm/wset.o \ + obj-ppc/ntoskrnl/mm/elf32.o \ + obj-ppc/ntoskrnl/mm/elf64.o \ + obj-ppc/ntoskrnl/ob/obdir.o \ + obj-ppc/ntoskrnl/ob/obinit.o \ + obj-ppc/ntoskrnl/ob/obhandle.o \ + obj-ppc/ntoskrnl/ob/obname.o \ + obj-ppc/ntoskrnl/ob/oblife.o \ + obj-ppc/ntoskrnl/ob/obref.o \ + obj-ppc/ntoskrnl/ob/sdcache.o \ + obj-ppc/ntoskrnl/ob/symlink.o \ + obj-ppc/ntoskrnl/po/power.o \ + obj-ppc/ntoskrnl/ps/*.o \ + obj-ppc/ntoskrnl/rtl/libsupp.o \ + obj-ppc/ntoskrnl/rtl/misc.o \ + obj-ppc/ntoskrnl/rtl/nls.o \ + obj-ppc/ntoskrnl/rtl/regio.o \ + obj-ppc/ntoskrnl/rtl/strtok.o \ + obj-ppc/ntoskrnl/se/access.o \ + obj-ppc/ntoskrnl/se/acl.o \ + obj-ppc/ntoskrnl/se/audit.o \ + obj-ppc/ntoskrnl/se/lsa.o \ + obj-ppc/ntoskrnl/se/luid.o \ + obj-ppc/ntoskrnl/se/priv.o \ + obj-ppc/ntoskrnl/se/sd.o \ + obj-ppc/ntoskrnl/se/semgr.o \ + obj-ppc/ntoskrnl/se/sid.o \ + obj-ppc/ntoskrnl/se/token.o \ + obj-ppc/ntoskrnl/ntoskrnl.coff \ + obj-ppc/ntoskrnl/kdbg/kdb_symbols.o \ + obj-ppc/lib/drivers/csq/csq.a \ + obj-ppc/hal/hal/libhal.a \ + obj-ppc/lib/kjs/kjs.a \ + obj-ppc/lib/pseh/pseh.a \ + obj-ppc/lib/rtl/rtl.a \ + obj-ppc/lib/rossym/rossym.a \ + obj-ppc/lib/string/string.a \ + obj-ppc/lib/wdmguid/wdmguid.a \ + -nostartfiles \ + -nostdlib \ + -lgcc -g From 4a7321f583c64ba4982cc3813ee5c8852c79f383 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 9 Sep 2006 13:33:18 +0000 Subject: [PATCH 33/81] Removed workaround. Now know the cause. svn path=/branches/powerpc/; revision=23989 --- reactos/boot/freeldr/freeldr/fs/fat.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/fs/fat.c b/reactos/boot/freeldr/freeldr/fs/fat.c index efe765e3366..8319ee5c717 100644 --- a/reactos/boot/freeldr/freeldr/fs/fat.c +++ b/reactos/boot/freeldr/freeldr/fs/fat.c @@ -431,11 +431,7 @@ BOOLEAN FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySi // if (DirEntry->FileName[0] == '\0') { - /* A workaround for something I see ... there are - * zero entries in the middle of the dir. This is - * probably a bug in the way the fat fs was made. - */ - continue; //return FALSE; + return FALSE; } // From d8e8330fd4312ea0e60d85cca8365548083ff8d4 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 9 Sep 2006 13:49:03 +0000 Subject: [PATCH 34/81] Merge fix to ppc branch. svn path=/branches/powerpc/; revision=23991 --- reactos/boot/freeldr/freeldr/cache/cache.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/cache/cache.c b/reactos/boot/freeldr/freeldr/cache/cache.c index 1200c76a274..eaf024fbfb4 100644 --- a/reactos/boot/freeldr/freeldr/cache/cache.c +++ b/reactos/boot/freeldr/freeldr/cache/cache.c @@ -90,12 +90,11 @@ BOOLEAN CacheInitializeDrive(ULONG DriveNumber) CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber); CacheBlockCount = 0; - //CacheSizeLimit = GetSystemMemorySize() / 8; - CacheSizeLimit = 16 * 1024; + CacheSizeLimit = GetSystemMemorySize() / 8; CacheSizeCurrent = 0; - if (CacheSizeLimit < (16 * 1024)) + if (CacheSizeLimit < (64 * 1024)) { - CacheSizeLimit = (16 * 1024); + CacheSizeLimit = (64 * 1024); } CacheManagerInitialized = TRUE; @@ -139,7 +138,7 @@ BOOLEAN CacheReadDiskSectors(ULONG DiskNumber, ULONG StartSector, ULONG SectorCo SectorOffsetInStartBlock = StartSector % CacheManagerDrive.BlockSize; CopyLengthInStartBlock = (SectorCount > (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock)) ? (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock) : SectorCount; EndBlock = (StartSector + (SectorCount - 1)) / CacheManagerDrive.BlockSize; - SectorOffsetInEndBlock = (StartSector + SectorCount) % CacheManagerDrive.BlockSize; + SectorOffsetInEndBlock = 1 + (StartSector + (SectorCount - 1)) % CacheManagerDrive.BlockSize; BlockCount = (EndBlock - StartBlock) + 1; DbgPrint((DPRINT_CACHE, "StartBlock: %d SectorOffsetInStartBlock: %d CopyLengthInStartBlock: %d EndBlock: %d SectorOffsetInEndBlock: %d BlockCount: %d\n", StartBlock, SectorOffsetInStartBlock, CopyLengthInStartBlock, EndBlock, SectorOffsetInEndBlock, BlockCount)); @@ -285,7 +284,7 @@ BOOLEAN CacheForceDiskSectorsIntoCache(ULONG DiskNumber, ULONG StartSector, ULON // // Lock the sectors into the cache // - //CacheBlock->LockedInCache = TRUE; + CacheBlock->LockedInCache = TRUE; } return TRUE; From 716a587e865fdf8faff8a87a126cc0118c89681d Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 10 Sep 2006 05:58:10 +0000 Subject: [PATCH 35/81] Add -fshort-wchar svn path=/branches/powerpc/; revision=24014 --- reactos/ReactOS-ppc.rbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/ReactOS-ppc.rbuild b/reactos/ReactOS-ppc.rbuild index 34c5ccf381b..66537306733 100644 --- a/reactos/ReactOS-ppc.rbuild +++ b/reactos/ReactOS-ppc.rbuild @@ -25,6 +25,7 @@ + -fshort-wchar -fsigned-char From 1cc1dd2dddc9ff7918312800fc63545e3c273592 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 10 Sep 2006 06:07:08 +0000 Subject: [PATCH 36/81] Cleaning: tweaks. svn path=/branches/powerpc/; revision=24015 --- reactos/include/psdk/winnt.h | 2 +- reactos/include/psdk/winternl.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h index 9c95b6d6a63..20a7dc531ac 100644 --- a/reactos/include/psdk/winnt.h +++ b/reactos/include/psdk/winnt.h @@ -81,7 +81,7 @@ extern "C" { #ifndef VOID #define VOID void #endif -typedef signed char CHAR; +typedef char CHAR; typedef short SHORT; #ifndef LONG_DEFINED #define LONG_DEFINED diff --git a/reactos/include/psdk/winternl.h b/reactos/include/psdk/winternl.h index 4fbf08d5fcf..a1c43275ffd 100644 --- a/reactos/include/psdk/winternl.h +++ b/reactos/include/psdk/winternl.h @@ -1663,6 +1663,9 @@ extern LPSTR _strupr(LPSTR str); /* FIXME: Doesn't belong here */ #if defined(__i386__) && defined(__GNUC__) static inline void WINAPI DbgBreakPoint(void) { __asm__ __volatile__("int3"); } static inline void WINAPI DbgUserBreakPoint(void) { __asm__ __volatile__("int3"); } +#elif defined(__PowerPC__) && defined(__GNUC__) +static inline void WINAPI DbgBreakPoint(void) { __asm__ __volatile__("ti 0,7,0"); } +static inline void WINAPI DbgUserBreakPoint(void) { __asm__ __volatile__("ti 0,7,0"); } #else /* __i386__ && __GNUC__ */ void WINAPI DbgBreakPoint(void); void WINAPI DbgUserBreakPoint(void); From 5b6b2b681f076c8632ebf76c7808766eed9269c3 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 10 Sep 2006 20:43:26 +0000 Subject: [PATCH 37/81] Insert PTEs for 16 mb of kernel memory. Added function to insert PTEs in mmu.c mboot: complete the jump to kernel space. mach: add some memory to our initial map. - We should allow freeldr's mm to request more memory before giving up - We'll do well to allocate big blocks directly from ofw and small blocks from this heap implementation - We can't return *all* memory like it wants because we still need ofw, which may need to do allocation itself svn path=/branches/powerpc/; revision=24045 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 2 +- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 34 +++++-- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 91 +++++++++++++++++++ .../boot/freeldr/freeldr/arch/powerpc/mmu.h | 3 + 4 files changed, 122 insertions(+), 8 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 1c1d010e9d9..12f4bf96e65 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -21,7 +21,7 @@ #include "of.h" #include "mmu.h" -#define TOTAL_HEAP_NEEDED (32 * 1024 * 1024) /* 32 megs */ +#define TOTAL_HEAP_NEEDED (48 * 1024 * 1024) /* 48 megs */ extern void BootMain( LPSTR CmdLine ); extern PCHAR GetFreeLoaderVersionString(); diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index f0c9c652aef..6ad18c5e5d7 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -37,7 +37,7 @@ static PVOID KernelMemory = 0; /* Converts a Relative Address read from the Kernel into a Physical Address */ ULONG RaToPa(ULONG p) { - return PpcVirt2phys((ULONG)(KernelMemory) + p, 0); + return (ULONG)(KernelMemory) + p; } /* Converts a Phsyical Address Pointer into a Page Frame Number */ @@ -67,6 +67,8 @@ ULONG RaToPa(ULONG p) { #define ApicPageTableIndexPae (APIC_BASE >> 21) +#define BAT_GRANULARITY (64 * 1024) +#define KernelMemorySize (16 * 1024 * 1024) #define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase /* Load Address of Next Module */ @@ -102,10 +104,30 @@ ULONG_PTR KernelEntry; * None. * *--*/ + +typedef void (*KernelEntryFn)( void * ); + VOID NTAPI FrLdrStartup(ULONG Magic) { + KernelEntryFn KernelEntryAddress = + (KernelEntryFn)(KernelEntry + KernelBase); + ULONG_PTR PhysAddr, i; + + for( i = 0; i < KernelMemorySize; i+=1<OptionalHeader.AddressOfEntryPoint); - printf("RaToPa(%x + %x) -> %x\n", - KernelMemory, - NtHeader->OptionalHeader.AddressOfEntryPoint, - KernelEntry); + KernelEntry = NtHeader->OptionalHeader.AddressOfEntryPoint; /* Load the file image */ FsReadFile(KernelImage, ImageSize, NULL, KernelMemory); diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c index beca13d0a9a..39f588fba35 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -23,6 +23,23 @@ __asm__("\t.globl GetPhys\n" "blr" ); +__asm__("\t.globl SetPhys\n" + "SetPhys:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "stw 4,0(3)\n\t" /* Get actual value at phys addr r3 */ + "mtmsr 5\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + inline int GetSR(int n) { register int res asm ("r3"); switch( n ) { @@ -123,6 +140,51 @@ inline void GetBat( int bat, int inst, int *batHi, int *batLo ) { *batLo = bl; } +inline void SetBat( int bat, int inst, int batHi, int batLo ) { + register int bh asm("r3"), bl asm("r4"); + bh = batHi; + bl = batLo; + if( inst ) { + switch( bat ) { + case 0: + __asm__("mtibatu 0,3"); + __asm__("mtibatl 0,4"); + break; + case 1: + __asm__("mtibatu 1,3"); + __asm__("mtibatl 1,4"); + break; + case 2: + __asm__("mtibatu 2,3"); + __asm__("mtibatl 2,4"); + break; + case 3: + __asm__("mtibatu 3,3"); + __asm__("mtibatl 3,4"); + break; + } + } else { + switch( bat ) { + case 0: + __asm__("mtdbatu 0,3"); + __asm__("mtdbatl 0,4"); + break; + case 1: + __asm__("mtdbatu 1,3"); + __asm__("mtdbatl 1,4"); + break; + case 2: + __asm__("mtdbatu 2,3"); + __asm__("mtdbatl 2,4"); + break; + case 3: + __asm__("mtdbatu 3,3"); + __asm__("mtdbatl 3,4"); + break; + } + } +} + inline int GetSDR1() { register int res asm("r3"); __asm__("mfsdr1 3"); @@ -191,3 +253,32 @@ int PpcVirt2phys( int virt, int inst ) { return virt; } } + +/* Add a new page table entry for the indicated mapping */ +BOOLEAN InsertPageEntry( int virt, int phys ) { + int i, ptehi, ptelo; + int sdr1 = GetSDR1(); + int sr = GetSR( (virt >> 28) & 0xf ); + int vsid = sr & 0xfffffff; + int physbase = sdr1 & ~0xffff; + int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; + int valo = (vsid << 28) | (virt & 0xfffffff); + int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); + int ptegaddr = ((hashmask & hash) * 64) + physbase; + + for( i = 0; i < 8; i++ ) { + ptehi = GetPhys( ptegaddr + (i * 8) ); + + if( ptehi & 0x80000000 ) continue; + + ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f); + ptelo = phys & ~0xfff; + + SetPhys( ptegaddr + (i * 8), ptehi ); + SetPhys( ptegaddr + (i * 8) + 4, ptelo ); + + return TRUE; + } + + return FALSE; +} diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h index 76734016c2f..920868782fd 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h @@ -3,12 +3,15 @@ int GetMSR(); int GetPhys( int addr ); +void SetPhys( int addr, int val ); int GetSR(int n); void GetBat( int bat, int inst, int *batHi, int *batLo ); +void SetBat( int bat, int inst, int batHi, int batLo ); int GetSDR1(); int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); /* translate address */ int PpcVirt2phys( int virt, int inst ); +BOOLEAN InsertPageEntry( int virt, int phys ); #endif/*FREELDR_MMU_H*/ From 32c139b3f3ec07330cac19309d7963a1f0410064 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 12 Sep 2006 05:09:41 +0000 Subject: [PATCH 38/81] rsym working right on ppc. Use a template (horror) to emulate an off-endian field in a struct. We'll reconcile this code later. remove link-ntoskrnl. I'm gonna split off the ppc ldscript. svn path=/branches/powerpc/; revision=24077 --- reactos/tools/bytesex.h | 66 ++ reactos/tools/ppc.lost+found/link-ntoskrnl | 174 ---- reactos/tools/ppc.lost+found/pmake | 1 + reactos/tools/rsym.cpp | 977 +++++++++++++++++++++ reactos/tools/rsym.h | 204 ++--- reactos/tools/rsym.mak | 18 +- reactos/tools/rsym_common.cpp | 62 ++ 7 files changed, 1219 insertions(+), 283 deletions(-) create mode 100644 reactos/tools/bytesex.h delete mode 100755 reactos/tools/ppc.lost+found/link-ntoskrnl create mode 100644 reactos/tools/rsym.cpp create mode 100644 reactos/tools/rsym_common.cpp diff --git a/reactos/tools/bytesex.h b/reactos/tools/bytesex.h new file mode 100644 index 00000000000..68eb702eb1d --- /dev/null +++ b/reactos/tools/bytesex.h @@ -0,0 +1,66 @@ +#ifndef BYTESEX_H +#define BYTESEX_H + +namespace { +static inline WORD dtohs(WORD in) +{ + PBYTE in_ptr = (PBYTE)∈ + return in_ptr[0] | (in_ptr[1] << 8); +} + +static inline WORD htods(WORD in) +{ + WORD out; + PBYTE out_ptr = (PBYTE)&out; + out_ptr[0] = in; out_ptr[1] = in >> 8; + return out; +} + +static inline DWORD dtohl(DWORD in) +{ + PBYTE in_ptr = (PBYTE)∈ + return in_ptr[0] | (in_ptr[1] << 8) | (in_ptr[2] << 16) | (in_ptr[3] << 24); +} + +static inline DWORD htodl(DWORD in) +{ + DWORD out; + PBYTE out_ptr = (PBYTE)&out; + out_ptr[0] = in ; out_ptr[1] = in >> 8; + out_ptr[2] = in >> 16; out_ptr[3] = in >> 24; + return out; +} + +template T toHost( T value ); +template T toDest( T value ); +template <> WORD toHost( WORD value ) { return dtohs(value); } +template <> DWORD toHost( DWORD value ) { return dtohl(value); } +template <> int toHost( int value ) { return dtohl(value); } +template <> WORD toDest( WORD value ) { return htods(value); } +template <> DWORD toDest( DWORD value ) { return htodl(value); } +template <> int toDest( int value ) { return htodl(value); } +} + +namespace ReactosBytesex { +template +struct LENumber { +public: + operator T () const { return toHost(value); } + LENumber &operator = (T other) { value = toDest(other); return *this; } + T operator ++ () { (*this) += 1; return *this; } + LENumber &operator ++ (int) { (*this) += 1; return *this; } + T operator -- () { (*this) -= 1; return *this; } + LENumber &operator -- (int) { (*this) -= 1; return *this; } + LENumber &operator += (T other) { value = toDest(toHost(value) + other); return *this; } + LENumber &operator -= (T other) { return (*this) += -other; } + LENumber &operator &= (T other) { value = toDest(toHost(value) & other); return *this; } + LENumber &operator |= (T other) { value = toDest(toHost(value) | other); return *this; } +private: + T value; +}; + +typedef LENumber LEWord; +typedef LENumber LEDWord; +} + +#endif/*BYTESEX_H*/ diff --git a/reactos/tools/ppc.lost+found/link-ntoskrnl b/reactos/tools/ppc.lost+found/link-ntoskrnl deleted file mode 100755 index eeacb95ef8d..00000000000 --- a/reactos/tools/ppc.lost+found/link-ntoskrnl +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/sh -xv - -reactos-powerpc-ld \ - -v \ - --subsystem native \ - --entry NtProcessStartup \ - --image-base 0x80000000 \ - --file-alignment 0x1000 \ - --section-alignment 0x1000 \ - -nostartfiles -shared \ - ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe \ - obj-ppc/ntoskrnl/ke/powerpc/main_asm.o \ - obj-ppc/ntoskrnl/ke/apc.o \ - obj-ppc/ntoskrnl/ke/bug.o \ - obj-ppc/ntoskrnl/ke/clock.o \ - obj-ppc/ntoskrnl/ke/device.o \ - obj-ppc/ntoskrnl/ke/dpc.o \ - obj-ppc/ntoskrnl/ke/event.o \ - obj-ppc/ntoskrnl/ke/exception.o \ - obj-ppc/ntoskrnl/ke/gate.o \ - obj-ppc/ntoskrnl/ke/gmutex.o \ - obj-ppc/ntoskrnl/ke/ipi.o \ - obj-ppc/ntoskrnl/ke/kqueue.o \ - obj-ppc/ntoskrnl/ke/kthread.o \ - obj-ppc/ntoskrnl/ke/mutex.o \ - obj-ppc/ntoskrnl/ke/process.o \ - obj-ppc/ntoskrnl/ke/profile.o \ - obj-ppc/ntoskrnl/ke/queue.o \ - obj-ppc/ntoskrnl/ke/sem.o \ - obj-ppc/ntoskrnl/ke/spinlock.o \ - obj-ppc/ntoskrnl/ke/timer.o \ - obj-ppc/ntoskrnl/ke/usercall.o \ - obj-ppc/ntoskrnl/ke/wait.o \ - obj-ppc/ntoskrnl/cc/cacheman.o \ - obj-ppc/ntoskrnl/cc/copy.o \ - obj-ppc/ntoskrnl/cc/fs.o \ - obj-ppc/ntoskrnl/cc/mdl.o \ - obj-ppc/ntoskrnl/cc/pin.o \ - obj-ppc/ntoskrnl/cc/view.o \ - obj-ppc/ntoskrnl/cm/import.o \ - obj-ppc/ntoskrnl/cm/ntfunc.o \ - obj-ppc/ntoskrnl/cm/regfile.o \ - obj-ppc/ntoskrnl/cm/registry.o \ - obj-ppc/ntoskrnl/cm/regobj.o \ - obj-ppc/ntoskrnl/dbgk/dbgkutil.o \ - obj-ppc/ntoskrnl/dbgk/debug.o \ - obj-ppc/ntoskrnl/ex/atom.o \ - obj-ppc/ntoskrnl/ex/callback.o \ - obj-ppc/ntoskrnl/ex/dbgctrl.o \ - obj-ppc/ntoskrnl/ex/error.o \ - obj-ppc/ntoskrnl/ex/event.o \ - obj-ppc/ntoskrnl/ex/evtpair.o \ - obj-ppc/ntoskrnl/ex/fmutex.o \ - obj-ppc/ntoskrnl/ex/handle.o \ - obj-ppc/ntoskrnl/ex/init.o \ - obj-ppc/ntoskrnl/ex/lookas.o \ - obj-ppc/ntoskrnl/ex/mutant.o \ - obj-ppc/ntoskrnl/ex/power.o \ - obj-ppc/ntoskrnl/ex/pushlock.o \ - obj-ppc/ntoskrnl/ex/profile.o \ - obj-ppc/ntoskrnl/ex/resource.o \ - obj-ppc/ntoskrnl/ex/rundown.o \ - obj-ppc/ntoskrnl/ex/sem.o \ - obj-ppc/ntoskrnl/ex/sysinfo.o \ - obj-ppc/ntoskrnl/ex/time.o \ - obj-ppc/ntoskrnl/ex/timer.o \ - obj-ppc/ntoskrnl/ex/uuid.o \ - obj-ppc/ntoskrnl/ex/win32k.o \ - obj-ppc/ntoskrnl/ex/work.o \ - obj-ppc/ntoskrnl/ex/zone.o \ - obj-ppc/ntoskrnl/ex/zw.o \ - obj-ppc/ntoskrnl/fs/context.o \ - obj-ppc/ntoskrnl/fs/fastio.o \ - obj-ppc/ntoskrnl/fs/filelock.o \ - obj-ppc/ntoskrnl/fs/mcb.o \ - obj-ppc/ntoskrnl/fs/name.o \ - obj-ppc/ntoskrnl/fs/notify.o \ - obj-ppc/ntoskrnl/fs/oplock.o \ - obj-ppc/ntoskrnl/fs/pool.o \ - obj-ppc/ntoskrnl/fs/tunnel.o \ - obj-ppc/ntoskrnl/fs/unc.o \ - obj-ppc/ntoskrnl/fs/util.o \ - obj-ppc/ntoskrnl/inbv/inbv.o \ - obj-ppc/ntoskrnl/io/iomgr/*.o \ - obj-ppc/ntoskrnl/io/pnpmgr/*.o \ - obj-ppc/ntoskrnl/kd/wrappers/bochs.o \ - obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o \ - obj-ppc/ntoskrnl/kd/kdinit.o \ - obj-ppc/ntoskrnl/kd/kdio.o \ - obj-ppc/ntoskrnl/kd/kdmain.o \ - obj-ppc/ntoskrnl/ldr/loader.o \ - obj-ppc/ntoskrnl/ldr/rtl.o \ - obj-ppc/ntoskrnl/lpc/close.o \ - obj-ppc/ntoskrnl/lpc/complete.o \ - obj-ppc/ntoskrnl/lpc/connect.o \ - obj-ppc/ntoskrnl/lpc/create.o \ - obj-ppc/ntoskrnl/lpc/listen.o \ - obj-ppc/ntoskrnl/lpc/port.o \ - obj-ppc/ntoskrnl/lpc/query.o \ - obj-ppc/ntoskrnl/lpc/queue.o \ - obj-ppc/ntoskrnl/lpc/receive.o \ - obj-ppc/ntoskrnl/lpc/reply.o \ - obj-ppc/ntoskrnl/lpc/send.o \ - obj-ppc/ntoskrnl/mm/anonmem.o \ - obj-ppc/ntoskrnl/mm/aspace.o \ - obj-ppc/ntoskrnl/mm/balance.o \ - obj-ppc/ntoskrnl/mm/cont.o \ - obj-ppc/ntoskrnl/mm/drvlck.o \ - obj-ppc/ntoskrnl/mm/freelist.o \ - obj-ppc/ntoskrnl/mm/iospace.o \ - obj-ppc/ntoskrnl/mm/kmap.o \ - obj-ppc/ntoskrnl/mm/marea.o \ - obj-ppc/ntoskrnl/mm/mdl.o \ - obj-ppc/ntoskrnl/mm/mm.o \ - obj-ppc/ntoskrnl/mm/process.o \ - obj-ppc/ntoskrnl/mm/mminit.o \ - obj-ppc/ntoskrnl/mm/mpw.o \ - obj-ppc/ntoskrnl/mm/ncache.o \ - obj-ppc/ntoskrnl/mm/npool.o \ - obj-ppc/ntoskrnl/mm/pagefile.o \ - obj-ppc/ntoskrnl/mm/pageop.o \ - obj-ppc/ntoskrnl/mm/pager.o \ - obj-ppc/ntoskrnl/mm/pagfault.o \ - obj-ppc/ntoskrnl/mm/paging.o \ - obj-ppc/ntoskrnl/mm/pe.o \ - obj-ppc/ntoskrnl/mm/physical.o \ - obj-ppc/ntoskrnl/mm/pool.o \ - obj-ppc/ntoskrnl/mm/ppool.o \ - obj-ppc/ntoskrnl/mm/region.o \ - obj-ppc/ntoskrnl/mm/rmap.o \ - obj-ppc/ntoskrnl/mm/section.o \ - obj-ppc/ntoskrnl/mm/verifier.o \ - obj-ppc/ntoskrnl/mm/virtual.o \ - obj-ppc/ntoskrnl/mm/wset.o \ - obj-ppc/ntoskrnl/mm/elf32.o \ - obj-ppc/ntoskrnl/mm/elf64.o \ - obj-ppc/ntoskrnl/ob/obdir.o \ - obj-ppc/ntoskrnl/ob/obinit.o \ - obj-ppc/ntoskrnl/ob/obhandle.o \ - obj-ppc/ntoskrnl/ob/obname.o \ - obj-ppc/ntoskrnl/ob/oblife.o \ - obj-ppc/ntoskrnl/ob/obref.o \ - obj-ppc/ntoskrnl/ob/sdcache.o \ - obj-ppc/ntoskrnl/ob/symlink.o \ - obj-ppc/ntoskrnl/po/power.o \ - obj-ppc/ntoskrnl/ps/*.o \ - obj-ppc/ntoskrnl/rtl/libsupp.o \ - obj-ppc/ntoskrnl/rtl/misc.o \ - obj-ppc/ntoskrnl/rtl/nls.o \ - obj-ppc/ntoskrnl/rtl/regio.o \ - obj-ppc/ntoskrnl/rtl/strtok.o \ - obj-ppc/ntoskrnl/se/access.o \ - obj-ppc/ntoskrnl/se/acl.o \ - obj-ppc/ntoskrnl/se/audit.o \ - obj-ppc/ntoskrnl/se/lsa.o \ - obj-ppc/ntoskrnl/se/luid.o \ - obj-ppc/ntoskrnl/se/priv.o \ - obj-ppc/ntoskrnl/se/sd.o \ - obj-ppc/ntoskrnl/se/semgr.o \ - obj-ppc/ntoskrnl/se/sid.o \ - obj-ppc/ntoskrnl/se/token.o \ - obj-ppc/ntoskrnl/ntoskrnl.coff \ - obj-ppc/ntoskrnl/kdbg/kdb_symbols.o \ - obj-ppc/lib/drivers/csq/csq.a \ - obj-ppc/hal/hal/libhal.a \ - obj-ppc/lib/kjs/kjs.a \ - obj-ppc/lib/pseh/pseh.a \ - obj-ppc/lib/rtl/rtl.a \ - obj-ppc/lib/rossym/rossym.a \ - obj-ppc/lib/string/string.a \ - obj-ppc/lib/wdmguid/wdmguid.a \ - -nostartfiles \ - -nostdlib \ - -lgcc -g diff --git a/reactos/tools/ppc.lost+found/pmake b/reactos/tools/ppc.lost+found/pmake index 942a1f2d7ca..988f524e55c 100755 --- a/reactos/tools/ppc.lost+found/pmake +++ b/reactos/tools/ppc.lost+found/pmake @@ -4,6 +4,7 @@ export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin make \ ARCH=powerpc \ HOST=mingw32-linux \ + PREFIX=reactos-powerpc \ ROS_INTERMEDIATE=obj-ppc \ ROS_OUTPUT=output-ppc \ ROS_PREFIX=reactos-powerpc \ diff --git a/reactos/tools/rsym.cpp b/reactos/tools/rsym.cpp new file mode 100644 index 00000000000..b4399ad7846 --- /dev/null +++ b/reactos/tools/rsym.cpp @@ -0,0 +1,977 @@ +/* + * Usage: rsym input-file output-file + * + * There are two sources of information: the .stab/.stabstr + * sections of the executable and the COFF symbol table. Most + * of the information is in the .stab/.stabstr sections. + * However, most of our asm files don't contain .stab directives, + * so routines implemented in assembler won't show up in the + * .stab section. They are present in the COFF symbol table. + * So, we mostly use the .stab/.stabstr sections, but we augment + * the info there with info from the COFF symbol table when + * possible. + * + * This is a tool and is compiled using the host compiler, + * i.e. on Linux gcc and not mingw-gcc (cross-compiler). + * Therefore we can't include SDK headers and we have to + * duplicate some definitions here. + * Also note that the internal functions are "old C-style", + * returning an int, where a return of 0 means success and + * non-zero is failure. + */ + +#include +#include +#include +#include + +#include "rsym.h" + +static int +CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2) +{ + if (SymEntry1->Address < SymEntry2->Address) + { + return -1; + } + + if (SymEntry2->Address < SymEntry1->Address) + { + return +1; + } + + return 0; +} + +static int +GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders, + ULONG *StabSymbolsLength, void **StabSymbolsBase, + ULONG *StabStringsLength, void **StabStringsBase) +{ + ULONG Idx; + + /* Load .stab and .stabstr sections if available */ + *StabSymbolsBase = NULL; + *StabSymbolsLength = 0; + *StabStringsBase = NULL; + *StabStringsLength = 0; + + for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++) + { + /* printf("section: '%.08s'\n", PESectionHeaders[Idx].Name); */ + if ((strncmp((char*)PESectionHeaders[Idx].Name, ".stab", 5) == 0) + && (PESectionHeaders[Idx].Name[5] == 0)) + { + /* printf(".stab section found. Size %d\n", + PESectionHeaders[Idx].SizeOfRawData); */ + + *StabSymbolsLength = PESectionHeaders[Idx].SizeOfRawData; + *StabSymbolsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData); + } + + if (strncmp((char*)PESectionHeaders[Idx].Name, ".stabstr", 8) == 0) + { + /* printf(".stabstr section found. Size %d\n", + PESectionHeaders[Idx].SizeOfRawData); */ + + *StabStringsLength = PESectionHeaders[Idx].SizeOfRawData; + *StabStringsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData); + } + } + + return 0; +} + +static int +GetCoffInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders, + ULONG *CoffSymbolsLength, void **CoffSymbolsBase, + ULONG *CoffStringsLength, void **CoffStringsBase) +{ + + if (0 == PEFileHeader->PointerToSymbolTable || 0 == PEFileHeader->NumberOfSymbols) + { + /* No COFF symbol table */ + *CoffSymbolsLength = 0; + *CoffStringsLength = 0; + } + else + { + *CoffSymbolsLength = PEFileHeader->NumberOfSymbols * sizeof(COFF_SYMENT); + *CoffSymbolsBase = (void *)((char *) FileData + PEFileHeader->PointerToSymbolTable); + *CoffStringsLength = *((ULONG *) ((char *) *CoffSymbolsBase + *CoffSymbolsLength)); + *CoffStringsBase = (void *)((char *) *CoffSymbolsBase + *CoffSymbolsLength); + } + + return 0; +} + +static ULONG +FindOrAddString(char *StringToFind, ULONG *StringsLength, void *StringsBase) +{ + char *Search, *End; + + Search = (char *) StringsBase; + End = Search + *StringsLength; + + while (Search < End) + { + if (0 == strcmp(Search, StringToFind)) + { + return Search - (char *) StringsBase; + } + Search += strlen(Search) + 1; + } + + strcpy(Search, StringToFind); + *StringsLength += strlen(StringToFind) + 1; + + return Search - (char *) StringsBase; +} + +static int +ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, + ULONG *StringsLength, void *StringsBase, + ULONG StabSymbolsLength, void *StabSymbolsBase, + ULONG StabStringsLength, void *StabStringsBase, + ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders) +{ + PSTAB_ENTRY StabEntry; + ULONG Count, i; + ULONG_PTR Address, LastFunctionAddress; + int First = 1; + char *Name; + char FuncName[256]; + PROSSYM_ENTRY Current; + + StabEntry = (PSTAB_ENTRY)StabSymbolsBase; + Count = StabSymbolsLength / sizeof(STAB_ENTRY); + *SymbolsCount = 0; + if (Count == 0) + { + /* No symbol info */ + *SymbolsBase = NULL; + return 0; + } + + *SymbolsBase = (PROSSYM_ENTRY)malloc(Count * sizeof(ROSSYM_ENTRY)); + if (NULL == *SymbolsBase) + { + fprintf(stderr, "Failed to allocate memory for converted .stab symbols\n"); + return 1; + } + Current = *SymbolsBase; + memset ( Current, 0, sizeof(*Current) ); + + LastFunctionAddress = 0; + for (i = 0; i < Count; i++) + { + if ( 0 == LastFunctionAddress ) + { + Address = StabEntry[i].n_value - ImageBase; + } + else + { + Address = LastFunctionAddress + StabEntry[i].n_value; + } + switch (StabEntry[i].n_type) + { + case N_SO: + case N_SOL: + case N_BINCL: + Name = (char *) StabStringsBase + StabEntry[i].n_strx; + if (StabStringsLength < StabEntry[i].n_strx + ||'\0' == *Name || '/' == Name[strlen(Name) - 1] + || '\\' == Name[strlen(Name) - 1] + || StabEntry[i].n_value < ImageBase) + { + continue; + } + if ( First || Address != Current->Address ) + { + if ( !First ) + { + memset ( ++Current, 0, sizeof(*Current) ); + Current->FunctionOffset = Current[-1].FunctionOffset; + } + else + First = 0; + Current->Address = Address; + } + Current->FileOffset = FindOrAddString((char *)StabStringsBase + + StabEntry[i].n_strx, + StringsLength, + StringsBase); + break; + case N_FUN: + if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) + { + LastFunctionAddress = 0; /* line # 0 = end of function */ + continue; + } + if ( First || Address != Current->Address ) + { + if ( !First ) + memset ( ++Current, 0, sizeof(*Current) ); + else + First = 0; + Current->Address = Address; + Current->FileOffset = Current[-1].FileOffset; + } + if (sizeof(FuncName) <= strlen((char *) StabStringsBase + StabEntry[i].n_strx)) + { + free(*SymbolsBase); + fprintf(stderr, "Function name too long\n"); + return 1; + } + strcpy(FuncName, (char *) StabStringsBase + StabEntry[i].n_strx); + Name = strchr(FuncName, ':'); + if (NULL != Name) + { + *Name = '\0'; + } + Current->FunctionOffset = FindOrAddString(FuncName, + StringsLength, + StringsBase); + Current->SourceLine = 0; + LastFunctionAddress = Address; + break; + case N_SLINE: + if ( First || Address != Current->Address ) + { + if ( !First ) + { + memset ( ++Current, 0, sizeof(*Current) ); + Current->FileOffset = Current[-1].FileOffset; + Current->FunctionOffset = Current[-1].FunctionOffset; + } + else + First = 0; + Current->Address = Address; + } + Current->SourceLine = StabEntry[i].n_desc; + break; + default: + continue; + } + } + *SymbolsCount = (Current - *SymbolsBase + 1); + + qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry); + + return 0; +} + +static int +ConvertCoffs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, + ULONG *StringsLength, void *StringsBase, + ULONG CoffSymbolsLength, void *CoffSymbolsBase, + ULONG CoffStringsLength, void *CoffStringsBase, + ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders) +{ + ULONG Count, i; + PCOFF_SYMENT CoffEntry; + char FuncName[256]; + char *p; + PROSSYM_ENTRY Current; + + CoffEntry = (PCOFF_SYMENT) CoffSymbolsBase; + Count = CoffSymbolsLength / sizeof(COFF_SYMENT); + *SymbolsBase = (PROSSYM_ENTRY)malloc(Count * sizeof(ROSSYM_ENTRY)); + if (NULL == *SymbolsBase) + { + fprintf(stderr, "Unable to allocate memory for converted COFF symbols\n"); + return 1; + } + *SymbolsCount = 0; + Current = *SymbolsBase; + + for (i = 0; i < Count; i++) + { + if (ISFCN(CoffEntry[i].e_type) || C_EXT == CoffEntry[i].e_sclass) + { + Current->Address = CoffEntry[i].e_value; + if (0 < CoffEntry[i].e_scnum) + { + if (PEFileHeader->NumberOfSections < CoffEntry[i].e_scnum) + { + free(*SymbolsBase); + fprintf(stderr, "Invalid section number %d in COFF symbols (only %d sections present)\n", + (DWORD)CoffEntry[i].e_scnum, (DWORD)PEFileHeader->NumberOfSections); + return 1; + } + Current->Address += PESectionHeaders[CoffEntry[i].e_scnum - 1].VirtualAddress; + } + Current->FileOffset = 0; + if (0 == CoffEntry[i].e.e.e_zeroes) + { + if (sizeof(FuncName) <= strlen((char *) CoffStringsBase + CoffEntry[i].e.e.e_offset)) + { + free(*SymbolsBase); + fprintf(stderr, "Function name too long\n"); + return 1; + } + strcpy(FuncName, (char *) CoffStringsBase + CoffEntry[i].e.e.e_offset); + } + else + { + memcpy(FuncName, CoffEntry[i].e.e_name, E_SYMNMLEN); + FuncName[E_SYMNMLEN] = '\0'; + } + + /* Name demangling: stdcall */ + p = strrchr(FuncName, '@'); + if (NULL != p) + { + *p = '\0'; + } + p = ('_' == FuncName[0] || '@' == FuncName[0] ? FuncName + 1 : FuncName); + Current->FunctionOffset = FindOrAddString(p, + StringsLength, + StringsBase); + Current->SourceLine = 0; + memset ( ++Current, 0, sizeof(*Current) ); + } + i += CoffEntry[i].e_numaux; + } + + *SymbolsCount = (Current - *SymbolsBase + 1); + qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry); + + return 0; +} + +static int +MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols, + ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols, + ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols) +{ + ULONG StabIndex, j; + ULONG CoffIndex; + ULONG_PTR StabFunctionStartAddress; + ULONG StabFunctionStringOffset, NewStabFunctionStringOffset; + + *MergedSymbolCount = 0; + if (StabSymbolsCount == 0) + { + *MergedSymbols = NULL; + return 0; + } + *MergedSymbols = (PROSSYM_ENTRY)malloc(StabSymbolsCount * sizeof(ROSSYM_ENTRY)); + if (NULL == *MergedSymbols) + { + fprintf(stderr, "Unable to allocate memory for merged symbols\n"); + return 1; + } + + StabFunctionStartAddress = 0; + StabFunctionStringOffset = 0; + CoffIndex = 0; + for (StabIndex = 0; StabIndex < StabSymbolsCount; StabIndex++) + { + (*MergedSymbols)[*MergedSymbolCount] = StabSymbols[StabIndex]; + for (j = StabIndex + 1; + j < StabSymbolsCount && StabSymbols[j].Address == StabSymbols[StabIndex].Address; + j++) + { + if (0 != StabSymbols[j].FileOffset && 0 == (*MergedSymbols)[*MergedSymbolCount].FileOffset) + { + (*MergedSymbols)[*MergedSymbolCount].FileOffset = StabSymbols[j].FileOffset; + } + if (0 != StabSymbols[j].FunctionOffset && 0 == (*MergedSymbols)[*MergedSymbolCount].FunctionOffset) + { + (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = StabSymbols[j].FunctionOffset; + } + if (0 != StabSymbols[j].SourceLine && 0 == (*MergedSymbols)[*MergedSymbolCount].SourceLine) + { + (*MergedSymbols)[*MergedSymbolCount].SourceLine = StabSymbols[j].SourceLine; + } + } + StabIndex = j - 1; + while (CoffIndex < CoffSymbolsCount + && CoffSymbols[CoffIndex + 1].Address <= (*MergedSymbols)[*MergedSymbolCount].Address) + { + CoffIndex++; + } + NewStabFunctionStringOffset = (*MergedSymbols)[*MergedSymbolCount].FunctionOffset; + if (CoffSymbolsCount > 0 && + CoffSymbols[CoffIndex].Address < (*MergedSymbols)[*MergedSymbolCount].Address + && StabFunctionStartAddress < CoffSymbols[CoffIndex].Address + && 0 != CoffSymbols[CoffIndex].FunctionOffset) + { + (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = CoffSymbols[CoffIndex].FunctionOffset; + } + if (StabFunctionStringOffset != NewStabFunctionStringOffset) + { + StabFunctionStartAddress = (*MergedSymbols)[*MergedSymbolCount].Address; + } + StabFunctionStringOffset = NewStabFunctionStringOffset; + (*MergedSymbolCount)++; + } + + return 0; +} + +static PIMAGE_SECTION_HEADER +FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders) +{ + unsigned Section; + + for (Section = 0; Section < NumberOfSections; Section++) + { + if (SectionHeaders[Section].VirtualAddress <= RVA && + RVA < SectionHeaders[Section].VirtualAddress + SectionHeaders[Section].Misc.VirtualSize) + { + return SectionHeaders + Section; + } + } + + return NULL; +} + +static int +IncludeRelocationsForSection(PIMAGE_SECTION_HEADER SectionHeader) +{ + static char *BlacklistedSections[] = + { + ".edata", + ".idata", + ".reloc" + }; + char SectionName[IMAGE_SIZEOF_SHORT_NAME]; + unsigned i; + + if (0 != (SectionHeader->Characteristics & IMAGE_SCN_LNK_REMOVE)) + { + return 0; + } + + for (i = 0; i < sizeof(BlacklistedSections) / sizeof(BlacklistedSections[0]); i++) + { + strncpy(SectionName, BlacklistedSections[i], IMAGE_SIZEOF_SHORT_NAME); + if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME)) + { + return 0; + } + } + + return 1; +} + +static int +ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs, + void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader, + unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders) +{ + PIMAGE_SECTION_HEADER RelocSectionHeader, TargetSectionHeader; + PIMAGE_BASE_RELOCATION BaseReloc, End, AcceptedRelocs; + int Found; + + if (OptHeader->NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC + || 0 == OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) + { + /* No relocation entries */ + *ProcessedRelocsLength = 0; + *ProcessedRelocs = NULL; + return 0; + } + + RelocSectionHeader = FindSectionForRVA(OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, + NumberOfSections, SectionHeaders); + if (NULL == RelocSectionHeader) + { + fprintf(stderr, "Can't find section header for relocation data\n"); + return 1; + } + + *ProcessedRelocs = malloc(RelocSectionHeader->SizeOfRawData); + if (NULL == *ProcessedRelocs) + { + fprintf(stderr, "Failed to allocate %lu bytes for relocations\n", (DWORD)RelocSectionHeader->SizeOfRawData); + return 1; + } + *ProcessedRelocsLength = 0; + + BaseReloc = (PIMAGE_BASE_RELOCATION) ((char *) RawData + + RelocSectionHeader->PointerToRawData + + (OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress - + RelocSectionHeader->VirtualAddress)); + End = (PIMAGE_BASE_RELOCATION) ((char *) BaseReloc + + OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); + + while (BaseReloc < End && 0 < BaseReloc->SizeOfBlock) + { + TargetSectionHeader = FindSectionForRVA(BaseReloc->VirtualAddress, NumberOfSections, + SectionHeaders); + if (NULL != TargetSectionHeader && IncludeRelocationsForSection(TargetSectionHeader)) + { + AcceptedRelocs = (PIMAGE_BASE_RELOCATION)*ProcessedRelocs; + Found = 0; + while (AcceptedRelocs < (PIMAGE_BASE_RELOCATION) ((char *) *ProcessedRelocs + + *ProcessedRelocsLength) + && ! Found) + { + Found = BaseReloc->SizeOfBlock == AcceptedRelocs->SizeOfBlock + && 0 == memcmp(BaseReloc, AcceptedRelocs, AcceptedRelocs->SizeOfBlock); + AcceptedRelocs= (PIMAGE_BASE_RELOCATION) ((char *) AcceptedRelocs + + AcceptedRelocs->SizeOfBlock); + } + if (! Found) + { + memcpy((char *) *ProcessedRelocs + *ProcessedRelocsLength, + BaseReloc, BaseReloc->SizeOfBlock); + *ProcessedRelocsLength += BaseReloc->SizeOfBlock; + } + } + BaseReloc = (PIMAGE_BASE_RELOCATION)((char *) BaseReloc + BaseReloc->SizeOfBlock); + } + + return 0; +} + +static int +CreateOutputFile(FILE *OutFile, void *InData, + PIMAGE_DOS_HEADER InDosHeader, PIMAGE_FILE_HEADER InFileHeader, + PIMAGE_OPTIONAL_HEADER InOptHeader, PIMAGE_SECTION_HEADER InSectionHeaders, + ULONG RosSymLength, void *RosSymSection) +{ + ULONG StartOfRawData; + unsigned Section; + void *OutHeader, *ProcessedRelocs, *PaddedRosSym, *Data; + PIMAGE_DOS_HEADER OutDosHeader; + PIMAGE_FILE_HEADER OutFileHeader; + PIMAGE_OPTIONAL_HEADER OutOptHeader; + PIMAGE_SECTION_HEADER OutSectionHeaders, CurrentSectionHeader; + DWORD CheckSum; + ULONG Length, i; + ULONG ProcessedRelocsLength; + ULONG RosSymOffset, RosSymFileLength; + int InRelocSectionIndex; + PIMAGE_SECTION_HEADER OutRelocSection; + + StartOfRawData = 0; + for (Section = 0; Section < InFileHeader->NumberOfSections; Section++) + { + if ((0 == StartOfRawData + || InSectionHeaders[Section].PointerToRawData < StartOfRawData) + && 0 != InSectionHeaders[Section].PointerToRawData + && 0 == (InSectionHeaders[Section].Characteristics & IMAGE_SCN_LNK_REMOVE)) + { + StartOfRawData = InSectionHeaders[Section].PointerToRawData; + } + } + OutHeader = malloc(StartOfRawData); + if (NULL == OutHeader) + { + fprintf(stderr, "Failed to allocate %lu bytes for output file header\n", StartOfRawData); + return 1; + } + memset(OutHeader, '\0', StartOfRawData); + + OutDosHeader = (PIMAGE_DOS_HEADER) OutHeader; + memcpy(OutDosHeader, InDosHeader, InDosHeader->e_lfanew + sizeof(ULONG)); + + OutFileHeader = (PIMAGE_FILE_HEADER)((char *) OutHeader + OutDosHeader->e_lfanew + sizeof(ULONG)); + memcpy(OutFileHeader, InFileHeader, sizeof(IMAGE_FILE_HEADER)); + OutFileHeader->PointerToSymbolTable = 0; + OutFileHeader->NumberOfSymbols = 0; + OutFileHeader->Characteristics &= ~(IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_LOCAL_SYMS_STRIPPED | + IMAGE_FILE_DEBUG_STRIPPED); + + OutOptHeader = (PIMAGE_OPTIONAL_HEADER)(OutFileHeader + 1); + memcpy(OutOptHeader, InOptHeader, sizeof(IMAGE_OPTIONAL_HEADER)); + OutOptHeader->CheckSum = 0; + + OutSectionHeaders = (PIMAGE_SECTION_HEADER)((char *) OutOptHeader + OutFileHeader->SizeOfOptionalHeader); + + if (ProcessRelocations(&ProcessedRelocsLength, &ProcessedRelocs, InData, InOptHeader, + InFileHeader->NumberOfSections, InSectionHeaders)) + { + return 1; + } + if (InOptHeader->NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC + || 0 == InOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) + { + InRelocSectionIndex = -1; + } + else + { + InRelocSectionIndex = FindSectionForRVA(InOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, + InFileHeader->NumberOfSections, InSectionHeaders) - InSectionHeaders; + } + + OutFileHeader->NumberOfSections = 0; + CurrentSectionHeader = OutSectionHeaders; + OutOptHeader->SizeOfImage = 0; + RosSymOffset = 0; + OutRelocSection = NULL; + for (Section = 0; Section < InFileHeader->NumberOfSections; Section++) + { + if (0 == (InSectionHeaders[Section].Characteristics & IMAGE_SCN_LNK_REMOVE)) + { + *CurrentSectionHeader = InSectionHeaders[Section]; + CurrentSectionHeader->PointerToLinenumbers = 0; + CurrentSectionHeader->NumberOfLinenumbers = 0; + if (OutOptHeader->SizeOfImage < CurrentSectionHeader->VirtualAddress + + CurrentSectionHeader->Misc.VirtualSize) + { + OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + + CurrentSectionHeader->Misc.VirtualSize, + OutOptHeader->SectionAlignment); + } + if (RosSymOffset < CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData) + { + RosSymOffset = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData; + } + if (Section == (ULONG)InRelocSectionIndex) + { + OutRelocSection = CurrentSectionHeader; + } + (OutFileHeader->NumberOfSections) ++; + CurrentSectionHeader++; + } + } + + if (OutRelocSection == CurrentSectionHeader - 1) + { + OutOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = ProcessedRelocsLength; + if (OutOptHeader->SizeOfImage == OutRelocSection->VirtualAddress + + ROUND_UP(OutRelocSection->Misc.VirtualSize, + OutOptHeader->SectionAlignment)) + { + OutOptHeader->SizeOfImage = OutRelocSection->VirtualAddress + + ROUND_UP(ProcessedRelocsLength, + OutOptHeader->SectionAlignment); + } + OutRelocSection->Misc.VirtualSize = ProcessedRelocsLength; + if (RosSymOffset == OutRelocSection->PointerToRawData + + OutRelocSection->SizeOfRawData) + { + RosSymOffset = OutRelocSection->PointerToRawData + + ROUND_UP(ProcessedRelocsLength, OutOptHeader->FileAlignment); + } + OutRelocSection->SizeOfRawData = ROUND_UP(ProcessedRelocsLength, + OutOptHeader->FileAlignment); + } + + if (RosSymLength > 0) + { + RosSymFileLength = ROUND_UP(RosSymLength, OutOptHeader->FileAlignment); + memcpy(CurrentSectionHeader->Name, ".rossym", 8); /* We're lucky: string is exactly 8 bytes long */ + CurrentSectionHeader->Misc.VirtualSize = RosSymLength; + CurrentSectionHeader->VirtualAddress = OutOptHeader->SizeOfImage; + CurrentSectionHeader->SizeOfRawData = RosSymFileLength; + CurrentSectionHeader->PointerToRawData = RosSymOffset; + CurrentSectionHeader->PointerToRelocations = 0; + CurrentSectionHeader->PointerToLinenumbers = 0; + CurrentSectionHeader->NumberOfRelocations = 0; + CurrentSectionHeader->NumberOfLinenumbers = 0; + CurrentSectionHeader->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE + | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_TYPE_NOLOAD; + OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + + CurrentSectionHeader->Misc.VirtualSize, + OutOptHeader->SectionAlignment); + (OutFileHeader->NumberOfSections)++; + + PaddedRosSym = malloc(RosSymFileLength); + if (NULL == PaddedRosSym) + { + fprintf(stderr, "Failed to allocate %lu bytes for padded .rossym\n", RosSymFileLength); + return 1; + } + memcpy(PaddedRosSym, RosSymSection, RosSymLength); + memset((char *) PaddedRosSym + RosSymLength, '\0', RosSymFileLength - RosSymLength); + } + else + { + PaddedRosSym = NULL; + } + CheckSum = 0; + for (i = 0; i < StartOfRawData / 2; i++) + { + CheckSum += ((unsigned short*) OutHeader)[i]; + CheckSum = 0xffff & (CheckSum + (CheckSum >> 16)); + } + Length = StartOfRawData; + for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++) + { + if (OutRelocSection == OutSectionHeaders + Section) + { + Data = (void *) ProcessedRelocs; + } + else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections) + { + Data = (void *) PaddedRosSym; + } + else + { + Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData); + } + for (i = 0; i < OutSectionHeaders[Section].SizeOfRawData / 2; i++) + { + CheckSum += ((unsigned short*) Data)[i]; + CheckSum = 0xffff & (CheckSum + (CheckSum >> 16)); + } + Length += OutSectionHeaders[Section].SizeOfRawData; + } + CheckSum += Length; + OutOptHeader->CheckSum = CheckSum; + + if (fwrite(OutHeader, 1, StartOfRawData, OutFile) != StartOfRawData) + { + perror("Error writing output header\n"); + free(OutHeader); + return 1; + } + + for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++) + { + if (0 != OutSectionHeaders[Section].SizeOfRawData) + { + fseek(OutFile, OutSectionHeaders[Section].PointerToRawData, SEEK_SET); + if (OutRelocSection == OutSectionHeaders + Section) + { + Data = (void *) ProcessedRelocs; + } + else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections) + { + Data = (void *) PaddedRosSym; + } + else + { + Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData); + } + if (fwrite(Data, 1, OutSectionHeaders[Section].SizeOfRawData, OutFile) != + OutSectionHeaders[Section].SizeOfRawData) + { + perror("Error writing section data\n"); + free(PaddedRosSym); + free(OutHeader); + return 1; + } + } + } + + if (PaddedRosSym) + { + free(PaddedRosSym); + } + free(OutHeader); + + return 0; +} + +int main(int argc, char* argv[]) +{ + PSYMBOLFILE_HEADER SymbolFileHeader; + PIMAGE_DOS_HEADER PEDosHeader; + PIMAGE_FILE_HEADER PEFileHeader; + PIMAGE_OPTIONAL_HEADER PEOptHeader; + PIMAGE_SECTION_HEADER PESectionHeaders; + ULONG ImageBase; + void *StabBase; + ULONG StabsLength; + void *StabStringBase; + ULONG StabStringsLength; + void *CoffBase = NULL; + ULONG CoffsLength; + void *CoffStringBase = NULL; + ULONG CoffStringsLength; + char* path1; + char* path2; + FILE* out; + void *StringBase; + ULONG StringsLength; + ULONG StabSymbolsCount; + PROSSYM_ENTRY StabSymbols; + ULONG CoffSymbolsCount; + PROSSYM_ENTRY CoffSymbols; + ULONG MergedSymbolsCount; + PROSSYM_ENTRY MergedSymbols; + size_t FileSize; + void *FileData; + ULONG RosSymLength; + void *RosSymSection; + + if (3 != argc) + { + fprintf(stderr, "Usage: rsym \n"); + exit(1); + } + + path1 = convert_path(argv[1]); + path2 = convert_path(argv[2]); + + FileData = load_file ( path1, &FileSize ); + if ( !FileData ) + { + fprintf ( stderr, "An error occured loading '%s'\n", path1 ); + exit(1); + } + + /* Check if MZ header exists */ + PEDosHeader = (PIMAGE_DOS_HEADER) FileData; + + if ((WORD)PEDosHeader->e_magic != IMAGE_DOS_MAGIC || + (DWORD)PEDosHeader->e_lfanew == 0L) + { + perror("Input file is not a PE image.\n"); + free(FileData); + exit(1); + } + + /* Locate PE file header */ + /* sizeof(ULONG) = sizeof(MAGIC) */ + PEFileHeader = (PIMAGE_FILE_HEADER)((char *) FileData + PEDosHeader->e_lfanew + sizeof(ULONG)); + + /* Locate optional header */ + assert(sizeof(ULONG) == 4); + PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1); + ImageBase = PEOptHeader->ImageBase; + + /* Locate PE section headers */ + PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader); + + if (GetStabInfo(FileData, PEFileHeader, PESectionHeaders, &StabsLength, &StabBase, + &StabStringsLength, &StabStringBase)) + { + free(FileData); + exit(1); + } + + if (GetCoffInfo(FileData, PEFileHeader, PESectionHeaders, &CoffsLength, &CoffBase, + &CoffStringsLength, &CoffStringBase)) + { + free(FileData); + exit(1); + } + + StringBase = malloc(1 + StabStringsLength + CoffStringsLength + + (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1)); + if (NULL == StringBase) + { + free(FileData); + fprintf(stderr, "Failed to allocate memory for strings table\n"); + exit(1); + } + /* Make offset 0 into an empty string */ + *((char *) StringBase) = '\0'; + StringsLength = 1; + + if (ConvertStabs(&StabSymbolsCount, &StabSymbols, &StringsLength, StringBase, + StabsLength, StabBase, StabStringsLength, StabStringBase, + ImageBase, PEFileHeader, PESectionHeaders)) + { + free(StringBase); + free(FileData); + fprintf(stderr, "Failed to allocate memory for strings table\n"); + exit(1); + } + + if (ConvertCoffs(&CoffSymbolsCount, &CoffSymbols, &StringsLength, StringBase, + CoffsLength, CoffBase, CoffStringsLength, CoffStringBase, + ImageBase, PEFileHeader, PESectionHeaders)) + { + if (StabSymbols) + { + free(StabSymbols); + } + free(StringBase); + free(FileData); + exit(1); + } + + if (MergeStabsAndCoffs(&MergedSymbolsCount, &MergedSymbols, + StabSymbolsCount, StabSymbols, + CoffSymbolsCount, CoffSymbols)) + { + if (CoffSymbols) + { + free(CoffSymbols); + } + if (StabSymbols) + { + free(StabSymbols); + } + free(StringBase); + free(FileData); + exit(1); + } + + if (CoffSymbols) + { + free(CoffSymbols); + } + if (StabSymbols) + { + free(StabSymbols); + } + if (MergedSymbolsCount == 0) + { + RosSymLength = 0; + RosSymSection = NULL; + } + else + { + RosSymLength = sizeof(SYMBOLFILE_HEADER) + MergedSymbolsCount * sizeof(ROSSYM_ENTRY) + + StringsLength; + RosSymSection = malloc(RosSymLength); + if (NULL == RosSymSection) + { + free(MergedSymbols); + free(StringBase); + free(FileData); + fprintf(stderr, "Unable to allocate memory for .rossym section\n"); + exit(1); + } + memset(RosSymSection, '\0', RosSymLength); + + SymbolFileHeader = (PSYMBOLFILE_HEADER) RosSymSection; + SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER); + SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY); + SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset + SymbolFileHeader->SymbolsLength; + SymbolFileHeader->StringsLength = StringsLength; + + memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset, MergedSymbols, + SymbolFileHeader->SymbolsLength); + memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset, StringBase, + SymbolFileHeader->StringsLength); + + free(MergedSymbols); + } + free(StringBase); + out = fopen(path2, "wb"); + if (out == NULL) + { + perror("Cannot open output file"); + free(RosSymSection); + free(FileData); + exit(1); + } + + if (CreateOutputFile(out, FileData, PEDosHeader, PEFileHeader, PEOptHeader, + PESectionHeaders, RosSymLength, RosSymSection)) + { + fclose(out); + if (RosSymSection) + { + free(RosSymSection); + } + free(FileData); + exit(1); + } + + fclose(out); + if (RosSymSection) + { + free(RosSymSection); + } + free(FileData); + + return 0; +} + +/* EOF */ diff --git a/reactos/tools/rsym.h b/reactos/tools/rsym.h index 6c68fe91f86..7bbcbc20b2b 100644 --- a/reactos/tools/rsym.h +++ b/reactos/tools/rsym.h @@ -33,27 +33,31 @@ typedef unsigned long ULONG_PTR; #endif #endif +#include "bytesex.h" + +using namespace ReactosBytesex; + #pragma pack(2) typedef struct _IMAGE_DOS_HEADER { - WORD e_magic; - WORD e_cblp; - WORD e_cp; - WORD e_crlc; - WORD e_cparhdr; - WORD e_minalloc; - WORD e_maxalloc; - WORD e_ss; - WORD e_sp; - WORD e_csum; - WORD e_ip; - WORD e_cs; - WORD e_lfarlc; - WORD e_ovno; - WORD e_res[4]; - WORD e_oemid; - WORD e_oeminfo; - WORD e_res2[10]; - LONG e_lfanew; + LEWord e_magic; + LEWord e_cblp; + LEWord e_cp; + LEWord e_crlc; + LEWord e_cparhdr; + LEWord e_minalloc; + LEWord e_maxalloc; + LEWord e_ss; + LEWord e_sp; + LEWord e_csum; + LEWord e_ip; + LEWord e_cs; + LEWord e_lfarlc; + LEWord e_ovno; + LEWord e_res[4]; + LEWord e_oemid; + LEWord e_oeminfo; + LEWord e_res2[10]; + LEDWord e_lfanew; } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; #pragma pack(4) @@ -63,53 +67,53 @@ typedef struct _IMAGE_DOS_HEADER { #pragma pack(4) typedef struct _IMAGE_FILE_HEADER { - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; + LEWord Machine; + LEWord NumberOfSections; + LEDWord TimeDateStamp; + LEDWord PointerToSymbolTable; + LEDWord NumberOfSymbols; + LEWord SizeOfOptionalHeader; + LEWord Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; + LEDWord VirtualAddress; + LEDWord Size; } IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 typedef struct _IMAGE_OPTIONAL_HEADER { - WORD Magic; + LEWord Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Reserved1; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; + LEDWord SizeOfCode; + LEDWord SizeOfInitializedData; + LEDWord SizeOfUninitializedData; + LEDWord AddressOfEntryPoint; + LEDWord BaseOfCode; + LEDWord BaseOfData; + LEDWord ImageBase; + LEDWord SectionAlignment; + LEDWord FileAlignment; + LEWord MajorOperatingSystemVersion; + LEWord MinorOperatingSystemVersion; + LEWord MajorImageVersion; + LEWord MinorImageVersion; + LEWord MajorSubsystemVersion; + LEWord MinorSubsystemVersion; + LEDWord Reserved1; + LEDWord SizeOfImage; + LEDWord SizeOfHeaders; + LEDWord CheckSum; + LEWord Subsystem; + LEWord DllCharacteristics; + LEDWord SizeOfStackReserve; + LEDWord SizeOfStackCommit; + LEDWord SizeOfHeapReserve; + LEDWord SizeOfHeapCommit; + LEDWord LoaderFlags; + LEDWord NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; @@ -121,62 +125,62 @@ typedef struct _IMAGE_OPTIONAL_HEADER { typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { - DWORD PhysicalAddress; - DWORD VirtualSize; + LEDWord PhysicalAddress; + LEDWord VirtualSize; } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; + LEDWord VirtualAddress; + LEDWord SizeOfRawData; + LEDWord PointerToRawData; + LEDWord PointerToRelocations; + LEDWord PointerToLinenumbers; + LEWord NumberOfRelocations; + LEWord NumberOfLinenumbers; + LEDWord Characteristics; } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; + LEDWord VirtualAddress; + LEDWord SizeOfBlock; } IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; typedef struct { - USHORT f_magic; /* magic number */ - USHORT f_nscns; /* number of sections */ - ULONG f_timdat; /* time & date stamp */ - ULONG f_symptr; /* file pointer to symtab */ - ULONG f_nsyms; /* number of symtab entries */ - USHORT f_opthdr; /* sizeof(optional hdr) */ - USHORT f_flags; /* flags */ + LEWord f_magic; /* magic number */ + LEWord f_nscns; /* number of sections */ + LEDWord f_timdat; /* time & date stamp */ + LEDWord f_symptr; /* file pointer to symtab */ + LEDWord f_nsyms; /* number of symtab entries */ + LEWord f_opthdr; /* sizeof(optional hdr) */ + LEWord f_flags; /* flags */ } FILHDR; typedef struct { char s_name[8]; /* section name */ - ULONG s_paddr; /* physical address, aliased s_nlib */ - ULONG s_vaddr; /* virtual address */ - ULONG s_size; /* section size */ - ULONG s_scnptr; /* file ptr to raw data for section */ - ULONG s_relptr; /* file ptr to relocation */ - ULONG s_lnnoptr; /* file ptr to line numbers */ - USHORT s_nreloc; /* number of relocation entries */ - USHORT s_nlnno; /* number of line number entries */ - ULONG s_flags; /* flags */ + LEDWord s_paddr; /* physical address, aliased s_nlib */ + LEDWord s_vaddr; /* virtual address */ + LEDWord s_size; /* section size */ + LEDWord s_scnptr; /* file ptr to raw data for section */ + LEDWord s_relptr; /* file ptr to relocation */ + LEDWord s_lnnoptr; /* file ptr to line numbers */ + LEWord s_nreloc; /* number of relocation entries */ + LEWord s_nlnno; /* number of line number entries */ + LEDWord s_flags; /* flags */ } SCNHDR; #pragma pack(4) typedef struct _SYMBOLFILE_HEADER { - ULONG SymbolsOffset; - ULONG SymbolsLength; - ULONG StringsOffset; - ULONG StringsLength; + LEDWord SymbolsOffset; + LEDWord SymbolsLength; + LEDWord StringsOffset; + LEDWord StringsLength; } SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER; typedef struct _STAB_ENTRY { - ULONG n_strx; /* index into string table of name */ + LEDWord n_strx; /* index into string table of name */ UCHAR n_type; /* type of symbol */ UCHAR n_other; /* misc info (usually empty) */ - USHORT n_desc; /* description field */ - ULONG n_value; /* value of symbol */ + LEWord n_desc; /* description field */ + LEDWord n_value; /* value of symbol */ } STAB_ENTRY, *PSTAB_ENTRY; /* http://www.math.utah.edu/docs/info/stabs_12.html */ @@ -279,25 +283,25 @@ typedef struct _COFF_SYMENT char e_name[E_SYMNMLEN]; struct { - ULONG e_zeroes; - ULONG e_offset; + LEDWord e_zeroes; + LEDWord e_offset; } e; } e; - ULONG e_value; - short e_scnum; - USHORT e_type; + LEDWord e_value; + LEWord e_scnum; + LEWord e_type; UCHAR e_sclass; UCHAR e_numaux; } COFF_SYMENT, *PCOFF_SYMENT; #pragma pack(4) typedef struct _ROSSYM_ENTRY { - ULONG_PTR Address; - ULONG FunctionOffset; - ULONG FileOffset; - ULONG SourceLine; + LEDWord Address; + LEDWord FunctionOffset; + LEDWord FileOffset; + LEDWord SourceLine; } ROSSYM_ENTRY, *PROSSYM_ENTRY; #define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1)) diff --git a/reactos/tools/rsym.mak b/reactos/tools/rsym.mak index ad6b383de87..5f057c66f43 100644 --- a/reactos/tools/rsym.mak +++ b/reactos/tools/rsym.mak @@ -10,13 +10,13 @@ RSYM_TARGET = \ $(EXEPREFIX)$(RSYM_OUT_)rsym$(EXEPOSTFIX) RSYM_SOURCES = \ - $(RSYM_BASE_)rsym.c \ - $(RSYM_BASE_)rsym_common.c + $(RSYM_BASE_)rsym.cpp \ + $(RSYM_BASE_)rsym_common.cpp RSYM_OBJECTS = \ - $(addprefix $(INTERMEDIATE_), $(RSYM_SOURCES:.c=.o)) + $(addprefix $(INTERMEDIATE_), $(RSYM_SOURCES:.cpp=.o)) -RSYM_HOST_CFLAGS = $(TOOLS_CFLAGS) +RSYM_HOST_CFLAGS = $(TOOLS_CFLAGS) -g -xc++ RSYM_HOST_LFLAGS = $(TOOLS_LFLAGS) @@ -25,15 +25,15 @@ rsym: $(RSYM_TARGET) $(RSYM_TARGET): $(RSYM_OBJECTS) | $(RSYM_OUT) $(ECHO_LD) - ${host_gcc} $(RSYM_OBJECTS) $(RSYM_HOST_LFLAGS) -o $@ + ${host_gpp} $(RSYM_OBJECTS) $(RSYM_HOST_LFLAGS) -o $@ -$(RSYM_INT_)rsym.o: $(RSYM_BASE_)rsym.c | $(RSYM_INT) +$(RSYM_INT_)rsym.o: $(RSYM_BASE_)rsym.cpp | $(RSYM_INT) $(ECHO_CC) - ${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@ + ${host_gpp} $(RSYM_HOST_CFLAGS) -c $< -o $@ -$(RSYM_INT_)rsym_common.o: $(RSYM_BASE_)rsym_common.c | $(RSYM_INT) +$(RSYM_INT_)rsym_common.o: $(RSYM_BASE_)rsym_common.cpp | $(RSYM_INT) $(ECHO_CC) - ${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@ + ${host_gpp} $(RSYM_HOST_CFLAGS) -c $< -o $@ .PHONY: rsym_clean rsym_clean: diff --git a/reactos/tools/rsym_common.cpp b/reactos/tools/rsym_common.cpp new file mode 100644 index 00000000000..875463fe920 --- /dev/null +++ b/reactos/tools/rsym_common.cpp @@ -0,0 +1,62 @@ +/* rsym_common.c */ + +#include +#include +#include + +#include "rsym.h" + +char* +convert_path ( const char* origpath ) +{ + char* newpath; + int i; + + newpath = strdup(origpath); + + i = 0; + while (newpath[i] != 0) + { +#ifdef UNIX_PATHS + if (newpath[i] == '\\') + { + newpath[i] = '/'; + } +#else +#ifdef DOS_PATHS + if (newpath[i] == '/') + { + newpath[i] = '\\'; + } +#endif +#endif + i++; + } + return(newpath); +} + +void* +load_file ( const char* file_name, size_t* file_size ) +{ + FILE* f; + void* FileData = NULL; + + f = fopen ( file_name, "rb" ); + if (f != NULL) + { + fseek(f, 0L, SEEK_END); + *file_size = ftell(f); + fseek(f, 0L, SEEK_SET); + FileData = malloc(*file_size); + if (FileData != NULL) + { + if ( *file_size != fread(FileData, 1, *file_size, f) ) + { + free(FileData); + FileData = NULL; + } + } + fclose(f); + } + return FileData; +} From 6b21a858d19e5a20a4b34ca89a73e6ead2c7835e Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 17 Sep 2006 09:37:46 +0000 Subject: [PATCH 39/81] Adapt pefixup for bytesex.h, rsym: add some debugging info that can be turned on if needed. svn path=/branches/powerpc/; revision=24157 --- reactos/tools/pefixup.cpp | 382 ++++++++++++++++++++++++++++++++++++++ reactos/tools/pefixup.mak | 10 +- reactos/tools/rsym.cpp | 7 + 3 files changed, 394 insertions(+), 5 deletions(-) create mode 100644 reactos/tools/pefixup.cpp diff --git a/reactos/tools/pefixup.cpp b/reactos/tools/pefixup.cpp new file mode 100644 index 00000000000..358662b65c1 --- /dev/null +++ b/reactos/tools/pefixup.cpp @@ -0,0 +1,382 @@ +/* + * PE Fixup Utility + * Copyright (C) 2005 Filip Navara + * + * The purpose of this utility is fix PE binaries generated by binutils and + * to manipulate flags that can't be set by binutils. + * + * Currently two features are implemented: + * + * - Setting flags on PE sections for use by drivers. The sections + * .text, .data, .idata, .bss are marked as non-pageable and + * non-discarable, section PAGE is marked as pageable and section + * INIT is marked as discaradable. + * + * - Sorting of export name table in executables. DLLTOOL has bug + * in sorting algorithm when the --kill-at flag is used. The exports + * are sorted in the decorated form and so the fastcall symbols are + * incorrectly put at the beginning of export table. This option + * allow to correct sort the table, so binary search can be used + * to process them. + */ + +#include +#include +#include +#include +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* The following definitions are ripped from MinGW W32API headers. We don't + use these headers directly in order to allow compilation on Linux hosts. */ + +typedef unsigned char BYTE, *PBYTE; +typedef unsigned short WORD; +typedef unsigned int DWORD; +typedef int LONG; + +#include "bytesex.h" +using namespace ReactosBytesex; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 +#define IMAGE_SIZEOF_SHORT_NAME 8 +#define IMAGE_DOS_SIGNATURE 0x5A4D +#define IMAGE_NT_SIGNATURE 0x00004550 +#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000 +#define FIELD_OFFSET(t,f) (((LONG)&(((t*)4)->f))-4) +#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((unsigned long)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader)) +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 + +#pragma pack(2) +typedef struct _IMAGE_DOS_HEADER { + LEWord e_magic; + LEWord e_cblp; + LEWord e_cp; + LEWord e_crlc; + LEWord e_cparhdr; + LEWord e_minalloc; + LEWord e_maxalloc; + LEWord e_ss; + LEWord e_sp; + LEWord e_csum; + LEWord e_ip; + LEWord e_cs; + LEWord e_lfarlc; + LEWord e_ovno; + LEWord e_res[4]; + LEWord e_oemid; + LEWord e_oeminfo; + LEWord e_res2[10]; + LEDWord e_lfanew; +} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; +#pragma pack(4) +#pragma pack(4) +typedef struct _IMAGE_EXPORT_DIRECTORY { + LEDWord Characteristics; + LEDWord TimeDateStamp; + LEWord MajorVersion; + LEWord MinorVersion; + LEDWord Name; + LEDWord Base; + LEDWord NumberOfFunctions; + LEDWord NumberOfNames; + LEDWord AddressOfFunctions; + LEDWord AddressOfNames; + LEDWord AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; +typedef struct _IMAGE_FILE_HEADER { + LEWord Machine; + LEWord NumberOfSections; + LEDWord TimeDateStamp; + LEDWord PointerToSymbolTable; + LEDWord NumberOfSymbols; + LEWord SizeOfOptionalHeader; + LEWord Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; +typedef struct _IMAGE_DATA_DIRECTORY { + LEDWord VirtualAddress; + LEDWord Size; +} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; +typedef struct _IMAGE_OPTIONAL_HEADER { + LEWord Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + LEDWord SizeOfCode; + LEDWord SizeOfInitializedData; + LEDWord SizeOfUninitializedData; + LEDWord AddressOfEntryPoint; + LEDWord BaseOfCode; + LEDWord BaseOfData; + LEDWord ImageBase; + LEDWord SectionAlignment; + LEDWord FileAlignment; + LEWord MajorOperatingSystemVersion; + LEWord MinorOperatingSystemVersion; + LEWord MajorImageVersion; + LEWord MinorImageVersion; + LEWord MajorSubsystemVersion; + LEWord MinorSubsystemVersion; + LEDWord Reserved1; + LEDWord SizeOfImage; + LEDWord SizeOfHeaders; + LEDWord CheckSum; + LEWord Subsystem; + LEWord DllCharacteristics; + LEDWord SizeOfStackReserve; + LEDWord SizeOfStackCommit; + LEDWord SizeOfHeapReserve; + LEDWord SizeOfHeapCommit; + LEDWord LoaderFlags; + LEDWord NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; +typedef struct _IMAGE_NT_HEADERS { + LEDWord Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS; +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + LEDWord PhysicalAddress; + LEDWord VirtualSize; + } Misc; + LEDWord VirtualAddress; + LEDWord SizeOfRawData; + LEDWord PointerToRawData; + LEDWord PointerToRelocations; + LEDWord PointerToLinenumbers; + LEWord NumberOfRelocations; + LEWord NumberOfLinenumbers; + LEDWord Characteristics; +} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; +#pragma pack(4) + +/* End of ripped definitions */ + +typedef struct _export_t { + LEDWord name; + LEWord ordinal; +} export_t; + +unsigned char *buffer; +PIMAGE_DOS_HEADER dos_header; +PIMAGE_NT_HEADERS nt_header; + +void *rva_to_ptr(DWORD rva) +{ + PIMAGE_SECTION_HEADER section_header; + unsigned int i; + + for (i = 0, section_header = IMAGE_FIRST_SECTION(nt_header); + i < nt_header->OptionalHeader.NumberOfRvaAndSizes; + i++, section_header++) + { + if (rva >= section_header->VirtualAddress && + rva < section_header->VirtualAddress + + section_header->Misc.VirtualSize) + { + return buffer + rva - section_header->VirtualAddress + + section_header->PointerToRawData; + } + } + + return NULL; +} + +int export_compare_func(const void *a, const void *b) +{ + const export_t *ap = (const export_t *)a; + const export_t *bp = (const export_t *)b; + char *an = (char *)rva_to_ptr(ap->name); + char *bn = (char *)rva_to_ptr(bp->name); + return strcmp(an, bn); +} + +int main(int argc, char **argv) +{ + int fd_in, fd_out; + long len; + PIMAGE_SECTION_HEADER section_header; + PIMAGE_DATA_DIRECTORY data_dir; + unsigned int i; + unsigned long checksum; + int fixup_exports = 0; + int fixup_sections = 0; + + /* + * Process parameters. + */ + + if (argc < 2) + { + printf("Usage: %s \n" + "Options:\n" + " -sections Sets section flags for PE image.\n" + " -exports Sort the names in export table.\n", + argv[0]); + return 1; + } + + for (i = 2; i < (unsigned int)argc; i++) + { + if (!strcmp(argv[i], "-sections")) + fixup_sections = 1; + else if (!strcmp(argv[i], "-exports")) + fixup_exports = 1; + else + { printf("Invalid option: %s\n", argv[i]); return 1; } + } + + if (fixup_sections == 0 && fixup_exports == 0) + { + printf("Nothing to do.\n"); + return 0; + } + + /* + * Read the whole file to memory. + */ + + fd_in = open(argv[1], O_RDONLY | O_BINARY); + if (fd_in == 0) + { + printf("Can't open input file.\n"); + return 1; + } + + len = lseek(fd_in, 0, SEEK_END); + if (len < (int)sizeof(IMAGE_DOS_HEADER)) + { + close(fd_in); + printf("'%s' isn't a PE image (too short)\n", argv[1]); + return 1; + } + + /* Lower down we overwrite the byte at len, so here, we need at least + * one more byte than len. We'll be guaranteed one or two now. */ + buffer = (unsigned char *)malloc((len + 2) & ~1); + if (buffer == NULL) + { + close(fd_in); + printf("Not enough memory available.\n"); + return 1; + } + + /* Read the whole input file into a buffer */ + lseek(fd_in, 0, SEEK_SET); + read(fd_in, buffer, len); + /* Here is where the block end overwrite was */ + if (len & 1) + buffer[len] = 0; + + close(fd_in); + + /* + * Check the headers and save pointers to them. + */ + + dos_header = (PIMAGE_DOS_HEADER)buffer; + nt_header = (PIMAGE_NT_HEADERS)(buffer + dos_header->e_lfanew); + + if (dos_header->e_magic != IMAGE_DOS_SIGNATURE || + nt_header->Signature != IMAGE_NT_SIGNATURE) + { + printf("'%s' isn't a PE image (bad headers)\n", argv[1]); + free(buffer); + return 1; + } + + if (fixup_exports) + { + /* Sort export directory */ + data_dir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + if (data_dir->Size != 0) + { + PIMAGE_EXPORT_DIRECTORY export_directory; + LEDWord *name_ptr; + LEWord *ordinal_ptr; + export_t *exports; + + export_directory = (PIMAGE_EXPORT_DIRECTORY)rva_to_ptr(data_dir->VirtualAddress); + if (export_directory != NULL) + { + exports = (export_t *)malloc(sizeof(export_t) * export_directory->NumberOfNames); + if (exports == NULL) + { + printf("Not enough memory.\n"); + free(buffer); + return 1; + } + + name_ptr = (LEDWord *)rva_to_ptr(export_directory->AddressOfNames); + ordinal_ptr = (LEWord *)rva_to_ptr(export_directory->AddressOfNameOrdinals); + + for (i = 0; i < export_directory->NumberOfNames; i++) + { + exports[i].name = name_ptr[i]; + exports[i].ordinal = ordinal_ptr[i]; + } + + qsort(exports, export_directory->NumberOfNames, sizeof(export_t), + export_compare_func); + + for (i = 0; i < export_directory->NumberOfNames; i++) + { + name_ptr[i] = exports[i].name; + ordinal_ptr[i] = exports[i].ordinal; + } + + free(exports); + } + } + } + + if (fixup_sections) + { + /* Update section flags */ + for (i = 0, section_header = IMAGE_FIRST_SECTION(nt_header); + i < nt_header->OptionalHeader.NumberOfRvaAndSizes; + i++, section_header++) + { + if (!strcmp((char*)section_header->Name, ".text") || + !strcmp((char*)section_header->Name, ".data") || + !strcmp((char*)section_header->Name, ".idata") || + !strcmp((char*)section_header->Name, ".bss")) + { + section_header->Characteristics |= IMAGE_SCN_MEM_NOT_PAGED; + section_header->Characteristics &= ~IMAGE_SCN_MEM_DISCARDABLE; + } + else if (!strcmp((char*)section_header->Name, "INIT")) + { + section_header->Characteristics |= IMAGE_SCN_MEM_DISCARDABLE; + } + else if (!strcmp((char*)section_header->Name, "PAGE")) + { + section_header->Characteristics |= IMAGE_SCN_MEM_NOT_PAGED; + } + } + } + + /* Recalculate checksum */ + nt_header->OptionalHeader.CheckSum = 0; + checksum = 0; + for (i = 0; i < (unsigned int)len; i += 2) + { + checksum += *(unsigned short *)(buffer + i); + checksum = (checksum + (checksum >> 16)) & 0xffff; + } + checksum += len; + nt_header->OptionalHeader.CheckSum = checksum; + + /* Write the output file */ + fd_out = open(argv[1], O_WRONLY | O_BINARY); + write(fd_out, buffer, len); + close(fd_out); + + return 0; +} diff --git a/reactos/tools/pefixup.mak b/reactos/tools/pefixup.mak index fec1a90ab7b..dc5854b49b1 100644 --- a/reactos/tools/pefixup.mak +++ b/reactos/tools/pefixup.mak @@ -10,10 +10,10 @@ PEFIXUP_TARGET = \ $(EXEPREFIX)$(PEFIXUP_OUT_)pefixup$(EXEPOSTFIX) PEFIXUP_SOURCES = \ - $(PEFIXUP_BASE_)pefixup.c + $(PEFIXUP_BASE_)pefixup.cpp PEFIXUP_OBJECTS = \ - $(addprefix $(INTERMEDIATE_), $(PEFIXUP_SOURCES:.c=.o)) + $(addprefix $(INTERMEDIATE_), $(PEFIXUP_SOURCES:.cpp=.o)) PEFIXUP_HOST_CFLAGS = $(TOOLS_CFLAGS) @@ -24,11 +24,11 @@ pefixup: $(PEFIXUP_TARGET) $(PEFIXUP_TARGET): $(PEFIXUP_OBJECTS) | $(PEFIXUP_OUT) $(ECHO_LD) - ${host_gcc} -g $(PEFIXUP_OBJECTS) $(PEFIXUP_HOST_LFLAGS) -o $@ + ${host_gpp} -g $(PEFIXUP_OBJECTS) $(PEFIXUP_HOST_LFLAGS) -o $@ -$(PEFIXUP_INT_)pefixup.o: $(PEFIXUP_BASE_)pefixup.c | $(PEFIXUP_INT) +$(PEFIXUP_INT_)pefixup.o: $(PEFIXUP_BASE_)pefixup.cpp | $(PEFIXUP_INT) $(ECHO_CC) - ${host_gcc} -g $(PEFIXUP_HOST_CFLAGS) -c $< -o $@ + ${host_gpp} -g $(PEFIXUP_HOST_CFLAGS) -c $< -o $@ .PHONY: pefixup_clean pefixup_clean: diff --git a/reactos/tools/rsym.cpp b/reactos/tools/rsym.cpp index b4399ad7846..fb348679b25 100644 --- a/reactos/tools/rsym.cpp +++ b/reactos/tools/rsym.cpp @@ -710,6 +710,13 @@ CreateOutputFile(FILE *OutFile, void *InData, { Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData); } +#if 0 + printf("Section %d (%s), location %x, size %x\n", + (DWORD)Section, + OutSectionHeaders[Section].Name, + (DWORD)OutSectionHeaders[Section].PointerToRawData, + (DWORD)OutSectionHeaders[Section].SizeOfRawData); +#endif for (i = 0; i < OutSectionHeaders[Section].SizeOfRawData / 2; i++) { CheckSum += ((unsigned short*) Data)[i]; From b6e4be8a15709e4ea95e1b0fc44f80098fd7adf0 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 17 Sep 2006 09:49:21 +0000 Subject: [PATCH 40/81] compile atapi.sys (add needed def for PAGE_SIZE) svn path=/branches/powerpc/; revision=24158 --- reactos/include/ddk/winddk.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index f667e60b26d..32bc6926be4 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -5500,6 +5500,10 @@ KeGetCurrentProcessorNumber(VOID) { return 0; // XXX arty fixme } + +#define PAGE_SIZE 0x1000 +#define PAGE_SHIFT 12L + #endif /* _X86_ */ /* From ee127f5c83e4ab20a1420ea4130f4a2f44e517d5 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 17 Sep 2006 09:51:36 +0000 Subject: [PATCH 41/81] Add needed definition (scsiport). KeGetCurrentIrql svn path=/branches/powerpc/; revision=24159 --- reactos/include/ddk/winddk.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 32bc6926be4..e107dfdf7cc 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -5390,6 +5390,12 @@ typedef struct _KPCR { UCHAR Number; /* 51 */ } KPCR, *PKPCR; /* 54 */ +NTHALAPI +KIRQL +DDKAPI +KeGetCurrentIrql( + VOID); + #if !defined(__INTERLOCKED_DECLARED) #define __INTERLOCKED_DECLARED From fd77489b59c8bacb120d51e24fcbddd9739a6a57 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 17 Sep 2006 10:00:59 +0000 Subject: [PATCH 42/81] Add disable, enable interrupts. svn path=/branches/powerpc/; revision=24160 --- reactos/include/ddk/winddk.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index e107dfdf7cc..a85ad4b248a 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -10758,6 +10758,7 @@ extern BOOLEAN KdDebuggerEnabled; #ifdef __GNUC__ /* Available as intrinsics on MSVC */ +#ifdef _X86_ static __inline void _disable(void) {__asm__ __volatile__("cli\n");} static __inline void _enable(void) {__asm__ __volatile__("sti\n");} @@ -10776,7 +10777,26 @@ static __inline ULONG64 __readcr4(void) :"=r"(Ret)); return (ULONG64)Ret; } - +#elif defined(_PPC_) +static __inline void _disable(void) { + /* Turn off EE bit */ + __asm__ __volatile__ + ("mfmsr 3\n\t" + "xor 4,5,5\n\t" + "addi 4,4,-1\n\t" + "and 0,3,4\n\t" + "mtmsr 0\n\t" + ); +} +static __inline void _enable(void) { + /* Turn on EE bit */ + __asm__ __volatile__ + ("mfmsr 3\n\t" + "ori 0,3,0x8000\n\t" + "mtmsr 0\n\t" + ); +} +#endif /*_X86_*/ #endif #ifdef __cplusplus From 99c1928bcbc79bd46ec29452f0890ac5da83c3e0 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 17 Sep 2006 10:19:34 +0000 Subject: [PATCH 43/81] Fix b0rked macros svn path=/branches/powerpc/; revision=24161 --- reactos/include/ddk/ndis.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/include/ddk/ndis.h b/reactos/include/ddk/ndis.h index 865be83e3d3..b33ec2823e8 100644 --- a/reactos/include/ddk/ndis.h +++ b/reactos/include/ddk/ndis.h @@ -2305,17 +2305,17 @@ NdisDestroyLookaheadBufferFromSharedMemory( #else #define NdisMoveMappedMemory(Destination, Source, Length) \ -{ - PUCHAR _Dest = Destination, _Src = Source, _End = _Dest + Length; - while (_Dest < _End) - *_Dest++ = _Src++; +{ \ + PUCHAR _Dest = Destination, _Src = Source, _End = _Dest + Length; \ + while (_Dest < _End) \ + *_Dest++ = _Src++; \ } #define NdisZeroMappedMemory(Destination, Length) \ -{ - PUCHAR _Dest = Destination, _End = _Dest + Length; - while (_Dest < _End) - *_Dest++ = 0; +{ \ + PUCHAR _Dest = Destination, _End = _Dest + Length; \ + while (_Dest < _End) \ + *_Dest++ = 0; \ } #endif /* _M_IX86 or _M_AMD64 */ From 1226225c284ef1f9286a4fbaa8b7028ae36c2e1c Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 17 Sep 2006 10:35:12 +0000 Subject: [PATCH 44/81] Add ppc version of bitops header (from linux) Compile usbuhci, usbohci svn path=/branches/powerpc/; revision=24163 --- .../usb/miniport/linux/asm/bitops-i386.h | 384 ++++++++++++++ .../usb/miniport/linux/asm/bitops-ppc.h | 468 ++++++++++++++++++ .../drivers/usb/miniport/linux/asm/bitops.h | 388 +-------------- 3 files changed, 860 insertions(+), 380 deletions(-) create mode 100644 reactos/drivers/usb/miniport/linux/asm/bitops-i386.h create mode 100644 reactos/drivers/usb/miniport/linux/asm/bitops-ppc.h diff --git a/reactos/drivers/usb/miniport/linux/asm/bitops-i386.h b/reactos/drivers/usb/miniport/linux/asm/bitops-i386.h new file mode 100644 index 00000000000..bb194fa25f2 --- /dev/null +++ b/reactos/drivers/usb/miniport/linux/asm/bitops-i386.h @@ -0,0 +1,384 @@ +#ifndef _I386_BITOPS_H +#define _I386_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +//#include + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif + +#define ADDR (*(volatile long *) addr) + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __set_bit(int nr, volatile void * addr) +{ + __asm__( + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/** + * __change_bit - Toggle a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * change_bit - Toggle a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * change_bit() is atomic and may not be reordered. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/* WARNING: non atomic and it can be reordered! */ +static __inline__ int __test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * test_and_change_bit - Change a bit and return its new value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +#if 0 /* Fool kernel-doc since it doesn't do macros yet */ +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static int test_bit(int nr, const volatile void * addr); +#endif + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + +/** + * find_first_zero_bit - find the first zero bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first zero bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/** + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +#ifdef __KERNEL__ + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "rm" (x)); + return r+1; +} + +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + +#define ext2_set_bit __test_and_set_bit +#define ext2_clear_bit __test_and_clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) __set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ + +#endif /* _I386_BITOPS_H */ diff --git a/reactos/drivers/usb/miniport/linux/asm/bitops-ppc.h b/reactos/drivers/usb/miniport/linux/asm/bitops-ppc.h new file mode 100644 index 00000000000..c85496b451e --- /dev/null +++ b/reactos/drivers/usb/miniport/linux/asm/bitops-ppc.h @@ -0,0 +1,468 @@ +/* + * bitops.h: Bit string operations on the ppc + */ + +#ifndef _PPC_BITOPS_H +#define _PPC_BITOPS_H +//#ifdef __KERNEL__ + +//#include +//#include +//#include +//#include + +/* + * The test_and_*_bit operations are taken to imply a memory barrier + * on SMP systems. + */ +#ifdef CONFIG_SMP +#define SMP_WMB "eieio\n" +#define SMP_MB "\nsync" +#else +#define SMP_WMB +#define SMP_MB +#endif /* CONFIG_SMP */ + +/* IBM Erratum 77 */ +#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" + +static __inline__ void set_bit(int nr, volatile unsigned long * addr) +{ + unsigned long old; + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + or %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc" ); +} + +/* + * non-atomic version + */ +static __inline__ void __set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + *p |= mask; +} + +/* + * clear_bit doesn't imply a memory barrier + */ +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() + +static __inline__ void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long old; + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + andc %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); +} + +/* + * non-atomic version + */ +static __inline__ void __clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + *p &= ~mask; +} + +static __inline__ void change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long old; + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + xor %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); +} + +/* + * non-atomic version + */ +static __inline__ void __change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + *p ^= mask; +} + +/* + * test_and_*_bit do imply a memory barrier (?) + */ +static __inline__ int test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned int old, t; + unsigned int mask = 1 << (nr & 0x1f); + volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + or %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc", "memory"); + + return (old & mask) != 0; +} + +/* + * non-atomic version + */ +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + unsigned long old = *p; + + *p = old | mask; + return (old & mask) != 0; +} + +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned int old, t; + unsigned int mask = 1 << (nr & 0x1f); + volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + andc %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc", "memory"); + + return (old & mask) != 0; +} + +/* + * non-atomic version + */ +static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + unsigned long old = *p; + + *p = old & ~mask; + return (old & mask) != 0; +} + +static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr) +{ + unsigned int old, t; + unsigned int mask = 1 << (nr & 0x1f); + volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\n\ +1: lwarx %0,0,%4 \n\ + xor %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc", "memory"); + + return (old & mask) != 0; +} + +/* + * non-atomic version + */ +static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + unsigned long old = *p; + + *p = old ^ mask; + return (old & mask) != 0; +} + +static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr) +{ + return ((addr[nr >> 5] >> (nr & 0x1f)) & 1) != 0; +} + +/* Return the bit position of the most significant 1 bit in a word */ +static __inline__ int __ilog2(unsigned long x) +{ + int lz; + + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x)); + return 31 - lz; +} + +static __inline__ int ffz(unsigned long x) +{ + if ((x = ~x) == 0) + return 32; + return __ilog2(x & -x); +} + +static inline int __ffs(unsigned long x) +{ + return __ilog2(x & -x); +} + +/* + * ffs: find first bit set. This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + return __ilog2(x & -x) + 1; +} + +#endif /* __KERNEL__ */ + +/* + * fls: find last (most-significant) bit set. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ +static __inline__ int fls(unsigned int x) +{ + int lz; + + asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x)); + return 32 - lz; +} + +#ifdef __KERNEL__ + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +/* + * Find the first bit set in a 140-bit bitmap. + * The first 100 bits are unlikely to be set. + */ +static inline int sched_find_first_bit(const unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (b[3]) + return __ffs(b[3]) + 96; + return __ffs(b[4]) + 128; +} + +/** + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ unsigned long find_next_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31UL; + unsigned int tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *p++; + tmp &= ~0UL << offset; + if (size < 32) + goto found_first; + if (tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size >= 32) { + if ((tmp = *p++) != 0) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= ~0UL >> (32 - size); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} + +/** + * find_first_bit - find the first set bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first set bit, not the number of the byte + * containing a bit. + */ +#define find_first_bit(addr, size) \ + find_next_bit((addr), (size), 0) + +/* + * This implementation of find_{first,next}_zero_bit was stolen from + * Linus' asm-alpha/bitops.h. + */ +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + +static __inline__ unsigned long find_next_zero_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned int * p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31UL; + unsigned int tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *p++; + tmp |= ~0UL >> (32-offset); + if (size < 32) + goto found_first; + if (tmp != ~0U) + goto found_middle; + size -= 32; + result += 32; + } + while (size >= 32) { + if ((tmp = *p++) != ~0U) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; +found_first: + tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + ffz(tmp); +} + + +#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)(addr)) +#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)(addr)) +#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)(addr)) +#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)(addr)) + +static __inline__ int ext2_test_bit(int nr, __const__ void * addr) +{ + __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; + + return (ADDR[nr >> 3] >> (nr & 7)) & 1; +} + +/* + * This implementation of ext2_find_{first,next}_zero_bit was stolen from + * Linus' asm-alpha/bitops.h and modified for a big-endian machine. + */ + +#define ext2_find_first_zero_bit(addr, size) \ + ext2_find_next_zero_bit((addr), (size), 0) + +static __inline__ unsigned long ext2_find_next_zero_bit(const void *addr, + unsigned long size, unsigned long offset) +{ + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31UL; + unsigned int tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = cpu_to_le32p(p++); + tmp |= ~0UL >> (32-offset); + if (size < 32) + goto found_first; + if (tmp != ~0U) + goto found_middle; + size -= 32; + result += 32; + } + while (size >= 32) { + if ((tmp = cpu_to_le32p(p++)) != ~0U) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = cpu_to_le32p(p); +found_first: + tmp |= ~0U << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + ffz(tmp); +} + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr) +#define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr)) +#define minix_test_and_clear_bit(nr,addr) ext2_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) ext2_test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size) + +//#endif /* __KERNEL__ */ +#endif /* _PPC_BITOPS_H */ + diff --git a/reactos/drivers/usb/miniport/linux/asm/bitops.h b/reactos/drivers/usb/miniport/linux/asm/bitops.h index bb194fa25f2..2c0972b6352 100644 --- a/reactos/drivers/usb/miniport/linux/asm/bitops.h +++ b/reactos/drivers/usb/miniport/linux/asm/bitops.h @@ -1,384 +1,12 @@ -#ifndef _I386_BITOPS_H -#define _I386_BITOPS_H +#ifndef _REACTOS_USB_BITOPS_H +#define _REACTOS_USB_BITOPS_H -/* - * Copyright 1992, Linus Torvalds. - */ - -//#include - -/* - * These have to be done with inline assembly: that way the bit-setting - * is guaranteed to be atomic. All bit operations return 0 if the bit - * was cleared before the operation and != 0 if it was not. - * - * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). - */ - -#ifdef CONFIG_SMP -#define LOCK_PREFIX "lock ; " +#ifdef _M_IX86 +#include "bitops-i386.h" +#elif defined(_M_PPC) +#include "bitops-ppc.h" #else -#define LOCK_PREFIX "" +#error "No bitops.h for this arch" #endif -#define ADDR (*(volatile long *) addr) - -/** - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static __inline__ void set_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btsl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} - -/** - * __set_bit - Set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * Unlike set_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static __inline__ void __set_bit(int nr, volatile void * addr) -{ - __asm__( - "btsl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} - -/** - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() - * in order to ensure changes are visible on other processors. - */ -static __inline__ void clear_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btrl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - -/** - * __change_bit - Toggle a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * Unlike change_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static __inline__ void __change_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( - "btcl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} - -/** - * change_bit - Toggle a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * change_bit() is atomic and may not be reordered. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static __inline__ void change_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btcl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} - -/** - * test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static __inline__ int test_and_set_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -/** - * __test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static __inline__ int __test_and_set_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__( - "btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr)); - return oldbit; -} - -/** - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static __inline__ int test_and_clear_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -/** - * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__( - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr)); - return oldbit; -} - -/* WARNING: non atomic and it can be reordered! */ -static __inline__ int __test_and_change_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -/** - * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static __inline__ int test_and_change_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -#if 0 /* Fool kernel-doc since it doesn't do macros yet */ -/** - * test_bit - Determine whether a bit is set - * @nr: bit number to test - * @addr: Address to start counting from - */ -static int test_bit(int nr, const volatile void * addr); -#endif - -static __inline__ int constant_test_bit(int nr, const volatile void * addr) -{ - return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; -} - -static __inline__ int variable_test_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( - "btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (ADDR),"Ir" (nr)); - return oldbit; -} - -#define test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - constant_test_bit((nr),(addr)) : \ - variable_test_bit((nr),(addr))) - -/** - * find_first_zero_bit - find the first zero bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search - * - * Returns the bit-number of the first zero bit, not the number of the byte - * containing a bit. - */ -static __inline__ int find_first_zero_bit(void * addr, unsigned size) -{ - int d0, d1, d2; - int res; - - if (!size) - return 0; - /* This looks at memory. Mark it volatile to tell gcc not to move it around */ - __asm__ __volatile__( - "movl $-1,%%eax\n\t" - "xorl %%edx,%%edx\n\t" - "repe; scasl\n\t" - "je 1f\n\t" - "xorl -4(%%edi),%%eax\n\t" - "subl $4,%%edi\n\t" - "bsfl %%eax,%%edx\n" - "1:\tsubl %%ebx,%%edi\n\t" - "shll $3,%%edi\n\t" - "addl %%edi,%%edx" - :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); - return res; -} - -/** - * find_next_zero_bit - find the first zero bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -static __inline__ int find_next_zero_bit (void * addr, int size, int offset) -{ - unsigned long * p = ((unsigned long *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; - - if (bit) { - /* - * Look for zero in first byte - */ - __asm__("bsfl %1,%0\n\t" - "jne 1f\n\t" - "movl $32, %0\n" - "1:" - : "=r" (set) - : "r" (~(*p >> bit))); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No zero yet, search remaining full bytes for a zero - */ - res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); - return (offset + set + res); -} - -/** - * ffz - find first zero in word. - * @word: The word to search - * - * Undefined if no zero exists, so code should check against ~0UL first. - */ -static __inline__ unsigned long ffz(unsigned long word) -{ - __asm__("bsfl %1,%0" - :"=r" (word) - :"r" (~word)); - return word; -} - -#ifdef __KERNEL__ - -/** - * ffs - find first bit set - * @x: the word to search - * - * This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ -static __inline__ int ffs(int x) -{ - int r; - - __asm__("bsfl %1,%0\n\t" - "jnz 1f\n\t" - "movl $-1,%0\n" - "1:" : "=r" (r) : "rm" (x)); - return r+1; -} - -/** - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * - * The Hamming Weight of a number is the total number of bits set in it. - */ - -#define hweight32(x) generic_hweight32(x) -#define hweight16(x) generic_hweight16(x) -#define hweight8(x) generic_hweight8(x) - -#endif /* __KERNEL__ */ - -#ifdef __KERNEL__ - -#define ext2_set_bit __test_and_set_bit -#define ext2_clear_bit __test_and_clear_bit -#define ext2_test_bit test_bit -#define ext2_find_first_zero_bit find_first_zero_bit -#define ext2_find_next_zero_bit find_next_zero_bit - -/* Bitmap functions for the minix filesystem. */ -#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) -#define minix_set_bit(nr,addr) __set_bit(nr,addr) -#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) -#define minix_test_bit(nr,addr) test_bit(nr,addr) -#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) - -#endif /* __KERNEL__ */ - -#endif /* _I386_BITOPS_H */ +#endif/*_REACTOS_USB_BITOPS_H*/ From 5ece9e35c8445d92b00a1247876ae07e028e95f1 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 25 Sep 2006 01:43:46 +0000 Subject: [PATCH 45/81] Add missing file from the branch. Preparing to move build hosts. svn path=/branches/powerpc/; revision=24265 --- reactos/lib/rtl/bitmap.c | 979 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 979 insertions(+) create mode 100644 reactos/lib/rtl/bitmap.c diff --git a/reactos/lib/rtl/bitmap.c b/reactos/lib/rtl/bitmap.c new file mode 100644 index 00000000000..584bfcf1660 --- /dev/null +++ b/reactos/lib/rtl/bitmap.c @@ -0,0 +1,979 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/rtl/bitmap.c + * PURPOSE: Bitmap functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + +/* MACROS *******************************************************************/ + +/* Bits set from LSB to MSB; used as mask for runs < 8 bits */ +static const BYTE NTDLL_maskBits[8] = { 0, 1, 3, 7, 15, 31, 63, 127 }; + +/* Number of set bits for each value of a nibble; used for counting */ +static const BYTE NTDLL_nibbleBitCount[16] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 +}; + +/* First set bit in a nibble; used for determining least significant bit */ +static const BYTE NTDLL_leastSignificant[16] = { + 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Last set bit in a nibble; used for determining most significant bit */ +static const signed char NTDLL_mostSignificant[16] = { + -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +/* PRIVATE FUNCTIONS *********************************************************/ + +static +int +NTDLL_RunSortFn(const void *lhs, + const void *rhs) +{ + if (((const RTL_BITMAP_RUN*)lhs)->NumberOfBits > ((const RTL_BITMAP_RUN*)rhs)->NumberOfBits) + return -1; + return 1; +} + +static +ULONG +WINAPI +NTDLL_FindRuns(PRTL_BITMAP lpBits, + PRTL_BITMAP_RUN lpSeries, + ULONG ulCount, + BOOLEAN bLongest, + ULONG (*fn)(PRTL_BITMAP,ULONG,PULONG)) +{ + BOOL bNeedSort = ulCount > 1 ? TRUE : FALSE; + ULONG ulPos = 0, ulRuns = 0; + + if (!ulCount) + return ~0U; + + while (ulPos < lpBits->SizeOfBitMap) + { + /* Find next set/clear run */ + ULONG ulSize, ulNextPos = fn(lpBits, ulPos, &ulSize); + + if (ulNextPos == ~0U) + break; + + if (bLongest && ulRuns == ulCount) + { + /* Sort runs with shortest at end, if they are out of order */ + if (bNeedSort) + qsort(lpSeries, ulRuns, sizeof(RTL_BITMAP_RUN), NTDLL_RunSortFn); + + /* Replace last run if this one is bigger */ + if (ulSize > lpSeries[ulRuns - 1].NumberOfBits) + { + lpSeries[ulRuns - 1].StartingIndex = ulNextPos; + lpSeries[ulRuns - 1].NumberOfBits = ulSize; + + /* We need to re-sort the array, _if_ we didn't leave it sorted */ + if (ulRuns > 1 && ulSize > lpSeries[ulRuns - 2].NumberOfBits) + bNeedSort = TRUE; + } + } + else + { + /* Append to found runs */ + lpSeries[ulRuns].StartingIndex = ulNextPos; + lpSeries[ulRuns].NumberOfBits = ulSize; + ulRuns++; + + if (!bLongest && ulRuns == ulCount) + break; + } + ulPos = ulNextPos + ulSize; + } + return ulRuns; +} + +static +ULONG +NTDLL_FindSetRun(PRTL_BITMAP lpBits, + ULONG ulStart, + PULONG lpSize) +{ + LPBYTE lpOut; + ULONG ulFoundAt = 0, ulCount = 0; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); + + while (1) + { + /* Check bits in first byte */ + const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; + const BYTE bFirst = *lpOut & bMask; + + if (bFirst) + { + /* Have a set bit in first byte */ + if (bFirst != bMask) + { + /* Not every bit is set */ + ULONG ulOffset; + + if (bFirst & 0x0f) + ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; + else + ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; + ulStart += ulOffset; + ulFoundAt = ulStart; + for (;ulOffset < 8; ulOffset++) + { + if (!(bFirst & (1 << ulOffset))) + { + *lpSize = ulCount; + return ulFoundAt; /* Set from start, but not until the end */ + } + ulCount++; + ulStart++; + } + /* Set to the end - go on to count further bits */ + lpOut++; + break; + } + /* every bit from start until the end of the byte is set */ + ulFoundAt = ulStart; + ulCount = 8 - (ulStart & 7); + ulStart = (ulStart & ~7u) + 8; + lpOut++; + break; + } + ulStart = (ulStart & ~7u) + 8; + lpOut++; + if (ulStart >= lpBits->SizeOfBitMap) + return ~0U; + } + + /* Count blocks of 8 set bits */ + while (*lpOut == 0xff) + { + ulCount += 8; + ulStart += 8; + if (ulStart >= lpBits->SizeOfBitMap) + { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; + } + lpOut++; + } + + /* Count remaining contiguous bits, if any */ + if (*lpOut & 1) + { + ULONG ulOffset = 0; + + for (;ulOffset < 7u; ulOffset++) + { + if (!(*lpOut & (1 << ulOffset))) + break; + ulCount++; + } + } + *lpSize = ulCount; + return ulFoundAt; +} + +static +ULONG +NTDLL_FindClearRun(PRTL_BITMAP lpBits, + ULONG ulStart, + PULONG lpSize) +{ + LPBYTE lpOut; + ULONG ulFoundAt = 0, ulCount = 0; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); + + while (1) + { + /* Check bits in first byte */ + const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; + const BYTE bFirst = (~*lpOut) & bMask; + + if (bFirst) + { + /* Have a clear bit in first byte */ + if (bFirst != bMask) + { + /* Not every bit is clear */ + ULONG ulOffset; + + if (bFirst & 0x0f) + ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; + else + ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; + ulStart += ulOffset; + ulFoundAt = ulStart; + for (;ulOffset < 8; ulOffset++) + { + if (!(bFirst & (1 << ulOffset))) + { + *lpSize = ulCount; + return ulFoundAt; /* Clear from start, but not until the end */ + } + ulCount++; + ulStart++; + } + /* Clear to the end - go on to count further bits */ + lpOut++; + break; + } + /* Every bit from start until the end of the byte is clear */ + ulFoundAt = ulStart; + ulCount = 8 - (ulStart & 7); + ulStart = (ulStart & ~7u) + 8; + lpOut++; + break; + } + ulStart = (ulStart & ~7u) + 8; + lpOut++; + if (ulStart >= lpBits->SizeOfBitMap) + return ~0U; + } + + /* Count blocks of 8 clear bits */ + while (!*lpOut) + { + ulCount += 8; + ulStart += 8; + if (ulStart >= lpBits->SizeOfBitMap) + { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; + } + lpOut++; + } + + /* Count remaining contiguous bits, if any */ + if (!(*lpOut & 1)) + { + ULONG ulOffset = 0; + + for (;ulOffset < 7u; ulOffset++) + { + if (*lpOut & (1 << ulOffset)) + break; + ulCount++; + } + } + *lpSize = ulCount; + return ulFoundAt; +} + +/* FUNCTIONS ****************************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +RtlInitializeBitMap(IN PRTL_BITMAP BitMapHeader, + IN PULONG BitMapBuffer, + IN ULONG SizeOfBitMap) +{ + /* Setup the bitmap header */ + BitMapHeader->SizeOfBitMap = SizeOfBitMap; + BitMapHeader->Buffer = BitMapBuffer; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +RtlAreBitsClear(IN PRTL_BITMAP BitMapHeader, + IN ULONG StartingIndex, + IN ULONG Length) +{ + LPBYTE lpOut; + ULONG ulRemainder; + + if (!BitMapHeader || !Length || + StartingIndex >= BitMapHeader->SizeOfBitMap || + Length > BitMapHeader->SizeOfBitMap - StartingIndex) + return FALSE; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); + + /* Check bits in first byte, if StartingIndex isn't a byte boundary */ + if (StartingIndex & 7) + { + if (Length > 7) + { + /* Check from start bit to the end of the byte */ + if (*lpOut & ((0xff << (StartingIndex & 7)) & 0xff)) + return FALSE; + lpOut++; + Length -= (8 - (StartingIndex & 7)); + } + else + { + /* Check from the start bit, possibly into the next byte also */ + USHORT initialWord = NTDLL_maskBits[Length] << (StartingIndex & 7); + + if (*lpOut & (initialWord & 0xff)) + return FALSE; + if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8))) + return FALSE; + return TRUE; + } + } + + /* Check bits in blocks of 8 bytes */ + ulRemainder = Length & 7; + Length >>= 3; + while (Length--) + { + if (*lpOut++) + return FALSE; + } + + /* Check remaining bits, if any */ + if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder]) + return FALSE; + return TRUE; +} + + +/* + * @implemented + */ +BOOLEAN NTAPI +RtlAreBitsSet(PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG Length) +{ + LPBYTE lpOut; + ULONG ulRemainder; + + + if (!BitMapHeader || !Length || + StartingIndex >= BitMapHeader->SizeOfBitMap || + Length > BitMapHeader->SizeOfBitMap - StartingIndex) + return FALSE; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); + + /* Check bits in first byte, if StartingIndex isn't a byte boundary */ + if (StartingIndex & 7) + { + if (Length > 7) + { + /* Check from start bit to the end of the byte */ + if ((*lpOut & + ((0xff << (StartingIndex & 7))) & 0xff) != ((0xff << (StartingIndex & 7) & 0xff))) + return FALSE; + lpOut++; + Length -= (8 - (StartingIndex & 7)); + } + else + { + /* Check from the start bit, possibly into the next byte also */ + USHORT initialWord = NTDLL_maskBits[Length] << (StartingIndex & 7); + + if ((*lpOut & (initialWord & 0xff)) != (initialWord & 0xff)) + return FALSE; + if ((initialWord & 0xff00) && + ((lpOut[1] & (initialWord >> 8)) != (initialWord >> 8))) + return FALSE; + return TRUE; + } + } + + /* Check bits in blocks of 8 bytes */ + ulRemainder = Length & 7; + Length >>= 3; + while (Length--) + { + if (*lpOut++ != 0xff) + return FALSE; + } + + /* Check remaining bits, if any */ + if (ulRemainder && + (*lpOut & NTDLL_maskBits[ulRemainder]) != NTDLL_maskBits[ulRemainder]) + return FALSE; + return TRUE; +} + + +/* + * @implemented + */ +VOID NTAPI +RtlClearAllBits(IN OUT PRTL_BITMAP BitMapHeader) +{ + memset(BitMapHeader->Buffer, 0, ((BitMapHeader->SizeOfBitMap + 31) & ~31) >> 3); +} + +/* + * @implemented + */ +VOID +NTAPI +RtlClearBit(PRTL_BITMAP BitMapHeader, + ULONG BitNumber) +{ + PULONG Ptr; + + if (BitNumber >= BitMapHeader->SizeOfBitMap) return; + + Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); + *Ptr &= ~(1 << (BitNumber % 32)); +} + +/* + * @implemented + */ +VOID +NTAPI +RtlClearBits(IN PRTL_BITMAP BitMapHeader, + IN ULONG StartingIndex, + IN ULONG NumberToClear) +{ + LPBYTE lpOut; + + if (!BitMapHeader || !NumberToClear || + StartingIndex >= BitMapHeader->SizeOfBitMap || + NumberToClear > BitMapHeader->SizeOfBitMap - StartingIndex) + return; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); + + /* Clear bits in first byte, if StartingIndex isn't a byte boundary */ + if (StartingIndex & 7) + { + if (NumberToClear > 7) + { + /* Clear from start bit to the end of the byte */ + *lpOut++ &= ~(0xff << (StartingIndex & 7)); + NumberToClear -= (8 - (StartingIndex & 7)); + } + else + { + /* Clear from the start bit, possibly into the next byte also */ + USHORT initialWord = ~(NTDLL_maskBits[NumberToClear] << (StartingIndex & 7)); + + *lpOut++ &= (initialWord & 0xff); + *lpOut &= (initialWord >> 8); + return; + } + } + + /* Clear bits (in blocks of 8) on whole byte boundaries */ + if (NumberToClear >> 3) + { + memset(lpOut, 0, NumberToClear >> 3); + lpOut = lpOut + (NumberToClear >> 3); + } + + /* Clear remaining bits, if any */ + if (NumberToClear & 0x7) + *lpOut &= ~NTDLL_maskBits[NumberToClear & 0x7]; +} + + +/* + * @implemented + */ +ULONG NTAPI +RtlFindClearBits(PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex) +{ + ULONG ulPos, ulEnd; + + if (!BitMapHeader || !NumberToFind || NumberToFind > BitMapHeader->SizeOfBitMap) + return ~0U; + + ulEnd = BitMapHeader->SizeOfBitMap; + + if (HintIndex + NumberToFind > BitMapHeader->SizeOfBitMap) + HintIndex = 0; + + ulPos = HintIndex; + + while (ulPos < ulEnd) + { + /* FIXME: This could be made a _lot_ more efficient */ + if (RtlAreBitsClear(BitMapHeader, ulPos, NumberToFind)) + return ulPos; + + /* Start from the beginning if we hit the end and started from HintIndex */ + if (ulPos == ulEnd - 1 && HintIndex) + { + ulEnd = HintIndex; + ulPos = HintIndex = 0; + } + else + ulPos++; + } + return ~0U; +} + + + + + + + +/* + * @implemented + */ +ULONG NTAPI +RtlFindClearRuns(PRTL_BITMAP BitMapHeader, + PRTL_BITMAP_RUN RunArray, + ULONG SizeOfRunArray, + BOOLEAN LocateLongestRuns) +{ + return NTDLL_FindRuns(BitMapHeader, RunArray, SizeOfRunArray, LocateLongestRuns, NTDLL_FindClearRun); +} + + +/* + * @unimplemented + */ +ULONG NTAPI +RtlFindLastBackwardRunClear(IN PRTL_BITMAP BitMapHeader, + IN ULONG FromIndex, + IN PULONG StartingRunIndex) +{ + UNIMPLEMENTED; + return 0; +} + +/* + * @implemented + */ +ULONG NTAPI +RtlFindNextForwardRunClear(IN PRTL_BITMAP BitMapHeader, + IN ULONG FromIndex, + IN PULONG StartingRunIndex) +{ + ULONG ulSize = 0; + + if (BitMapHeader && FromIndex < BitMapHeader->SizeOfBitMap && StartingRunIndex) + *StartingRunIndex = NTDLL_FindClearRun(BitMapHeader, FromIndex, &ulSize); + + return ulSize; +} + +/* + * @implemented + */ +ULONG NTAPI +RtlFindFirstRunSet(IN PRTL_BITMAP BitMapHeader, + IN PULONG StartingIndex) +{ + ULONG Size; + ULONG Index; + ULONG Count; + PULONG Ptr; + ULONG Mask; + + Size = BitMapHeader->SizeOfBitMap; + if (*StartingIndex > Size) + { + *StartingIndex = (ULONG)-1; + return 0; + } + + Index = *StartingIndex; + Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32); + Mask = 1 << (Index & 0x1F); + + /* Skip clear bits */ + for (; Index < Size && ~*Ptr & Mask; Index++) + { + Mask <<= 1; + + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + /* Return index of first set bit */ + if (Index >= Size) + { + *StartingIndex = (ULONG)-1; + return 0; + } + else + { + *StartingIndex = Index; + } + + /* Count set bits */ + for (Count = 0; Index < Size && *Ptr & Mask; Index++) + { + Count++; + Mask <<= 1; + + if (Mask == 0) + { + Mask = 1; + Ptr++; + } + } + + return Count; +} + + +/* + * @implemented + */ +ULONG NTAPI +RtlFindLongestRunClear(PRTL_BITMAP BitMapHeader, + PULONG StartingIndex) +{ + RTL_BITMAP_RUN br; + + if (RtlFindClearRuns(BitMapHeader, &br, 1, TRUE) == 1) + { + if (StartingIndex) + *StartingIndex = br.StartingIndex; + return br.NumberOfBits; + } + return 0; +} + + +/* + * @implemented + */ +ULONG NTAPI +RtlFindLongestRunSet(PRTL_BITMAP BitMapHeader, + PULONG StartingIndex) +{ + RTL_BITMAP_RUN br; + + if (NTDLL_FindRuns(BitMapHeader, &br, 1, TRUE, NTDLL_FindSetRun) == 1) + { + if (StartingIndex) + *StartingIndex = br.StartingIndex; + return br.NumberOfBits; + } + return 0; +} + + +/* + * @implemented + */ +ULONG NTAPI +RtlFindSetBits(PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex) +{ + ULONG ulPos, ulEnd; + + if (!BitMapHeader || !NumberToFind || NumberToFind > BitMapHeader->SizeOfBitMap) + return ~0U; + + ulEnd = BitMapHeader->SizeOfBitMap; + + if (HintIndex + NumberToFind > BitMapHeader->SizeOfBitMap) + HintIndex = 0; + + ulPos = HintIndex; + + while (ulPos < ulEnd) + { + /* FIXME: This could be made a _lot_ more efficient */ + if (RtlAreBitsSet(BitMapHeader, ulPos, NumberToFind)) + return ulPos; + + /* Start from the beginning if we hit the end and had a hint */ + if (ulPos == ulEnd - 1 && HintIndex) + { + ulEnd = HintIndex; + ulPos = HintIndex = 0; + } + else + ulPos++; + } + return ~0U; +} + + +/* + * @implemented + */ +ULONG NTAPI +RtlFindSetBitsAndClear(PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex) +{ + ULONG ulPos; + + ulPos = RtlFindSetBits(BitMapHeader, NumberToFind, HintIndex); + if (ulPos != ~0U) + RtlClearBits(BitMapHeader, ulPos, NumberToFind); + return ulPos; +} + + + + + +/* + * @implemented + */ +ULONG NTAPI +RtlNumberOfSetBits(PRTL_BITMAP BitMapHeader) +{ + ULONG ulSet = 0; + + if (BitMapHeader) + { + LPBYTE lpOut = (BYTE *)BitMapHeader->Buffer; + ULONG Length, ulRemainder; + BYTE bMasked; + + Length = BitMapHeader->SizeOfBitMap >> 3; + ulRemainder = BitMapHeader->SizeOfBitMap & 0x7; + + while (Length--) + { + ulSet += NTDLL_nibbleBitCount[*lpOut >> 4]; + ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf]; + lpOut++; + } + + bMasked = *lpOut & NTDLL_maskBits[ulRemainder]; + ulSet += NTDLL_nibbleBitCount[bMasked >> 4]; + ulSet += NTDLL_nibbleBitCount[bMasked & 0xf]; + } + return ulSet; +} + + +/* + * @implemented + */ +VOID NTAPI +RtlSetAllBits(IN OUT PRTL_BITMAP BitMapHeader) +{ + memset(BitMapHeader->Buffer, 0xff, ((BitMapHeader->SizeOfBitMap + 31) & ~31) >> 3); +} + + +/* + * @implemented + */ +VOID NTAPI +RtlSetBit(PRTL_BITMAP BitMapHeader, + ULONG BitNumber) +{ + PULONG Ptr; + + if (BitNumber >= BitMapHeader->SizeOfBitMap) + return; + + Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); + + *Ptr |= (1 << (BitNumber % 32)); +} + + +/* + * @implemented + */ +VOID NTAPI +RtlSetBits(PRTL_BITMAP BitMapHeader, + ULONG StartingIndex, + ULONG NumberToSet) +{ + LPBYTE lpOut; + + if (!BitMapHeader || !NumberToSet || + StartingIndex >= BitMapHeader->SizeOfBitMap || + NumberToSet > BitMapHeader->SizeOfBitMap - StartingIndex) + return; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u); + + /* Set bits in first byte, if StartingIndex isn't a byte boundary */ + if (StartingIndex & 7) + { + if (NumberToSet > 7) + { + /* Set from start bit to the end of the byte */ + *lpOut++ |= 0xff << (StartingIndex & 7); + NumberToSet -= (8 - (StartingIndex & 7)); + } + else + { + /* Set from the start bit, possibly into the next byte also */ + USHORT initialWord = NTDLL_maskBits[NumberToSet] << (StartingIndex & 7); + + *lpOut++ |= (initialWord & 0xff); + *lpOut |= (initialWord >> 8); + return; + } + } + + /* Set bits up to complete byte count */ + if (NumberToSet >> 3) + { + memset(lpOut, 0xff, NumberToSet >> 3); + lpOut = lpOut + (NumberToSet >> 3); + } + + /* Set remaining bits, if any */ + *lpOut |= NTDLL_maskBits[NumberToSet & 0x7]; +} + + +/* + * @implemented + */ +BOOLEAN NTAPI +RtlTestBit(PRTL_BITMAP BitMapHeader, + ULONG BitNumber) +{ + PULONG Ptr; + + if (BitNumber >= BitMapHeader->SizeOfBitMap) + return FALSE; + + Ptr = (PULONG)BitMapHeader->Buffer + (BitNumber / 32); + + return (*Ptr & (1 << (BitNumber % 32))); +} + +/* + * @implemented + */ +ULONG NTAPI +RtlFindFirstRunClear(PRTL_BITMAP BitMapHeader, + PULONG StartingIndex) +{ + return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex); +} + +/* + * @implemented + */ +ULONG NTAPI +RtlNumberOfClearBits(PRTL_BITMAP BitMapHeader) +{ + + if (BitMapHeader) + return BitMapHeader->SizeOfBitMap - RtlNumberOfSetBits(BitMapHeader); + return 0; +} + +/* + * @implemented + */ +ULONG NTAPI +RtlFindClearBitsAndSet(PRTL_BITMAP BitMapHeader, + ULONG NumberToFind, + ULONG HintIndex) +{ + ULONG ulPos; + + ulPos = RtlFindClearBits(BitMapHeader, NumberToFind, HintIndex); + if (ulPos != ~0U) + RtlSetBits(BitMapHeader, ulPos, NumberToFind); + return ulPos; +} + +/* + * @implemented + */ +CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong) +{ + signed char ret = 32; + DWORD dw; + + if (!(dw = (ulLong >> 32))) + { + ret = 0; + dw = (DWORD)ulLong; + } + if (dw & 0xffff0000) + { + dw >>= 16; + ret += 16; + } + if (dw & 0xff00) + { + dw >>= 8; + ret += 8; + } + if (dw & 0xf0) + { + dw >>= 4; + ret += 4; + } + return ret + NTDLL_mostSignificant[dw]; +} + +/* + * @implemented + */ +CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong) +{ + signed char ret = 0; + DWORD dw; + + if (!(dw = (DWORD)ulLong)) + { + ret = 32; + if (!(dw = ulLong >> 32)) return -1; + } + if (!(dw & 0xffff)) + { + dw >>= 16; + ret += 16; + } + if (!(dw & 0xff)) + { + dw >>= 8; + ret += 8; + } + if (!(dw & 0x0f)) + { + dw >>= 4; + ret += 4; + } + return ret + NTDLL_leastSignificant[dw & 0x0f]; +} + +/* EOF */ From 1956e17bc7a8114384068d2a984914aca07d9ae5 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 26 Sep 2006 03:29:53 +0000 Subject: [PATCH 46/81] Added some needed OFW calls. svn path=/branches/powerpc/; revision=24274 --- reactos/tools/ofw_interface/calls.ofw | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index 4bbab90241b..e05463c36b8 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -8,12 +8,14 @@ read 3 1 int char*:arg2 int int exit 0 0 child 1 1 int int peer 1 1 int int +parent 1 1 int int seek 3 1 int int int int # MMU methods # claim (virt size align -- base) claim 3 1 int int int int # release (virt size --) release 2 0 int int +package-to-path 3 1 int char*:arg2 int int # Declare the call-method BE function +call-method 0 0 # Convenience functions that interact closely with OFW (written in BE asm) From 77caf5c3c7bf81c64ec03df61904e11555bf4d57 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 26 Sep 2006 03:33:05 +0000 Subject: [PATCH 47/81] Checkpoint in here. More work needed. svn path=/branches/powerpc/; revision=24275 --- reactos/ntoskrnl/include/internal/ke.h | 4 + .../ntoskrnl/include/internal/powerpc/mm.h | 37 +++ reactos/ntoskrnl/ke/krnlinit.c | 2 + reactos/ntoskrnl/ke/powerpc/main_asm.S | 6 +- reactos/ntoskrnl/ntoskrnl.lnk | 286 ++++++++++++------ reactos/ntoskrnl/ntoskrnl.rbuild | 1 + 6 files changed, 247 insertions(+), 89 deletions(-) create mode 100644 reactos/ntoskrnl/include/internal/powerpc/mm.h diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 1acd0c8acec..de862ff9c9b 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -73,11 +73,13 @@ extern PVOID KeUserExceptionDispatcher; extern PVOID KeRaiseUserExceptionDispatcher; extern LARGE_INTEGER SystemBootTime; extern ULONG_PTR KERNEL_BASE; +#ifdef _M_IX86 extern ULONG KeI386NpxPresent; extern ULONG KeI386XMMIPresent; extern ULONG KeI386FxsrPresent; extern ULONG KeI386CpuType; extern ULONG KeI386CpuStep; +#endif extern ULONG KeProcessorArchitecture; extern ULONG KeProcessorLevel; extern ULONG KeProcessorRevision; @@ -94,6 +96,7 @@ extern PULONG KiInterruptTemplateObject; extern PULONG KiInterruptTemplateDispatch; extern PULONG KiInterruptTemplate2ndDispatch; extern ULONG KiUnexpectedEntrySize; +#ifdef _M_IX86 extern PVOID Ki386IopmSaveArea; extern ULONG KeI386EFlagsAndMaskV86; extern ULONG KeI386EFlagsOrMaskV86; @@ -103,6 +106,7 @@ extern KGDTENTRY KiBootGdt[]; extern KDESCRIPTOR KiGdtDescriptor; extern KDESCRIPTOR KiIdtDescriptor; extern KTSS KiBootTss; +#endif extern UCHAR P0BootStack[]; extern UCHAR KiDoubleFaultStack[]; extern FAST_MUTEX KernelAddressSpaceLock; diff --git a/reactos/ntoskrnl/include/internal/powerpc/mm.h b/reactos/ntoskrnl/include/internal/powerpc/mm.h new file mode 100644 index 00000000000..558edd80f8e --- /dev/null +++ b/reactos/ntoskrnl/include/internal/powerpc/mm.h @@ -0,0 +1,37 @@ +/* + * Lowlevel memory managment definitions + */ + +#ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_MM_H +#define __NTOSKRNL_INCLUDE_INTERNAL_I386_MM_H + +#if 0 +/* + * Page access attributes (or these together) + */ +#define PA_READ (1<<0) +#define PA_WRITE ((1<<0)+(1<<1)) +#define PA_EXECUTE PA_READ +#define PA_PCD (1<<4) +#define PA_PWT (1<<3) + +/* + * Page attributes + */ +#define PA_USER (1<<2) +#define PA_SYSTEM (0) +#endif + +#define FLUSH_TLB { \ + } + +#define FLUSH_TLB_ONE(addr) { \ +} + +struct _EPROCESS; +PULONG MmGetPageDirectory(VOID); + +#define PAGE_MASK(x) ((x)&(~0xfff)) +#define PAE_PAGE_MASK(x) ((x)&(~0xfffLL)) + +#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_MM_H */ diff --git a/reactos/ntoskrnl/ke/krnlinit.c b/reactos/ntoskrnl/ke/krnlinit.c index e766864cb3c..ce4b63e6cbc 100644 --- a/reactos/ntoskrnl/ke/krnlinit.c +++ b/reactos/ntoskrnl/ke/krnlinit.c @@ -327,6 +327,8 @@ KeInit2(VOID) } /* Set IDT to writable */ +#ifdef _M_IX86 Protect = MmGetPageProtect(NULL, (PVOID)KiIdt); MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE); +#endif } diff --git a/reactos/ntoskrnl/ke/powerpc/main_asm.S b/reactos/ntoskrnl/ke/powerpc/main_asm.S index 34f65311035..d8be8a8a995 100644 --- a/reactos/ntoskrnl/ke/powerpc/main_asm.S +++ b/reactos/ntoskrnl/ke/powerpc/main_asm.S @@ -28,6 +28,8 @@ _kernel_trap_stack_top: .text .globl NtProcessStartup + .globl KiSystemStartup + .globl KiRosPrepareForSystemStartup NtProcessStartup: lis 0,AP_MAGIC@ha ori 0,0,AP_MAGIC@l @@ -42,7 +44,7 @@ NtProcessStartup: /* * Call the application processor initialization code */ - bl _KiSystemStartup + bl KiSystemStartup .m1: /* Load the initial kernel stack */ @@ -53,5 +55,5 @@ NtProcessStartup: /* Call the main kernel initialization */ mr 3,5 mr 4,6 - bl __main + bl KiRosPrepareForSystemStartup diff --git a/reactos/ntoskrnl/ntoskrnl.lnk b/reactos/ntoskrnl/ntoskrnl.lnk index c759babe6b9..fe2a58fba19 100644 --- a/reactos/ntoskrnl/ntoskrnl.lnk +++ b/reactos/ntoskrnl/ntoskrnl.lnk @@ -1,105 +1,217 @@ -OUTPUT_FORMAT(pei-i386) -ENTRY(_mainCRTStartup) +/* Default linker script, for normal executables */ +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", + "elf32-powerpc") +OUTPUT_ARCH(powerpc:common) +ENTRY(_start) +SEARCH_DIR("/usr/powerpc-unknown-linux-gnu/lib"); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +PROVIDE (__stack = 0); PROVIDE (___stack = 0); SECTIONS { - .text __image_base__ + __section_alignment__ : + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x10000000); . = 0x10000000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data.rel.ro : { *(.rel.data.rel.ro*) } + .rela.data.rel.ro : { *(.rel.data.rel.ro*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { - __text_start__ = .; - *(.init) - *(.text) - *(SORT(.text$*)) - *(.glue_7t) - *(.glue_7) - ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; - LONG (-1); *(.ctors); *(.ctor); LONG (0); - ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; - LONG (-1); *(.dtors); *(.dtor); LONG (0); - *(.fini) - /* ??? Why is .gcc_exc here? */ - *(.gcc_exc) - __text_end__ = .; - *(.gcc_except_table) - } - init BLOCK(__section_alignment__) : + KEEP (*(.init)) + } =0 + .text : { - __init_start__ = . ; - *(init) - __init_end__ = . ; - } - /* The Cygwin32 library uses a section to avoid copying certain data - on fork. This used to be named ".data". The linker used - to include this between __data_start__ and __data_end__, but that - breaks building the cygwin32 dll. Instead, we name the section - ".data_cygwin_nocopy" and explictly include it after __data_end__. */ - .data BLOCK(__section_alignment__) : + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .fini : { - __data_start__ = . ; - *(.data) - *(.data2) - *(SORT(.data$*)) - __data_end__ = . ; - *(.data_cygwin_nocopy) - } - .rdata BLOCK(__section_alignment__) : + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { KEEP (*(.preinit_array)) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { KEEP (*(.init_array)) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { KEEP (*(.fini_array)) } + PROVIDE (__fini_array_end = .); + .ctors : { - *(.rdata) - *(SORT(.rdata$*)) - *(.eh_frame) + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) } - .edata BLOCK(__section_alignment__) : + .dtors : { - *(.edata) + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) } - /DISCARD/ : + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .fixup : { *(.fixup) } + .got1 : { *(.got1) } + .got2 : { *(.got2) } + .dynamic : { *(.dynamic) } + . = DATA_SEGMENT_RELRO_END (0, .); + .data : { - *(.debug$S) - *(.debug$T) - *(.debug$F) - *(.drectve) + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) } - - .idata BLOCK(__section_alignment__) : + .data1 : { *(.data1) } + .got : { *(.got.plt) *(.got) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { - /* This cannot currently be handled with grouped sections. - See pe.em:sort_sections. */ - SORT(*)(.idata$2) - SORT(*)(.idata$3) - /* These zeroes mark the end of the import list. */ - LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); - SORT(*)(.idata$4) - SORT(*)(.idata$5) - SORT(*)(.idata$6) - SORT(*)(.idata$7) + *(.sdata .sdata.* .gnu.linkonce.s.*) } - .CRT BLOCK(__section_alignment__) : - { - *(SORT(.CRT$*)) - } - .rsrc BLOCK(__section_alignment__) : - { - *(.rsrc) - *(SORT(.rsrc$*)) - } - .bss BLOCK(__section_alignment__) : + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { - __bss_start__ = . ; - *(.bss) - *(COMMON) - __bss_end__ = . ; + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); } - .reloc BLOCK(__section_alignment__) : - { - *(.reloc) - /* These zeroes mark the end of the reloc section. */ - LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); - } - .stab BLOCK(__section_alignment__) (NOLOAD) : + .plt : { *(.plt) } + .bss : { - [ .stab ] - } - .stabstr BLOCK(__section_alignment__) (NOLOAD) : - { - [ .stabstr ] + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); } + . = ALIGN(32 / 8); + _end = .; + __end = .; + PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /DISCARD/ : { *(.note.GNU-stack) } } - diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 777b0ca4b1f..7b6c1e9f345 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -45,6 +45,7 @@ main_asm.S + kiinit.c ppc_irq.c From 6421038be31b5cfcd9b0912e81bf44c75529b6f3 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 1 Oct 2006 03:30:06 +0000 Subject: [PATCH 48/81] Remove the need to relocate freeldr. We now use it in-place as stored in ofwldr's .data. Fix call_ofw for more modern macs. Add more debugging type calls to calls.ofw. svn path=/branches/powerpc/; revision=24327 --- reactos/boot/freeldr/bootsect/ofw_util.s | 72 ++++++++++++++++------- reactos/boot/freeldr/bootsect/ofwboot.s | 46 +-------------- reactos/tools/ofw_interface/calls.ofw | 2 + reactos/tools/ppc.lost+found/link-freeldr | 9 +-- 4 files changed, 59 insertions(+), 70 deletions(-) diff --git a/reactos/boot/freeldr/bootsect/ofw_util.s b/reactos/boot/freeldr/bootsect/ofw_util.s index 7e0aa840bc2..2d2b5effff6 100644 --- a/reactos/boot/freeldr/bootsect/ofw_util.s +++ b/reactos/boot/freeldr/bootsect/ofw_util.s @@ -25,56 +25,80 @@ call_ofw: * Other arg registers are unchanged. * Note that these 4 instructions are in reverse order due to * little-endian convention */ + stw %r8,24(%r1) + subi %r1,%r1,0x100 + stw %r8,0(%r1) + mflr %r8 + /* - */ + stw %r3,4(%r1) + stw %r4,8(%r1) + stw %r5,12(%r1) + stw %r6,16(%r1) + /* - */ + stw %r7,20(%r1) + stw %r9,28(%r1) + stw %r10,32(%r1) + stw %r20,36(%r1) + + /* - */ subi %r20,%r20,1 mfmsr %r20 mtmsr %r20 nop - /* Now normal ordering resumes */ - subi %r1,%r1,0x100 - stw %r8,4(%r1) - stw %r9,8(%r1) - stw %r10,12(%r1) + sync + isync + + /* BE MODE */ mflr %r8 stw %r8,16(%r1) lis %r10,0xe00000@ha addi %r8,%r10,ofw_functions_addr@l + /* - */ lwz %r9,0(%r8) add %r8,%r3,%r9 lwz %r9,0(%r8) mtctr %r9 + /* - */ mr %r3,%r4 mr %r4,%r5 mr %r5,%r6 mr %r6,%r7 + /* - */ mr %r7,%r8 mr %r8,%r9 - /* Goto the swapped function */ + /* Call ofw proxy function */ bctrl + nop - lwz %r8,16(%r1) - mtlr %r8 - - lwz %r8,4(%r1) - lwz %r9,8(%r1) - lwz %r10,12(%r1) - - addi %r1,%r1,0x100 /* Ok, go back to little endian */ - - .align 4 - mfmsr %r0 - ori %r0,%r0,1 - + mfmsr %r10 + ori %r10,%r10,1 nop - mtmsr %r0 + mtmsr %r10 - /* Note that this is little-endian from here on */ + sync + isync + + /* LE MODE */ + mtlr %r8 + lwz %r8,0(%r1) + lwz %r4,8(%r1) + lwz %r5,12(%r1) + /* - */ + lwz %r6,16(%r1) + lwz %r7,20(%r1) + lwz %r8,24(%r1) + lwz %r9,28(%r1) + /* - */ + lwz %r10,32(%r1) + lwz %r20,36(%r1) + /* - */ blr - nop + addi %r1,%r1,0x100 prim_strlen: mr %r5,%r3 @@ -93,6 +117,10 @@ copy_bits: cmp 0,0,%r3,%r4 bgelr + andi. %r6,%r3,0xfff + beql ofw_dumpregs + mtdec %r3 + lwz %r6,0(%r3) stw %r6,0(%r5) addi %r3,%r3,4 diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index ff49c6582ef..4158d2de2a8 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -23,56 +23,14 @@ _begin: addi %r3,%r3,freeldr_banner - _start bl ofw_print_string - bl ofw_print_eol - - /* Claim enough bytes to place freeldr at 0x8000 */ - lis %r3,0x8000@ha - li %r3,0x8000@l - - lis %r4,_binary_freeldr_tmp_end@ha - addi %r4,%r4,_binary_freeldr_tmp_end@l - lis %r5,_binary_freeldr_tmp_start@ha - addi %r5,%r5,_binary_freeldr_tmp_start@l - sub %r4,%r4,%r5 - li %r5,0x1000 - - bl ofw_claim - - /* Now copy freeldr */ - lis %r3,0x8000@ha - addi %r3,%r3,0x8000@l - - lis %r4,_binary_freeldr_tmp_end@ha - addi %r4,%r4,_binary_freeldr_tmp_end@l - lis %r5,_binary_freeldr_tmp_start@ha - addi %r5,%r5,_binary_freeldr_tmp_start@l - /* Make sufficient room for .bss */ - sub %r4,%r4,%r5 - addi %r4,%r4,0x6000 - - xor %r5,%r5,%r5 - li %r5,0x1000 - - bl ofw_claim - - lis %r4,_binary_freeldr_tmp_end@ha - addi %r4,%r4,_binary_freeldr_tmp_end@l - lis %r3,_binary_freeldr_tmp_start@ha - addi %r3,%r3,_binary_freeldr_tmp_start@l - - lis %r5,0x8000@ha - addi %r5,%r5,0x8000@l - - bl ofw_dumpregs - bl copy_bits bl zero_registers /* Zero CTR */ mtcr %r31 - lis %r3,0x8000@ha - addi %r3,%r3,0x8000@l + lis %r3,0xe17000@ha + addi %r3,%r3,0xe17000@l mtlr %r3 diff --git a/reactos/tools/ofw_interface/calls.ofw b/reactos/tools/ofw_interface/calls.ofw index e05463c36b8..7d8f0be112d 100644 --- a/reactos/tools/ofw_interface/calls.ofw +++ b/reactos/tools/ofw_interface/calls.ofw @@ -22,6 +22,8 @@ package-to-path 3 1 int char*:arg2 int int -dumpregs 0 0 -print_string 1 0 char* -print_number 1 0 int +-print_eol 0 0 +-print_space 0 0 # MMU Methods @phys2virt!translate 4 1 int int int int&0 int @virt2phys!translate 2 1 int int&1 int diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr index 313382256ea..ae44a7eaf86 100755 --- a/reactos/tools/ppc.lost+found/link-freeldr +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -1,9 +1,10 @@ #!/bin/sh -v export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin -ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/cmlib/cmlib.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a -objcopy -O binary freeldr.elf freeldr.tmp.le +powerpc-unknown-linux-gnu-ld -EL -g -nostartfiles -nostdlib -N -Ttext=0xe17000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/cmlib/cmlib.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a +powerpc-unknown-linux-gnu-objcopy -O binary freeldr.elf freeldr.tmp.le output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp -objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload +powerpc-unknown-linux-gnu-objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s boot/freeldr/bootsect/ofw_util.s boot/freeldr/bootsect/ofw.s -ld -EB -Ttext 0xe00000 -Tdata 0xe17000 -e _begin -o ofwldr ofwboot.o ofwldr.payload +powerpc-unknown-linux-gnu-ld -EB -Ttext 0xe00000 -Tdata 0xe17000 -e _begin -o ofwldr.x ofwboot.o ofwldr.payload +powerpc-unknown-linux-gnu-objcopy --only-section=.text --only-section=.data ofwldr.x ofwldr From 042ade46e981317dfb4051f0f28fa626d7b5603f Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 1 Oct 2006 05:46:59 +0000 Subject: [PATCH 49/81] Working out boot video, fixed memory map completely. svn path=/branches/powerpc/; revision=24332 --- .../freeldr/freeldr/arch/powerpc/compat.h | 108 ++++++++++ .../boot/freeldr/freeldr/arch/powerpc/mach.c | 199 +++++++++++++----- 2 files changed, 257 insertions(+), 50 deletions(-) create mode 100644 reactos/boot/freeldr/freeldr/arch/powerpc/compat.h diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h new file mode 100644 index 00000000000..66797a6929d --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h @@ -0,0 +1,108 @@ +#ifndef _FREELDR_ARCH_COMPAT_H +#define _FREELDR_ARCH_COMPAT_H + +#define __init +#define __initdata + +#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */ +#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */ +#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */ +#define SPRN_LDSTDB 0x3f4 /* */ +#define SPRN_LR 0x008 /* Link Register */ +#ifndef SPRN_PIR +#define SPRN_PIR 0x3FF /* Processor Identification Register */ +#endif +#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ +#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ +#define SPRN_PURR 0x135 /* Processor Utilization of Resources Reg */ +#define SPRN_PVR 0x11F /* Processor Version Register */ +#define SPRN_RPA 0x3D6 /* Required Physical Address Register */ +#define SPRN_SDA 0x3BF /* Sampled Data Address Register */ +#define SPRN_SDR1 0x019 /* MMU Hash Base Register */ +#define SPRN_ASR 0x118 /* Address Space Register */ +#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ +#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ +#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ +#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ +#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ +#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */ +#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */ +#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */ +#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ +#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ +#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ +#ifndef SPRN_SVR +#define SPRN_SVR 0x11E /* System Version Register */ +#endif +#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ +/* these bits were defined in inverted endian sense originally, ugh, confusing */ + +/* Values for PP (assumes Ks=0, Kp=1) */ +#define PP_RWXX 0 /* Supervisor read/write, User none */ +#define PP_RWRX 1 /* Supervisor read/write, User read */ +#define PP_RWRW 2 /* Supervisor read/write, User read/write */ +#define PP_RXRX 3 /* Supervisor read, User read */ + +/* Block size masks */ +#define BL_128K 0x000 +#define BL_256K 0x001 +#define BL_512K 0x003 +#define BL_1M 0x007 +#define BL_2M 0x00F +#define BL_4M 0x01F +#define BL_8M 0x03F +#define BL_16M 0x07F +#define BL_32M 0x0FF +#define BL_64M 0x1FF +#define BL_128M 0x3FF +#define BL_256M 0x7FF + +/* BAT Access Protection */ +#define BPP_XX 0x00 /* No access */ +#define BPP_RX 0x01 /* Read only */ +#define BPP_RW 0x02 /* Read/write */ + +/* Definitions for 40x embedded chips. */ +#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */ +#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */ +#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */ +#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ +#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ +#define _PAGE_USER 0x010 /* matches one of the zone permission bits */ +#define _PAGE_RW 0x040 /* software: Writes permitted */ +#define _PAGE_DIRTY 0x080 /* software: dirty page */ +#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */ +#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */ +#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */ + +#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */ +#define _PMD_BAD 0x802 +#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */ +#define _PMD_SIZE_4M 0x0c0 +#define _PMD_SIZE_16M 0x0e0 +#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4)) + +#define PVR_VER(pvr)(((pvr) >> 16) & 0xFFFF) /* Version field */ + +#define KERNELBASE 0x80000000 + +typedef unsigned char __u8; +typedef unsigned short __u16; +typedef unsigned int __u32; + +typedef struct _pci_reg_property { + struct { + int a_hi, a_mid, a_lo; + } addr; + int size_hi, size_lo; +} pci_reg_property; + +void btext_drawstring(const char *c); +void btext_drawhex(unsigned long v); + +void *ioremap(__u32 phys, __u32 size); +void iounmap(void *logical); + +__u32 GetPVR(); + +#endif/*_FREELDR_ARCH_COMPAT_H*/ diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 12f4bf96e65..a25b60121fa 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -20,19 +20,20 @@ #include "machine.h" #include "of.h" #include "mmu.h" - -#define TOTAL_HEAP_NEEDED (48 * 1024 * 1024) /* 48 megs */ +#include "compat.h" +#include "ppcboot.h" extern void BootMain( LPSTR CmdLine ); extern PCHAR GetFreeLoaderVersionString(); extern ULONG CacheSizeLimit; of_proxy ofproxy; -void *PageDirectoryStart, *PageDirectoryEnd, *mem_base = 0; +void *PageDirectoryStart, *PageDirectoryEnd; static int chosen_package, stdin_handle, part_handle = -1; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; volatile char *video_mem = 0; +boot_infos_t BootInfo; void le_swap( void *start_addr_v, void *end_addr_v, @@ -183,56 +184,160 @@ VOID PpcVideoSync() { printf( "Sync\n" ); } -VOID PpcVideoPrepareForReactOS() { - printf( "PrepareForReactOS\n"); +static int prom_next_node(int *nodep) +{ + int node; + + if ((node = *nodep) != 0 + && (*nodep = ofw_child(node)) != 0) + return 1; + if ((*nodep = ofw_peer(node)) != 0) + return 1; + for (;;) { + if ((node = ofw_parent(node)) == 0) + return 0; + if ((*nodep = ofw_peer(node)) != 0) + return 1; + } } + +VOID PpcVideoPrepareForReactOS() { + int i, j, display_handle, display_size = 0; + int node, ret, elts; + pci_reg_property display_regs[8]; + char type[256], path[256], name[256]; + + for( node = ofw_finddevice("/"); prom_next_node(&node); ) { + memset(type, 0, sizeof(type)); + memset(path, 0, sizeof(path)); + + ret = ofw_getprop(node, "name", name, sizeof(name)); + + if(ofw_getprop(node, "device_type", type, sizeof(type)) <= 0) { + printf("Could not get type for node %x\n", node); + continue; + } + + printf("Node %x ret %d name %s type %s\n", node, ret, name, type); + + if(strcmp(type, "display") == 0) break; + } + + if(!node) return; + + if(ofw_package_to_path(node, path, sizeof(path)) < 0) { + printf("could not get path for display package %x\n", node); + return; + } + + printf("Opening display package: %s\n", path); + + display_handle = ofw_open(path); + + printf("display handle %x\n", display_handle); + + BootInfo.dispDeviceRect[0] = BootInfo.dispDeviceRect[1] = 0; + + ofw_getprop(display_handle, "width", + (void *)&BootInfo.dispDeviceRect[2], sizeof(int)); + ofw_getprop(display_handle, "height", + (void *)&BootInfo.dispDeviceRect[3], sizeof(int)); + ofw_getprop(display_handle, "depth", + (void *)&BootInfo.dispDeviceDepth, sizeof(int)); + ofw_getprop(display_handle, "linebytes", + (void *)&BootInfo.dispDeviceRowBytes, sizeof(int)); + + if(ofw_getprop + (display_handle, + "address", + (void *)&BootInfo.dispDeviceBase, + sizeof(BootInfo.dispDeviceBase)) > 0) { + goto finish; + } + + if((elts = ofw_getprop(display_handle, + "assigned-addresses", + (void *)display_regs, + sizeof(display_regs))) <= 0) { + printf("Could not get assigned addresses\n"); + return; + } + + elts /= sizeof(display_regs[0]); + for( i = 0; i < elts; i++ ) { + display_size = display_regs[i].size_lo; + if( display_size >= (1 << 20) ) { + BootInfo.dispDeviceBase = (void *)display_regs[i].addr.a_lo; + + /* Map pages for display at some location */ + BootInfo.logicalDisplayBase = (void *)0xc0000000; + + for( i = 0; i < display_size; i += (1 << 12) ) { + InsertPageEntry((ULONG_PTR)((PCHAR)BootInfo.logicalDisplayBase)+i, + (ULONG_PTR)((PCHAR)BootInfo.dispDeviceBase)+i); + } + } + } + +finish: + /* Draw something ... */ + elts = 0; + for( i = 0; i < BootInfo.dispDeviceRect[3]; i++ ) { + for( j = 0; j < BootInfo.dispDeviceRect[2]; j++ ) { + ((PCHAR)BootInfo.logicalDisplayBase) + [(j * (BootInfo.dispDeviceDepth/8)) + + (i * (BootInfo.dispDeviceRowBytes))] = elts++; + } + } +} + /* * Get memory the proper openfirmware way */ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize ) { - int i, memhandle, mmuhandle, returned, total = 0, num_mem = 0; - int memdata[256]; + int i, memhandle, returned, total = 0, slots = 0; + int memdata[0x40]; printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize); - if( mem_base ) { - BiosMemoryMap[0].Type = MEMTYPE_USABLE; - BiosMemoryMap[0].BaseAddress = (ULONG)mem_base; - BiosMemoryMap[0].Length = TOTAL_HEAP_NEEDED; - printf("[cached] returning 1 element\n"); - return 1; - } - - ofw_getprop(chosen_package, "memory", - (char *)&memhandle, sizeof(memhandle)); - ofw_getprop(chosen_package, "mmu", - (char *)&mmuhandle, sizeof(mmuhandle)); + memhandle = ofw_finddevice("/memory"); returned = ofw_getprop(memhandle, "available", (char *)memdata, sizeof(memdata)); - /* We need to leave some for open firmware. Let's claim up to 16 megs - * for now */ + printf("Returned data: %d\n", returned); + if( returned == -1 ) { + printf("getprop /memory[@reg] failed\n"); + return 0; + } - for( i = 0; i < returned / sizeof(int) && !num_mem; i += 2 ) { - BiosMemoryMap[num_mem].Type = MEMTYPE_USABLE; - BiosMemoryMap[num_mem].BaseAddress = memdata[i]; - mem_base = (void *)memdata[i]; - BiosMemoryMap[num_mem].Length = memdata[i+1]; - if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED && - total < TOTAL_HEAP_NEEDED ) { - BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED; - ofw_claim(BiosMemoryMap[num_mem].BaseAddress, - BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */ - total += BiosMemoryMap[0].Length; - num_mem++; + for( i = 0; i < returned; i++ ) { + printf("%x ", memdata[i]); + } + printf("\n"); + + for( i = 0; i < returned / 2; i++ ) { + BiosMemoryMap[slots].Type = MEMTYPE_USABLE; + BiosMemoryMap[slots].BaseAddress = REV(memdata[i*2]); + BiosMemoryMap[slots].Length = REV(memdata[i*2+1]); + printf("MemoryMap[%d] = (%x:%x)\n", + i, + (int)BiosMemoryMap[slots].BaseAddress, + (int)BiosMemoryMap[slots].Length); + + if( BiosMemoryMap[slots].Length && + ofw_claim((int)BiosMemoryMap[slots].BaseAddress, + (int)BiosMemoryMap[slots].Length, + 0x1000) ) { + total += BiosMemoryMap[slots].Length; + slots++; } } printf( "Returning memory map (%dk total)\n", total / 1024 ); - return num_mem; + return slots; } /* Strategy: @@ -304,6 +409,7 @@ BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber, printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512)); return FALSE; } + rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) ); return rlen > 0; } @@ -374,36 +480,27 @@ BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) { return TRUE; } +extern int _bss; typedef unsigned int uint32_t; - void PpcInit( of_proxy the_ofproxy ) { int len, stdin_handle_chosen; ofproxy = the_ofproxy; - ofw_print_string("Freeldr PowerPC Init\n"); - + //SetPhys(0x900, (19 << 26) | (50 << 1)); + chosen_package = ofw_finddevice( "/chosen" ); - ofw_print_string("Freeldr: chosen_package is "); - ofw_print_number(chosen_package); - ofw_print_string("\n"); - ofw_getprop( chosen_package, "stdin", - (char *)&stdin_handle_chosen, sizeof(stdin_handle_chosen) ); + (char *)&stdin_handle_chosen, sizeof(stdin_handle_chosen) ); - ofw_print_string("Freeldr: stdin_handle is "); - ofw_print_number(stdin_handle_chosen); - ofw_print_string("\n"); - - stdin_handle = stdin_handle_chosen; - - /* stdin_handle = REV(stdin_handle); */ + stdin_handle = REV(stdin_handle_chosen); MachVtbl.ConsPutChar = PpcPutChar; MachVtbl.ConsKbHit = PpcConsKbHit; MachVtbl.ConsGetCh = PpcConsGetCh; - printf( "stdin_handle is %x\n", stdin_handle ); + printf( "chosen_package %x, stdin_handle is %x\n", + chosen_package, stdin_handle ); printf("virt2phys (0xe00000,D) -> %x\n", PpcVirt2phys(0xe00000,0)); printf("virt2phys (0xe01000,D) -> %x\n", PpcVirt2phys(0xe01000,0)); @@ -444,6 +541,8 @@ void PpcInit( of_proxy the_ofproxy ) { len = ofw_getprop(chosen_package, "bootargs", CmdLine, sizeof(CmdLine)); + printf("bootargs: len %d\n", len); + if( len < 0 ) len = 0; CmdLine[len] = 0; From 532db1da727941fe6e43ea2b2429990146719b2d Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 1 Oct 2006 22:57:16 +0000 Subject: [PATCH 50/81] A 'boot logo' of sorts to show we're about to switch to kernel mode. We'll pass the FB address into kernel land so we can continue writing on it. svn path=/branches/powerpc/; revision=24357 --- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 104 ++++++++++-------- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 40 ++++++- .../boot/freeldr/freeldr/arch/powerpc/mmu.h | 2 + reactos/include/reactos/ppcboot.h | 11 ++ 4 files changed, 111 insertions(+), 46 deletions(-) create mode 100644 reactos/include/reactos/ppcboot.h diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index a25b60121fa..39650347876 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -201,11 +201,31 @@ static int prom_next_node(int *nodep) } } +/* Appropriated from linux' btext.c + * author: + * Benjamin Herrenschmidt + */ VOID PpcVideoPrepareForReactOS() { - int i, j, display_handle, display_size = 0; + int i, j, k, /* display_handle, */ display_package, display_size = 0; int node, ret, elts; - pci_reg_property display_regs[8]; + int device_address; + //pci_reg_property display_regs[8]; char type[256], path[256], name[256]; + char logo[] = { + " " + " XXXXXX " + " X X " + " X X X X " + " X X " + " X XXXX X " + " X XX X " + " X X " + " XXXXXX " + " " + }; + int logo_x = 10, logo_y = 10; + int logo_scale_x = 8, logo_scale_y = 8; + for( node = ofw_finddevice("/"); prom_next_node(&node); ) { memset(type, 0, sizeof(type)); @@ -231,62 +251,56 @@ VOID PpcVideoPrepareForReactOS() { } printf("Opening display package: %s\n", path); - - display_handle = ofw_open(path); - - printf("display handle %x\n", display_handle); + display_package = ofw_finddevice(path); + printf("display package %x\n", display_package); BootInfo.dispDeviceRect[0] = BootInfo.dispDeviceRect[1] = 0; - ofw_getprop(display_handle, "width", + ofw_getprop(display_package, "width", (void *)&BootInfo.dispDeviceRect[2], sizeof(int)); - ofw_getprop(display_handle, "height", + ofw_getprop(display_package, "height", (void *)&BootInfo.dispDeviceRect[3], sizeof(int)); - ofw_getprop(display_handle, "depth", + ofw_getprop(display_package, "depth", (void *)&BootInfo.dispDeviceDepth, sizeof(int)); - ofw_getprop(display_handle, "linebytes", + ofw_getprop(display_package, "linebytes", (void *)&BootInfo.dispDeviceRowBytes, sizeof(int)); - if(ofw_getprop - (display_handle, - "address", - (void *)&BootInfo.dispDeviceBase, - sizeof(BootInfo.dispDeviceBase)) > 0) { - goto finish; - } + BootInfo.dispDeviceRect[2] = REV(BootInfo.dispDeviceRect[2]); + BootInfo.dispDeviceRect[3] = REV(BootInfo.dispDeviceRect[3]); + BootInfo.dispDeviceDepth = REV(BootInfo.dispDeviceDepth); + BootInfo.dispDeviceRowBytes = REV(BootInfo.dispDeviceRowBytes); - if((elts = ofw_getprop(display_handle, - "assigned-addresses", - (void *)display_regs, - sizeof(display_regs))) <= 0) { - printf("Could not get assigned addresses\n"); + if(ofw_getprop + (display_package, + "address", + (void *)&device_address, + sizeof(device_address)) < 1) { + printf("Could not get device base\n"); return; } - elts /= sizeof(display_regs[0]); - for( i = 0; i < elts; i++ ) { - display_size = display_regs[i].size_lo; - if( display_size >= (1 << 20) ) { - BootInfo.dispDeviceBase = (void *)display_regs[i].addr.a_lo; - - /* Map pages for display at some location */ - BootInfo.logicalDisplayBase = (void *)0xc0000000; - - for( i = 0; i < display_size; i += (1 << 12) ) { - InsertPageEntry((ULONG_PTR)((PCHAR)BootInfo.logicalDisplayBase)+i, - (ULONG_PTR)((PCHAR)BootInfo.dispDeviceBase)+i); - } - } - } + BootInfo.dispDeviceBase = (PVOID)(REV(device_address)); -finish: - /* Draw something ... */ - elts = 0; - for( i = 0; i < BootInfo.dispDeviceRect[3]; i++ ) { - for( j = 0; j < BootInfo.dispDeviceRect[2]; j++ ) { - ((PCHAR)BootInfo.logicalDisplayBase) - [(j * (BootInfo.dispDeviceDepth/8)) + - (i * (BootInfo.dispDeviceRowBytes))] = elts++; + display_size = BootInfo.dispDeviceRowBytes * BootInfo.dispDeviceRect[3]; + + printf("Display size is %x bytes (%x per row times %x rows)\n", + display_size, + BootInfo.dispDeviceRowBytes, + BootInfo.dispDeviceRect[3]); + + printf("display is at %x\n", BootInfo.dispDeviceBase); + + for( i = 0; i < logo_y * logo_scale_y; i++ ) { + for( j = 0; j < logo_x * logo_scale_x; j++ ) { + elts = (j/logo_scale_x) + ((i/logo_scale_y) * logo_x); + + for( k = 0; k < BootInfo.dispDeviceDepth/8; k++ ) { + SetPhysByte(((ULONG_PTR)BootInfo.dispDeviceBase)+ + k + + ((j * (BootInfo.dispDeviceDepth/8)) + + (i * (BootInfo.dispDeviceRowBytes))), + logo[elts] == ' ' ? 0 : 255); + } } } } diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c index 39f588fba35..84a310e8470 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -7,6 +7,12 @@ inline int GetMSR() { return res; } +inline int GetDEC() { + register int res asm ("r3"); + __asm__("mfdec 3"); + return res; +} + __asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" @@ -15,8 +21,12 @@ __asm__("\t.globl GetPhys\n" "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ "mtmsr 6\n\t" + "isync\n\t" + "sync\n\t" "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ "mtmsr 5\n\t" + "isync\n\t" + "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" @@ -31,8 +41,35 @@ __asm__("\t.globl SetPhys\n" "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ "mtmsr 6\n\t" - "stw 4,0(3)\n\t" /* Get actual value at phys addr r3 */ + "sync\n\t" + "eieio\n\t" + "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl SetPhysByte\n" + "SetPhysByte:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,7\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "sync\n\t" + "eieio\n\t" + "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" + "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" "mr 3,4\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" @@ -183,6 +220,7 @@ inline void SetBat( int bat, int inst, int batHi, int batLo ) { break; } } + __asm__("isync\n\tsync"); } inline int GetSDR1() { diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h index 920868782fd..2baed2a5f43 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h @@ -1,9 +1,11 @@ #ifndef FREELDR_MMU_H #define FREELDR_MMU_H +int GetDEC(); int GetMSR(); int GetPhys( int addr ); void SetPhys( int addr, int val ); +void SetPhysByte( int addr, int val ); int GetSR(int n); void GetBat( int bat, int inst, int *batHi, int *batLo ); void SetBat( int bat, int inst, int batHi, int batLo ); diff --git a/reactos/include/reactos/ppcboot.h b/reactos/include/reactos/ppcboot.h new file mode 100644 index 00000000000..96e7baa2af2 --- /dev/null +++ b/reactos/include/reactos/ppcboot.h @@ -0,0 +1,11 @@ +#ifndef REACTOS_PPCBOOT_H +#define REACTOS_PPCBOOT_H + +typedef struct _boot_infos_t { + int dispDeviceRect[4]; + int dispDeviceRowBytes; + int dispDeviceDepth; + void *dispDeviceBase; +} boot_infos_t; + +#endif/*REACTOS_PPCBOOT_H*/ From 47e3cefe5babd1624543beb5a59f1d2fb63ddf21 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 4 Oct 2006 08:10:01 +0000 Subject: [PATCH 51/81] - Create a slab that contains the last vestage of our life as the boot program. - Include a font containing some characters we can use with boot video. - Copy in a description of the boot framebuffer. - Add a small ad-hoc number writing function. - Display our progress building the initial page table. - We don't necessarily have space in the boot-time page table so just kill off boot-time paging. - Pass ntoskrnl the address of the boot slab. It contains the boot font, a description of the boot video device and all active page table entries. - Next, well be able to use this in early ntoskrnl space to display our progress etc. Since we're using phyiscal addresses to write to the boot framebuffer, the page table needn't include it. This simplifies things compared to linux, but it's expensive. svn path=/branches/powerpc/; revision=24390 --- .../boot/freeldr/freeldr/arch/powerpc/boot.s | 5 + .../freeldr/freeldr/arch/powerpc/compat.h | 101 ++++++++++++++++++ .../boot/freeldr/freeldr/arch/powerpc/mach.c | 30 ++++-- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 96 +++++++++++++++-- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 4 +- .../boot/freeldr/freeldr/arch/powerpc/mmu.h | 2 +- reactos/include/reactos/ppcboot.h | 2 + 7 files changed, 218 insertions(+), 22 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s index 30c1f1c3e18..c522936d0a7 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s @@ -1,3 +1,8 @@ .extern PpcInit _start: b PpcInit + + .globl _bss + .section ".bss" +_bss: + .long 0 diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h index 66797a6929d..031710e7096 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/compat.h @@ -103,6 +103,107 @@ void btext_drawhex(unsigned long v); void *ioremap(__u32 phys, __u32 size); void iounmap(void *logical); +font_char BootDigits[16] = { + " XXXXX " + "X X " + "X x X " + "X X X " + "X X " + " XXXXX " + " ", + " XX " + " XXX " + " XX " + " XX " + " XX " + " XX " + " ", + " XXXX " + " X X " + " XX " + " XX " + " XX " + " XXXXXX " + " ", + " XXXX " + " X X " + " XX " + " X " + " X X " + " XXXX " + " ", + " X X " + " X X " + " XXXXXX " + " X " + " X " + " X " + " ", + " XXXXXX " + " X " + " XXXXX " + " X " + " X " + " XXXXX " + " ", + " XXXXX " + " X " + " XXXXX " + " X X " + " X X " + " XXXX " + " ", + " XXXXXX " + " XX " + " XX " + " XXXXX " + " XX " + " XX " + " ", + " XXXX " + " X X " + " XXXX " + " X X " + " X X " + " XXXX " + " ", + " XXXX " + " X X " + " XXXXXX " + " X X " + " X X " + " X X " + " ", + " XXXXX " + " X X " + " XXXXX " + " X X " + " X X " + " XXXXX " + " ", + " XXXX " + " X X " + " X " + " X " + " X X " + " XXXX " + " ", + " XXXXXX " + " X " + " XXXX " + " X " + " X " + " XXXXXX " + " ", + " XXXXXX " + " X " + " XXXX " + " X " + " X " + " X " + " " +}; + __u32 GetPVR(); #endif/*_FREELDR_ARCH_COMPAT_H*/ diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 39650347876..6e5ac5c9d7f 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -28,7 +28,7 @@ extern PCHAR GetFreeLoaderVersionString(); extern ULONG CacheSizeLimit; of_proxy ofproxy; void *PageDirectoryStart, *PageDirectoryEnd; -static int chosen_package, stdin_handle, part_handle = -1; +static int chosen_package, stdin_handle, part_handle = -1, kernel_mem = 0; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; @@ -340,10 +340,20 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, (int)BiosMemoryMap[slots].BaseAddress, (int)BiosMemoryMap[slots].Length); - if( BiosMemoryMap[slots].Length && + /* Hack for pearpc */ + if( kernel_mem ) { + BiosMemoryMap[slots].Length = kernel_mem * 1024; ofw_claim((int)BiosMemoryMap[slots].BaseAddress, (int)BiosMemoryMap[slots].Length, - 0x1000) ) { + 0x1000); + total += BiosMemoryMap[slots].Length; + slots++; + break; + /* Normal way */ + } else if( BiosMemoryMap[slots].Length && + ofw_claim((int)BiosMemoryMap[slots].BaseAddress, + (int)BiosMemoryMap[slots].Length, + 0x1000) ) { total += BiosMemoryMap[slots].Length; slots++; } @@ -555,11 +565,11 @@ void PpcInit( of_proxy the_ofproxy ) { len = ofw_getprop(chosen_package, "bootargs", CmdLine, sizeof(CmdLine)); - printf("bootargs: len %d\n", len); - if( len < 0 ) len = 0; CmdLine[len] = 0; + printf("bootargs: len %d [%s]\n", len, CmdLine); + BootMain( CmdLine ); } @@ -572,15 +582,19 @@ void MachInit(const char *CmdLine) { printf( "Determining boot device: [%s]\n", CmdLine ); - printf( "Boot Args: %s\n", CmdLine ); sep = NULL; for( i = 0; i < strlen(CmdLine); i++ ) { if( strncmp(CmdLine + i, "boot=", 5) == 0) { strcpy(BootPart, CmdLine + i + 5); - sep = strchr(BootPart, ' '); + sep = strchr(BootPart, ','); if( sep ) *sep = 0; - break; + while(CmdLine[i] && CmdLine[i]!=',') i++; + } + if( strncmp(CmdLine + i, "mem=", 4) == 0) { + kernel_mem = atoi(CmdLine+i+4); + printf("Allocate %dk kernel memory\n", kernel_mem); + while(CmdLine[i] && CmdLine[i]!=',') i++; } } diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 6ad18c5e5d7..a423027d227 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -20,12 +20,15 @@ #include #include +#include "ppcboot.h" #include "mmu.h" +#include "compat.h" #define NDEBUG #include static PVOID KernelMemory = 0; +extern boot_infos_t BootInfo; /* Bits to shift to convert a Virtual Address into an Offset in the Page Table */ #define PFN_SHIFT 12 @@ -107,26 +110,97 @@ ULONG_PTR KernelEntry; typedef void (*KernelEntryFn)( void * ); +VOID +DrawDigit(boot_infos_t *BootInfo, ULONG Digit, int x, int y) +{ + int i,j,k; + + for( i = 0; i < 7; i++ ) { + for( j = 0; j < 8; j++ ) { + for( k = 0; k < BootInfo->dispDeviceDepth/8; k++ ) { + SetPhysByte(((ULONG_PTR)BootInfo->dispDeviceBase)+ + k + + (((j+x) * (BootInfo->dispDeviceDepth/8)) + + ((i+y) * (BootInfo->dispDeviceRowBytes))), + BootInfo->dispFont[Digit][i*8+j] == ' ' ? 0 : 255); + } + } + } +} + +VOID +DrawNumber(boot_infos_t *BootInfo, ULONG Number, int x, int y) +{ + int i; + + for( i = 0; i < 8; i++, Number<<=4 ) { + DrawDigit(BootInfo,(Number>>28)&0xf,x+(i*8),y); + } +} + VOID NTAPI FrLdrStartup(ULONG Magic) { KernelEntryFn KernelEntryAddress = (KernelEntryFn)(KernelEntry + KernelBase); - ULONG_PTR PhysAddr, i; - - for( i = 0; i < KernelMemorySize; i+=1<> PFN_SHIFT; + UINT NeededMemory = + (2 * sizeof(ULONG_PTR) * (NeededPTE + NeededPTE / 512)) + + sizeof(BootInfo) + sizeof(BootDigits); + UINT NeededPages = ROUND_UP(NeededMemory,(1<dispFont = (font_char *)&LocalBootInfo[1]; + + TranslationMap[0] = (ULONG_PTR)FrLdrStartup; + for( i = 1; i < NeededPages; i++ ) { - PhysAddr = PpcVirt2phys((ULONG)KernelMemory + i,0); - - if( !InsertPageEntry(KernelBase + i,PhysAddr) ) - { - printf("Foo: couldn't find a page slot for %x\n", i); - while(1); - } + TranslationMap[i*2] = NeededMemory+(i<>PFN_SHIFT; j++ ) + { + TranslationMap[(i+j)*2] = ((UINT)(KernelMemory+(i<>10)); + } + + /* Tell them we're booting */ + DrawNumber(LocalBootInfo,0x1cabba9e,10,120); + DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,120); + + KernelEntryAddress( (void*)LocalBootInfo ); while(1); } diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c index 84a310e8470..39f7b72568d 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -293,7 +293,7 @@ int PpcVirt2phys( int virt, int inst ) { } /* Add a new page table entry for the indicated mapping */ -BOOLEAN InsertPageEntry( int virt, int phys ) { +BOOLEAN InsertPageEntry( int virt, int phys, int slot ) { int i, ptehi, ptelo; int sdr1 = GetSDR1(); int sr = GetSR( (virt >> 28) & 0xf ); @@ -307,7 +307,7 @@ BOOLEAN InsertPageEntry( int virt, int phys ) { for( i = 0; i < 8; i++ ) { ptehi = GetPhys( ptegaddr + (i * 8) ); - if( ptehi & 0x80000000 ) continue; + if( (slot != i) && (ptehi & 0x80000000) ) continue; ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f); ptelo = phys & ~0xfff; diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h index 2baed2a5f43..99d8bb2e3ac 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h @@ -14,6 +14,6 @@ int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); /* translate address */ int PpcVirt2phys( int virt, int inst ); -BOOLEAN InsertPageEntry( int virt, int phys ); +BOOLEAN InsertPageEntry( int virt, int phys, int slot ); #endif/*FREELDR_MMU_H*/ diff --git a/reactos/include/reactos/ppcboot.h b/reactos/include/reactos/ppcboot.h index 96e7baa2af2..460af14eba9 100644 --- a/reactos/include/reactos/ppcboot.h +++ b/reactos/include/reactos/ppcboot.h @@ -1,11 +1,13 @@ #ifndef REACTOS_PPCBOOT_H #define REACTOS_PPCBOOT_H +typedef char font_char[57]; typedef struct _boot_infos_t { int dispDeviceRect[4]; int dispDeviceRowBytes; int dispDeviceDepth; void *dispDeviceBase; + font_char *dispFont; } boot_infos_t; #endif/*REACTOS_PPCBOOT_H*/ From 4b55d29dd3e0932f8d6f170942cce0262bafcef1 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 8 Oct 2006 10:11:51 +0000 Subject: [PATCH 52/81] Straggler. Early boot video font. svn path=/branches/powerpc/; revision=24445 --- reactos/include/reactos/font.h | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 reactos/include/reactos/font.h diff --git a/reactos/include/reactos/font.h b/reactos/include/reactos/font.h new file mode 100644 index 00000000000..6ad0903260c --- /dev/null +++ b/reactos/include/reactos/font.h @@ -0,0 +1,105 @@ +#ifndef _ARCH_POWERPC_FONT_H +#define _ARCH_POWERPC_FONT_H + +font_char BootDigits[16] = { + " XXXXX " + "X X " + "X x X " + "X X X " + "X X " + " XXXXX " + " ", + " XX " + " XXX " + " XX " + " XX " + " XX " + " XX " + " ", + " XXXX " + " X X " + " XX " + " XX " + " XX " + " XXXXXX " + " ", + " XXXX " + " X X " + " XX " + " X " + " X X " + " XXXX " + " ", + " X X " + " X X " + " XXXXXX " + " X " + " X " + " X " + " ", + " XXXXXX " + " X " + " XXXXX " + " X " + " X " + " XXXXX " + " ", + " XXXXX " + " X " + " XXXXX " + " X X " + " X X " + " XXXX " + " ", + " XXXXXX " + " XX " + " XX " + " XXXXX " + " XX " + " XX " + " ", + " XXXX " + " X X " + " XXXX " + " X X " + " X X " + " XXXX " + " ", + " XXXX " + " X X " + " XXXXXX " + " X X " + " X X " + " X X " + " ", + " XXXXX " + " X X " + " XXXXX " + " X X " + " X X " + " XXXXX " + " ", + " XXXX " + " X X " + " X " + " X " + " X X " + " XXXX " + " ", + " XXXXXX " + " X " + " XXXX " + " X " + " X " + " XXXXXX " + " ", + " XXXXXX " + " X " + " XXXX " + " X " + " X " + " X " + " " +}; + +#endif/*_ARCH_POWERPC_FONT_H*/ From 9c051d65f9f1cf6b40841e16738a3dcc132913d8 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 8 Oct 2006 10:14:01 +0000 Subject: [PATCH 53/81] Fix silly error: missing digit. svn path=/branches/powerpc/; revision=24446 --- reactos/include/reactos/font.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reactos/include/reactos/font.h b/reactos/include/reactos/font.h index 6ad0903260c..e3de3939c07 100644 --- a/reactos/include/reactos/font.h +++ b/reactos/include/reactos/font.h @@ -86,6 +86,13 @@ font_char BootDigits[16] = { " X X " " XXXX " " ", + " XXXXX " + " X X " + " X X " + " X X " + " X X " + " XXXXX " + " ", " XXXXXX " " X " " XXXX " From d908957c655938933a22d4822b7469798664dbc6 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 8 Oct 2006 10:18:28 +0000 Subject: [PATCH 54/81] Really fix font.h svn path=/branches/powerpc/; revision=24447 --- reactos/include/reactos/font.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reactos/include/reactos/font.h b/reactos/include/reactos/font.h index e3de3939c07..1dd1eb80d17 100644 --- a/reactos/include/reactos/font.h +++ b/reactos/include/reactos/font.h @@ -67,6 +67,13 @@ font_char BootDigits[16] = { " ", " XXXX " " X X " + " X X " + " XXXXX " + " X " + " XXXX " + " ", + " XXXX " + " X X " " XXXXXX " " X X " " X X " From d56f62106c253723c59d2181a54a08f20122bc46 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 8 Oct 2006 10:27:42 +0000 Subject: [PATCH 55/81] Move mmu.h to make it more generally accessible since we need translation functions in windows subdir. svn path=/branches/powerpc/; revision=24448 --- reactos/boot/freeldr/freeldr/{arch/powerpc => include}/mmu.h | 2 ++ 1 file changed, 2 insertions(+) rename reactos/boot/freeldr/freeldr/{arch/powerpc => include}/mmu.h (95%) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h b/reactos/boot/freeldr/freeldr/include/mmu.h similarity index 95% rename from reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h rename to reactos/boot/freeldr/freeldr/include/mmu.h index 99d8bb2e3ac..6818613fe25 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.h +++ b/reactos/boot/freeldr/freeldr/include/mmu.h @@ -1,6 +1,8 @@ #ifndef FREELDR_MMU_H #define FREELDR_MMU_H +extern int mmu_handle; + int GetDEC(); int GetMSR(); int GetPhys( int addr ); From 884712c2ba19bf095f2c9d0219555105b8adab22 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 8 Oct 2006 10:31:52 +0000 Subject: [PATCH 56/81] Also added for merge. svn path=/branches/powerpc/; revision=24449 --- reactos/lib/rtl/mem.c | 173 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 reactos/lib/rtl/mem.c diff --git a/reactos/lib/rtl/mem.c b/reactos/lib/rtl/mem.c new file mode 100644 index 00000000000..e5152b5dafd --- /dev/null +++ b/reactos/lib/rtl/mem.c @@ -0,0 +1,173 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/rtl/mem.c + * PURPOSE: Memory functions + * PROGRAMMER: David Welch (welch@mcmail.com) + */ + +/* INCLUDES *****************************************************************/ + +#include + +#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ + +/****************************************************************************** + * RtlCompareMemory [NTDLL.@] + * + * Compare one block of memory with another + * + * PARAMS + * Source1 [I] Source block + * Source2 [I] Block to compare to Source1 + * Length [I] Number of bytes to fill + * + * RETURNS + * The length of the first byte at which Source1 and Source2 differ, or Length + * if they are the same. + * + * @implemented + */ +SIZE_T NTAPI +RtlCompareMemory(IN const VOID *Source1, + IN const VOID *Source2, + IN SIZE_T Length) +{ + SIZE_T i; + for(i=0; (i 0) + { + *Dest = Fill; + Dest++; + Count--; + } +} + + +#undef RtlMoveMemory +/* + * @implemented + */ +VOID +NTAPI +RtlMoveMemory ( + PVOID Destination, + CONST VOID * Source, + ULONG Length +) +{ + memmove ( + Destination, + Source, + Length + ); +} + +/* +* @implemented +*/ +VOID +FASTCALL +RtlPrefetchMemoryNonTemporal( + IN PVOID Source, + IN SIZE_T Length + ) +{ + /* By nature of prefetch, this is non-portable. */ + (void)Source; + (void)Length; +} + + +#undef RtlZeroMemory +/* + * @implemented + */ +VOID +NTAPI +RtlZeroMemory ( + PVOID Destination, + ULONG Length +) +{ + RtlFillMemory ( + Destination, + Length, + 0 + ); +} + +/* EOF */ From 6dae10c682a97a9409f131f9639f1f45bfbb14b8 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 8 Oct 2006 10:50:50 +0000 Subject: [PATCH 57/81] Simplify this since we now have intrin.h svn path=/branches/powerpc/; revision=24450 --- reactos/include/ndk/psfuncs.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/reactos/include/ndk/psfuncs.h b/reactos/include/ndk/psfuncs.h index a057c8dd48a..74fa9788418 100644 --- a/reactos/include/ndk/psfuncs.h +++ b/reactos/include/ndk/psfuncs.h @@ -180,19 +180,7 @@ FORCEINLINE PTEB NtCurrentTeb(VOID) { -#ifndef __GNUC__ return (PTEB)(ULONG_PTR)__readfsdword(0x18); -#else - struct _TEB *ret; - - __asm__ __volatile__ ( - "movl %%fs:0x18, %0\n" - : "=r" (ret) - : /* no inputs */ - ); - - return ret; -#endif } #endif From 8268d67594b590bfa2292130ca6a5990839edf6d Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 22 Oct 2006 07:24:21 +0000 Subject: [PATCH 58/81] Build an entirely new page table. svn path=/branches/powerpc/; revision=24597 --- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 120 +++++++++++++----- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 16 ++- reactos/boot/freeldr/freeldr/include/mmu.h | 3 +- 3 files changed, 100 insertions(+), 39 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 317e0dd4680..73ff20e9c8c 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -139,44 +139,92 @@ DrawNumber(boot_infos_t *BootInfo, ULONG Number, int x, int y) } } +typedef struct _DIRECTORY_ENTRY { + ULONG Virt, Phys; +} DIRECTORY_ENTRY; + +typedef struct _DIRECTORY_HEADER { + UINT NumberOfPages; + UINT DirectoryPage, UsedSpace; + DIRECTORY_ENTRY *Directory[1]; +} DIRECTORY_HEADER; + +DIRECTORY_ENTRY * +GetPageMapping( DIRECTORY_HEADER *TranslationMap, ULONG Number ) { + if( Number >= (ULONG)TranslationMap->NumberOfPages ) return 0; + else { + int EntriesPerPage = (1<Directory + [Number/EntriesPerPage][Number%EntriesPerPage]; + } +} + +VOID +AddPageMapping( DIRECTORY_HEADER *TranslationMap, + ULONG Virt, + ULONG OldVirt) { + ULONG Phys; + DIRECTORY_ENTRY *Entry; + if( !TranslationMap->DirectoryPage || + TranslationMap->UsedSpace >= ((1<Directory + [TranslationMap->DirectoryPage] = MmAllocateMemory(1<UsedSpace = 0; + TranslationMap->DirectoryPage++; + AddPageMapping + (TranslationMap, + (ULONG)TranslationMap->Directory + [TranslationMap->DirectoryPage-1],0); + } + Phys = PpcVirt2phys(Virt,0); + TranslationMap->NumberOfPages++; + Entry = GetPageMapping(TranslationMap, TranslationMap->NumberOfPages-1); + Entry->Virt = OldVirt ? OldVirt : Virt; Entry->Phys = Phys; + TranslationMap->UsedSpace++; +} + VOID NTAPI FrLdrStartup(ULONG Magic) { KernelEntryFn KernelEntryAddress = (KernelEntryFn)(KernelEntry + KernelBase); - register ULONG_PTR i asm("r4"), j asm("r5"); - UINT NeededPTE = ((UINT)KernelMemory) >> PFN_SHIFT; - UINT NeededMemory = - (2 * sizeof(ULONG_PTR) * (NeededPTE + NeededPTE / 512)) + - sizeof(BootInfo) + sizeof(BootDigits); - UINT NeededPages = ROUND_UP(NeededMemory,(1<dispFont = (font_char *)&LocalBootInfo[1]; - - TranslationMap[0] = (ULONG_PTR)FrLdrStartup; - for( i = 1; i < NeededPages; i++ ) - { - TranslationMap[i*2] = NeededMemory+(i<>PFN_SHIFT; j++ ) - { - TranslationMap[(i+j)*2] = ((UINT)(KernelMemory+(i<NumberOfPages); /* * Stuff page table entries for the page containing this code, @@ -185,22 +233,20 @@ FrLdrStartup(ULONG Magic) * * When done, we'll be able to flop over to kernel land! */ - for( i = 0; i < j; i++ ) - { - DrawNumber(LocalBootInfo,i,10,90); - DrawNumber(LocalBootInfo,TranslationMap[i*2],10,100); - DrawNumber(LocalBootInfo,TranslationMap[i*2+1],10,110); - - InsertPageEntry - (TranslationMap[i*2], - TranslationMap[(i*2)+1], - (i>>10)); + for( i = 0, Entry = GetPageMapping( TranslationMap, i ); + Entry; + i++, Entry = GetPageMapping( TranslationMap, i ) ) { + DrawNumber(LocalBootInfo,Entry->Virt,10,90); + DrawNumber(LocalBootInfo,Entry->Phys,100,90); + InsertPageEntry( Entry->Virt, Entry->Phys, + (i & 0x3ff) >> 3, NewMapSdr ); } /* Tell them we're booting */ - DrawNumber(LocalBootInfo,0x1cabba9e,10,120); - DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,120); + DrawNumber(LocalBootInfo,0x1cabba9e,10,100); + DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,100); + SetSDR1( NewMapSdr ); KernelEntryAddress( (void*)LocalBootInfo ); while(1); } @@ -481,6 +527,10 @@ FrLdrMapKernel(FILE *KernelImage) LongPtr = (PULONG)ShortPtr; *LongPtr += Delta; break; + + default: + printf("Unknown relocation %d\n", *TypeOffset >> 12); + break; } TypeOffset++; diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c index 39f7b72568d..363e4180531 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -229,6 +229,10 @@ inline int GetSDR1() { return res; } +inline void SetSDR1( int sdr ) { + __asm__("mtsdr1 3"); +} + inline int BatHit( int bath, int batl, int virt ) { int mask = 0xfffe0000 & ~((batl & 0x3f) << 17); return (batl & 0x40) && ((virt & mask) == (bath & mask)); @@ -293,9 +297,9 @@ int PpcVirt2phys( int virt, int inst ) { } /* Add a new page table entry for the indicated mapping */ -BOOLEAN InsertPageEntry( int virt, int phys, int slot ) { +BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) { int i, ptehi, ptelo; - int sdr1 = GetSDR1(); + int sdr1 = _sdr1 ? _sdr1 : GetSDR1(); int sr = GetSR( (virt >> 28) & 0xf ); int vsid = sr & 0xfffffff; int physbase = sdr1 & ~0xffff; @@ -303,7 +307,7 @@ BOOLEAN InsertPageEntry( int virt, int phys, int slot ) { int valo = (vsid << 28) | (virt & 0xfffffff); int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); int ptegaddr = ((hashmask & hash) * 64) + physbase; - + for( i = 0; i < 8; i++ ) { ptehi = GetPhys( ptegaddr + (i * 8) ); @@ -315,6 +319,12 @@ BOOLEAN InsertPageEntry( int virt, int phys, int slot ) { SetPhys( ptegaddr + (i * 8), ptehi ); SetPhys( ptegaddr + (i * 8) + 4, ptelo ); + __asm__("ptesync"); + __asm__("tlbie %0,0" : : "r" (virt)); + __asm__("eieio"); + __asm__("tlbsync"); + __asm__("ptesync"); + return TRUE; } diff --git a/reactos/boot/freeldr/freeldr/include/mmu.h b/reactos/boot/freeldr/freeldr/include/mmu.h index 6818613fe25..30666d21f38 100644 --- a/reactos/boot/freeldr/freeldr/include/mmu.h +++ b/reactos/boot/freeldr/freeldr/include/mmu.h @@ -12,10 +12,11 @@ int GetSR(int n); void GetBat( int bat, int inst, int *batHi, int *batLo ); void SetBat( int bat, int inst, int batHi, int batLo ); int GetSDR1(); +void SetSDR1( int newsdr ); int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); /* translate address */ int PpcVirt2phys( int virt, int inst ); -BOOLEAN InsertPageEntry( int virt, int phys, int slot ); +BOOLEAN InsertPageEntry( int virt, int phys, int slot, int sdr ); #endif/*FREELDR_MMU_H*/ From aeea011c59a226ff131e83517a2338d232edf2a1 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 1 Jan 2007 11:32:44 +0000 Subject: [PATCH 59/81] - most of the churn here is from code and headers imported from trunk. - there are several improvements to freeldr for which ion and fireball are responsible. - also here is filip's cmlib. - my changes to freeldr mostly centered around managing the kernel slab and transitioning to the kernel memory map. the new map is built in a new area and installed once we have every page set up. this is a bit safer than the old method. - the video planes are handed off to ntoskrnl, and some trace macros using the frame buffer are available. - some hacks are removed. - current status: LdrInitModuleManagement tries to get the header from hal.dll but fails for some reason. i need to look into it. - this is a checkpoint, since there's been some interest in seeing how things are progressing. - you can put any pe-coff powerpc exe (based at 0x80000000) in place of ntoskrnl to test various aspects of the boot handoff. this will be useful for testing our trap handlers and such. - the toolchain didn't produce correct executables in all cases before, and didn't differentiate rva32 and rel32, causing some things to be linked wrong. so far, the current toolchain (20061231) links correctly, using R_PPC_UADDR32 as a surrogate for rva32, since it's never produced by gcc. - some earlyboot video tracing is in ntoskrnl so i can peek around a bit. svn path=/branches/powerpc/; revision=25259 --- reactos/ReactOS-ppc.rbuild | 2 + reactos/boot/freeldr/bootsect/ofwboot.s | 3 +- .../boot/freeldr/freeldr/arch/powerpc/mach.c | 15 +- .../boot/freeldr/freeldr/arch/powerpc/mboot.c | 56 +- .../boot/freeldr/freeldr/arch/powerpc/mmu.c | 22 +- .../boot/freeldr/freeldr/freeldr_base.rbuild | 1 + reactos/boot/freeldr/freeldr/mm/mm.c | 4 +- .../boot/freeldr/freeldr/reactos/reactos.c | 71 +- .../boot/freeldr/freeldr/windows/peloader.c | 9 + reactos/boot/freeldr/freeldr/windows/winldr.c | 228 +- .../boot/freeldr/freeldr/windows/wlmemory.c | 110 +- .../boot/freeldr/freeldr/windows/wlregistry.c | 337 +++ reactos/include/ddk/winddk.h | 2241 ++++++++--------- reactos/include/ndk/powerpc/ketypes.h | 2 + reactos/include/psdk/winnt.h | 2 +- reactos/include/reactos/arc/arc.h | 27 + reactos/include/reactos/font.h | 142 +- reactos/include/reactos/ppcboot.h | 1 + reactos/include/reactos/ppcdebug.h | 20 + reactos/include/reactos/rosldr.h | 1 + reactos/lib/cmlib/cmdata.h | 308 +-- reactos/lib/cmlib/cminit.c | 164 +- reactos/lib/cmlib/cmlib.h | 474 ++-- reactos/lib/cmlib/cmlib.mak | 144 +- reactos/lib/cmlib/hivebin.c | 196 +- reactos/lib/cmlib/hivecell.c | 858 +++---- reactos/lib/cmlib/hivedata.h | 1 - reactos/lib/cmlib/hiveinit.c | 781 +++--- reactos/lib/cmlib/hivewrt.c | 554 ++-- reactos/ntoskrnl/ex/rundown.c | 4 + reactos/ntoskrnl/include/internal/ke_x.h | 3 - reactos/ntoskrnl/include/internal/ntoskrnl.h | 10 + .../ntoskrnl/include/internal/powerpc/ke.h | 6 +- reactos/ntoskrnl/ke/freeldr.c | 68 +- reactos/ntoskrnl/ke/powerpc/main_asm.S | 31 +- reactos/ntoskrnl/ke/thrdobj.c | 11 - reactos/ntoskrnl/ldr/loader.c | 19 + reactos/tools/ppc.lost+found/link-freeldr | 66 +- 38 files changed, 3978 insertions(+), 3014 deletions(-) create mode 100644 reactos/include/reactos/ppcdebug.h diff --git a/reactos/ReactOS-ppc.rbuild b/reactos/ReactOS-ppc.rbuild index 66537306733..d6f73a4483b 100644 --- a/reactos/ReactOS-ppc.rbuild +++ b/reactos/ReactOS-ppc.rbuild @@ -25,8 +25,10 @@ + 1 -fshort-wchar -fsigned-char + -map diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s index 4158d2de2a8..dde2becaaef 100644 --- a/reactos/boot/freeldr/bootsect/ofwboot.s +++ b/reactos/boot/freeldr/bootsect/ofwboot.s @@ -86,7 +86,6 @@ zero_registers: blr - .org 0x1000 freeldr_banner: .ascii "ReactOS OpenFirmware Boot Program\r\n\0" @@ -99,7 +98,7 @@ ofw_memory_size: .long 0 .long 0 - .org 0x2000 + .org 0x1000 stack: .space 0x4000 diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c index 5af5522a944..8ec781769ec 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c @@ -29,7 +29,7 @@ extern ULONG CacheSizeLimit; of_proxy ofproxy; void *PageDirectoryStart, *PageDirectoryEnd; static int chosen_package, stdin_handle, part_handle = -1, kernel_mem = 0; -int mmu_handle = 0; +int mmu_handle = 0, FixedMemory = 0; BOOLEAN AcpiPresent = FALSE; char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 }; jmp_buf jmp; @@ -344,9 +344,12 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, /* Hack for pearpc */ if( kernel_mem ) { BiosMemoryMap[slots].Length = kernel_mem * 1024; - ofw_claim((int)BiosMemoryMap[slots].BaseAddress, - (int)BiosMemoryMap[slots].Length, - 0x1000); + if( !FixedMemory ) { + ofw_claim((int)BiosMemoryMap[slots].BaseAddress, + (int)BiosMemoryMap[slots].Length, + 0x1000); + FixedMemory = BiosMemoryMap[slots].BaseAddress; + } total += BiosMemoryMap[slots].Length; slots++; break; @@ -520,6 +523,10 @@ void PpcInit( of_proxy the_ofproxy ) { ofw_getprop( chosen_package, "mmu", (char *)&mmu_handle_chosen, sizeof(mmu_handle_chosen) ); + ofw_print_string("Found stdin "); + ofw_print_number(stdin_handle_chosen); + ofw_print_string("\r\n"); + stdin_handle = REV(stdin_handle_chosen); mmu_handle = REV(mmu_handle_chosen); diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c index 73ff20e9c8c..36743833404 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c @@ -74,6 +74,7 @@ ULONG RaToPa(ULONG p) { #define BAT_GRANULARITY (64 * 1024) #define KernelMemorySize (16 * 1024 * 1024) #define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase +#define XROUNDUP(x,n) ((((ULONG)x) + ((n) - 1)) & (~((n) - 1))) /* Load Address of Next Module */ ULONG_PTR NextModuleBase = 0; @@ -165,6 +166,7 @@ AddPageMapping( DIRECTORY_HEADER *TranslationMap, ULONG OldVirt) { ULONG Phys; DIRECTORY_ENTRY *Entry; + if( !TranslationMap->DirectoryPage || TranslationMap->UsedSpace >= ((1<NumberOfPages); + printf("Local boot info at %x\n", LocalBootInfo); /* * Stuff page table entries for the page containing this code, @@ -243,11 +251,12 @@ FrLdrStartup(ULONG Magic) } /* Tell them we're booting */ - DrawNumber(LocalBootInfo,0x1cabba9e,10,100); + DrawNumber(LocalBootInfo,(ULONG)&LoaderBlock,10,100); DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,100); SetSDR1( NewMapSdr ); - KernelEntryAddress( (void*)LocalBootInfo ); + KernelEntryAddress( (void*)&LoaderBlock ); + /* Nothing more */ while(1); } @@ -364,6 +373,12 @@ FrLdrSetupPageDirectory(VOID) { } +ULONG SignExtend24(ULONG Base, ULONG Delta) +{ + Delta = (Base & 0xfffffc) + Delta; + return (Base & 0xff000003) | (Delta & 0xfffffc); +} + /*++ * FrLdrMapKernel * INTERNAL @@ -402,6 +417,7 @@ FrLdrMapKernel(FILE *KernelImage) ULONG_PTR Delta; PUSHORT ShortPtr; PULONG LongPtr; + PLOADER_MODULE ModuleData; /* Allocate 1024 bytes for PE Header */ ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024); @@ -519,6 +535,11 @@ FrLdrMapKernel(FILE *KernelImage) *ShortPtr += HIWORD(Delta); break; + case IMAGE_REL_BASED_HIGHADJ: + *ShortPtr += + HIWORD(Delta) + ((LOWORD(Delta) & 0x8000) ? 1 : 0); + break; + case IMAGE_REL_BASED_LOW: *ShortPtr += LOWORD(Delta); break; @@ -528,8 +549,13 @@ FrLdrMapKernel(FILE *KernelImage) *LongPtr += Delta; break; + case IMAGE_REL_BASED_MIPS_JMPADDR: + LongPtr = (PULONG)ShortPtr; + *LongPtr = SignExtend24(*LongPtr,Delta); + break; + default: - printf("Unknown relocation %d\n", *TypeOffset >> 12); + //printf("Unknown relocation %d\n", *TypeOffset >> 12); break; } @@ -540,8 +566,13 @@ FrLdrMapKernel(FILE *KernelImage) RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); } + ModuleData = &reactos_modules[LoaderBlock.ModsCount]; + ModuleData->ModStart = (ULONG)KernelMemory; /* Increase the next Load Base */ NextModuleBase = ROUND_UP((ULONG)KernelMemory + ImageSize, PAGE_SIZE); + ModuleData->ModEnd = NextModuleBase; + ModuleData->String = (ULONG)"ntoskrnl.exe"; + LoaderBlock.ModsCount++; /* Return Success */ return TRUE; @@ -580,6 +611,11 @@ FrLdrLoadModule(FILE *ModuleImage, ModuleData->ModStart = NextModuleBase; ModuleData->ModEnd = NextModuleBase + LocalModuleSize; + printf("Module size %x len %x name %s\n", + ModuleData->ModStart, + ModuleData->ModEnd - ModuleData->ModStart, + ModuleName); + /* Save name */ strcpy(NameBuffer, ModuleName); ModuleData->String = (ULONG_PTR)NameBuffer; diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c index 363e4180531..4f4ee7051ac 100644 --- a/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c +++ b/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c @@ -230,7 +230,23 @@ inline int GetSDR1() { } inline void SetSDR1( int sdr ) { +#if 0 + int i,j; +#endif __asm__("mtsdr1 3"); +#if 0 + __asm__("sync"); + __asm__("isync"); + __asm__("ptesync"); + + for( i = 0; i < 256; i++ ) { + j = i << 12; + __asm__("tlbie %0,0" : : "r" (j)); + } + __asm__("eieio"); + __asm__("tlbsync"); + __asm__("ptesync"); +#endif } inline int BatHit( int bath, int batl, int virt ) { @@ -319,12 +335,6 @@ BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) { SetPhys( ptegaddr + (i * 8), ptehi ); SetPhys( ptegaddr + (i * 8) + 4, ptelo ); - __asm__("ptesync"); - __asm__("tlbie %0,0" : : "r" (virt)); - __asm__("eieio"); - __asm__("tlbsync"); - __asm__("ptesync"); - return TRUE; } diff --git a/reactos/boot/freeldr/freeldr/freeldr_base.rbuild b/reactos/boot/freeldr/freeldr/freeldr_base.rbuild index be33668daf3..9a64ccd0eab 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_base.rbuild +++ b/reactos/boot/freeldr/freeldr/freeldr_base.rbuild @@ -54,6 +54,7 @@ list.c + libsupp.c gui.c diff --git a/reactos/boot/freeldr/freeldr/mm/mm.c b/reactos/boot/freeldr/freeldr/mm/mm.c index 91fd0bd5eaf..b049aee385c 100644 --- a/reactos/boot/freeldr/freeldr/mm/mm.c +++ b/reactos/boot/freeldr/freeldr/mm/mm.c @@ -92,8 +92,10 @@ PVOID MmAllocateMemory(ULONG MemorySize) if (FreePagesInLookupTable < PagesNeeded) { #ifdef _M_PPC + ULONG ptr; printf("Allocating %d bytes directly ...\n", MemorySize); - MemPointer = (PVOID)ofw_claim(0,MemorySize,MM_PAGE_SIZE); + ptr = ofw_claim(0,MemorySize,MM_PAGE_SIZE); + MemPointer = (PVOID)(REV(ptr)); #endif if( !MemPointer ) { diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index b04b8bd8958..c170d894370 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -30,8 +30,13 @@ LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded f char reactos_module_strings[64][256]; // Array to hold module names unsigned long reactos_memory_map_descriptor_size; memory_map_t reactos_memory_map[32]; // Memory map - +ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information +char reactos_arc_strings[32][256]; +unsigned long reactos_disk_count = 0; +CHAR szHalName[255]; +CHAR szBootPath[255]; static CHAR szLoadingMsg[] = "Loading ReactOS..."; +BOOLEAN FrLdrBootType; static BOOLEAN NTAPI @@ -123,6 +128,7 @@ LoadKernelSymbols(PCHAR szKernelName, int nPos) PROSSYM_INFO RosSymInfo; ULONG Size; ULONG_PTR Base; + //return TRUE; RosSymInit(&FreeldrCallbacks); @@ -562,14 +568,12 @@ VOID LoadAndBootReactOS(PCSTR OperatingSystemName) { PFILE FilePointer; - CHAR name[1024]; - CHAR value[1024]; - CHAR SystemPath[1024]; - CHAR szKernelName[1024]; - CHAR szHalName[1024]; - CHAR szFileName[1024]; - CHAR szBootPath[256]; - UINT i; + CHAR name[255]; + CHAR value[255]; + CHAR SystemPath[255]; + CHAR szKernelName[255]; + CHAR szFileName[255]; + UINT i; CHAR MsgBuffer[256]; ULONG SectionId; @@ -595,6 +599,8 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) UiDrawStatusText("Detecting Hardware..."); UiDrawProgressBarCenter(1, 100, szLoadingMsg); + printf("LoadAndBootReactOS\n"); + /* * Setup multiboot information structure */ @@ -602,17 +608,21 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart; LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd; LoaderBlock.BootDevice = 0xffffffff; - LoaderBlock.CommandLine = (unsigned long)reactos_kernel_cmdline; + LoaderBlock.CommandLine = (ULONG)reactos_kernel_cmdline; LoaderBlock.ModsCount = 0; - LoaderBlock.ModsAddr = (unsigned long)reactos_modules; + LoaderBlock.ModsAddr = (ULONG)reactos_modules; + LoaderBlock.DrivesAddr = (ULONG)reactos_arc_disk_info; LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&reactos_memory_map, 32) * sizeof(memory_map_t); + printf("Got memory map length: %d\n", LoaderBlock.MmapLength); if (LoaderBlock.MmapLength) { LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map; LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO; - reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24 + *((PULONG)(LoaderBlock.MmapAddr - sizeof(ULONG))) = + reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24 DbgPrint((DPRINT_REACTOS, "memory map length: %d\n", LoaderBlock.MmapLength)); DbgPrint((DPRINT_REACTOS, "dumping memory map:\n")); + printf("memory map length: %d\n", LoaderBlock.MmapLength); for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++) { if (BiosMemoryUsable == reactos_memory_map[i].type && @@ -634,6 +644,10 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) reactos_memory_map[i].base_addr_low, reactos_memory_map[i].length_low, reactos_memory_map[i].type)); + printf("start: %x size: %x type %d\n", + reactos_memory_map[i].base_addr_low, + reactos_memory_map[i].length_low, + reactos_memory_map[i].type); } } DbgPrint((DPRINT_REACTOS, "low_mem = %d\n", LoaderBlock.MemLower)); @@ -679,7 +693,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) /* * Read the optional kernel parameters (if any) */ - if (IniReadSettingByName(SectionId, "Options", value, 1024)) + if (IniReadSettingByName(SectionId, "Options", value, sizeof(value))) { strcat(reactos_kernel_cmdline, " "); strcat(reactos_kernel_cmdline, value); @@ -692,6 +706,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) UiDrawProgressBarCenter(5, 100, szLoadingMsg); if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE; + LoaderBlock.DrivesCount = reactos_disk_count; UiDrawStatusText("Loading..."); @@ -715,7 +730,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) * Find the kernel image name * and try to load the kernel off the disk */ - if(IniReadSettingByName(SectionId, "Kernel", value, 1024)) + if(IniReadSettingByName(SectionId, "Kernel", value, sizeof(value))) { /* * Set the name and @@ -739,13 +754,11 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) strcat(szKernelName, value); } - if (!FrLdrLoadKernel(szKernelName, 5)) return; - /* * Find the HAL image name * and try to load the kernel off the disk */ - if(IniReadSettingByName(SectionId, "Hal", value, 1024)) + if(IniReadSettingByName(SectionId, "Hal", value, sizeof(value))) { /* * Set the name and @@ -769,19 +782,10 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) strcat(szHalName, value); } - if (!FrLdrLoadDriver(szHalName, 10)) - return; + /* Load the kernel */ + if (!FrLdrLoadKernel(szKernelName, 5)) return; + if (!FrLdrLoadDriver(szHalName, 6)) return; -#if 0 - /* Load bootvid */ - strcpy(value, "INBV.DLL"); - strcpy(szHalName, szBootPath); - strcat(szHalName, "SYSTEM32\\"); - strcat(szHalName, value); - - if (!FrLdrLoadDriver(szHalName, 10)) - return; -#endif /* * Load the System hive from disk */ @@ -820,11 +824,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) /* * Import the loaded system hive */ - if( !RegImportBinaryHive((PCHAR)Base, Size) ) - { - printf("Could not load system hive\n"); - return; - } + RegImportBinaryHive((PCHAR)Base, Size); /* * Initialize the 'CurrentControlSet' link @@ -874,8 +874,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) #undef DbgPrint ULONG -__cdecl -DbgPrint(PCCH Format, ...) +DbgPrint(const char *Format, ...) { va_list ap; CHAR Buffer[512]; diff --git a/reactos/boot/freeldr/freeldr/windows/peloader.c b/reactos/boot/freeldr/freeldr/windows/peloader.c index 9419dd40539..1f1e75f8181 100644 --- a/reactos/boot/freeldr/freeldr/windows/peloader.c +++ b/reactos/boot/freeldr/freeldr/windows/peloader.c @@ -21,6 +21,15 @@ /* FUNCTIONS **************************************************************/ +BOOLEAN +WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PCH DllName, + OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry) +{ + return FALSE; +} + + BOOLEAN WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, IN PCCH DirectoryPath, diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index bef20f48ccd..603965e15de 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -26,8 +26,25 @@ //#define NDEBUG #include +//FIXME: Do a better way to retrieve Arc disk information +extern ULONG reactos_disk_count; +extern ARC_DISK_SIGNATURE reactos_arc_disk_info[]; +extern char reactos_arc_strings[32][256]; + +ARC_DISK_SIGNATURE BldrDiskInfo[32]; +CHAR BldrArcNames[32][256]; + +BOOLEAN +WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, + IN PCH DllName, + OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry); + +// debug stuff VOID DumpMemoryAllocMap(VOID); VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock); +VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock); +VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock); + void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock) { @@ -85,6 +102,14 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock) InitializeListHead(&LoaderBlock->MemoryDescriptorListHead); InitializeListHead(&LoaderBlock->BootDriverListHead); + /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */ + LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK)); + if (LoaderBlock->NlsData == NULL) + { + UiMessageBox("Failed to allocate memory for NLS table data!"); + return; + } + RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK)); *OutLoaderBlock = LoaderBlock; } @@ -95,11 +120,12 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) { //CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200"; CHAR Options[] = "/NODEBUG"; - CHAR SystemRoot[] = "\\WINNT"; + CHAR SystemRoot[] = "\\WINNT\\"; CHAR HalPath[] = "\\"; CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)"; CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)"; + ULONG i; PLOADER_PARAMETER_EXTENSION Extension; LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support @@ -132,18 +158,32 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) /* Arc devices */ LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION)); InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); + + /* Convert ARC disk information from freeldr to a correct format */ + for (i = 0; i < reactos_disk_count; i++) + { + PARC_DISK_SIGNATURE ArcDiskInfo; + + /* Get the ARC structure */ + ArcDiskInfo = &BldrDiskInfo[i]; + + /* Copy the data over */ + ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature; + ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum; + + /* Copy the ARC Name */ + strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName); + ArcDiskInfo->ArcName = BldrArcNames[i]; + + /* Insert into the list */ + InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead, + &ArcDiskInfo->ListEntry); + } + + /* Convert the list to virtual address */ List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation); - /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */ - LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK)); - if (LoaderBlock->NlsData == NULL) - { - UiMessageBox("Failed to allocate memory for NLS table data!"); - return; - } - RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK)); - /* Create configuration entries */ InitializeHWConfig(LoaderBlock); @@ -224,6 +264,111 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock, RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT); } +BOOLEAN +WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock, + LPSTR BootPath, + PUNICODE_STRING FilePath, + ULONG Flags, + PLDR_DATA_TABLE_ENTRY *DriverDTE) +{ + CHAR FullPath[1024]; + CHAR DriverPath[1024]; + CHAR DllName[1024]; + PCHAR DriverNamePos; + BOOLEAN Status; + PVOID DriverBase; + + // Separate the path to file name and directory path + sprintf(DriverPath, "%wZ", FilePath); + DriverNamePos = strrchr(DriverPath, '\\'); + if (DriverNamePos != NULL) + { + // Copy the name + strcpy(DllName, DriverNamePos+1); + + // Cut out the name from the path + *(DriverNamePos+1) = 0; + } + + DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock)); + + + // Check if driver is already loaded + Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE); + if (Status) + { + // We've got the pointer to its DTE, just return success + return TRUE; + } + + // It's not loaded, we have to load it + sprintf(FullPath,"%s%wZ", BootPath, FilePath); + Status = WinLdrLoadImage(FullPath, &DriverBase); + if (!Status) + return FALSE; + + // Allocate a DTE for it + Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n")); + return FALSE; + } + + // Modify any flags, if needed + (*DriverDTE)->Flags |= Flags; + + // Look for any dependencies it may have, and load them too + sprintf(FullPath,"%s%s", BootPath, DriverPath); + Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE); + if (!Status) + { + DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n", + FullPath)); + return FALSE; + } + + return TRUE; +} + +BOOLEAN +WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock, + LPSTR BootPath) +{ + PLIST_ENTRY NextBd; + PBOOT_DRIVER_LIST_ENTRY BootDriver; + BOOLEAN Status; + + // Walk through the boot drivers list + NextBd = LoaderBlock->BootDriverListHead.Flink; + + while (NextBd != &LoaderBlock->BootDriverListHead) + { + BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry); + + //DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath, + // BootDriver->DataTableEntry, &BootDriver->RegistryPath)); + + // Paths are relative (FIXME: Are they always relative?) + + // Load it + Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath, + 0, &BootDriver->DataTableEntry); + + // If loading failed - cry loudly + //FIXME: Maybe remove it from the list and try to continue? + if (!Status) + { + UiMessageBox("Can't load boot driver!"); + return FALSE; + } + + NextBd = BootDriver->ListEntry.Flink; + } + + return TRUE; +} + VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) { @@ -243,8 +388,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) ULONG PcrBasePage=0; ULONG TssBasePage=0; - - //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion); //UiMessageBox(MsgBuffer); @@ -257,6 +400,13 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) return; } + UiDrawBackdrop(); + UiDrawStatusText("Detecting Hardware..."); + UiDrawProgressBarCenter(1, 100, "Loading Windows..."); + + //FIXME: This is needed only for MachHwDetect() which performs registry operations! + RegInitializeRegistry(); + /* Make sure the system path is set in the .ini file */ if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath))) { @@ -271,6 +421,9 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) return; } + /* Detect hardware */ + MachHwDetect(); + UiDrawStatusText("Loading..."); /* Try to open system drive */ @@ -331,17 +484,16 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) if (KdComDTE) WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE); - /* Initialize Phase 1 - before NLS */ - WinLdrInitializePhase1(LoaderBlock); - /* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */ Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath); DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status)); - /* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */ - /* Load boot drivers */ - //WinLdrLoadBootDrivers(); + Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath); + DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status)); + + /* Initialize Phase 1 - no drivers loading anymore */ + WinLdrInitializePhase1(LoaderBlock); /* Alloc PCR, TSS, do magic things with the GDT/IDT */ WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); @@ -361,6 +513,8 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) KiSystemStartup, LoaderBlockVA)); WinLdrpDumpMemoryDescriptors(LoaderBlockVA); + WinLdrpDumpBootDriver(LoaderBlockVA); + WinLdrpDumpArcDisks(LoaderBlockVA); //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below //while (1) {}; @@ -394,3 +548,41 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock) NextMd = MemoryDescriptor->ListEntry.Flink; } } + +VOID +WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY NextBd; + PBOOT_DRIVER_LIST_ENTRY BootDriver; + + NextBd = LoaderBlock->BootDriverListHead.Flink; + + while (NextBd != &LoaderBlock->BootDriverListHead) + { + BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry); + + DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath, + BootDriver->DataTableEntry, &BootDriver->RegistryPath)); + + NextBd = BootDriver->ListEntry.Flink; + } +} + +VOID +WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY NextBd; + PARC_DISK_SIGNATURE ArcDisk; + + NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink; + + while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead) + { + ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry); + + DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n", + ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature)); + + NextBd = ArcDisk->ListEntry.Flink; + } +} diff --git a/reactos/boot/freeldr/freeldr/windows/wlmemory.c b/reactos/boot/freeldr/freeldr/windows/wlmemory.c index 9f6cbc5e545..7848a3e8353 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlmemory.c +++ b/reactos/boot/freeldr/freeldr/windows/wlmemory.c @@ -15,6 +15,8 @@ #define NDEBUG #include +extern ULONG TotalNLSSize; + // This is needed because headers define wrong one for ReactOS #undef KIP0PCRADDRESS #define KIP0PCRADDRESS 0xffdff000 @@ -300,7 +302,7 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, // Check if it's more than the allowed for OS loader // if yes - don't map the pages, just add as FirmwareTemporary // - if (BasePage + PageCount > LOADER_HIGH_ZONE) + if (BasePage + PageCount > LOADER_HIGH_ZONE && (Type != LoaderNlsData)) { Mad[MadCount].MemoryType = LoaderFirmwareTemporary; @@ -353,24 +355,9 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, else { // - // Now choose memory type as usual. FIXME!!! + // Set memory type // - if (Type == 0) - { - Mad[MadCount].MemoryType = LoaderFree; - } - else if (Type != 0 && Type != 1) - { - Mad[MadCount].MemoryType = LoaderFirmwarePermanent; - } - else if (Type == 1) - { - Mad[MadCount].MemoryType = LoaderSystemCode; - } - else - { - Mad[MadCount].MemoryType = LoaderFirmwarePermanent; - } + Mad[MadCount].MemoryType = Type; // // Add descriptor @@ -397,12 +384,15 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG TssBasePage, PVOID GdtIdt) { -#ifdef _M_IX86 ULONG i, PagesCount; - ULONG LastPageIndex, LastPageType; + ULONG LastPageIndex, LastPageType, NtType; PPAGE_LOOKUP_TABLE_ITEM MemoryMap; ULONG NoEntries; +#if 0 PKTSS Tss; +#endif + PVOID NlsBase = VaToPa(((PNLS_DATA_BLOCK)VaToPa(LoaderBlock->NlsData))->AnsiCodePageData); + ULONG NlsBasePage = (ULONG_PTR)NlsBase >> PAGE_SHIFT; // // Creating a suitable memory map for the Windows can be tricky, so let's @@ -439,7 +429,8 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, return FALSE; } - DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries\n")); + DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries, NlsBasePage 0x%X\n", + NoEntries, NlsBasePage)); // Construct a good memory map from what we've got PagesCount = 1; @@ -447,14 +438,67 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, LastPageType = MemoryMap[0].PageAllocated; for(i=1;i NlsBasePage+TotalNLSSize) && (i != NoEntries-1) ) { PagesCount++; } + else if (i == NlsBasePage) + { + // This is NLS data, map it accordingly + // It's VERY important for NT kernel - it calculates size of NLS + // tables based on NlsData memory type descriptors! + + // Firstly map what we already have (if we have any) + // Convert mem types + if (LastPageType == 0) + NtType = LoaderFree; + else if (LastPageType != 0 && LastPageType != 1) + NtType = LoaderFirmwarePermanent; + else if (LastPageType == 1) + NtType = LoaderSystemCode; + else + NtType = LoaderFirmwarePermanent; + + if (PagesCount > 0) + MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType); + + // Then map nls data + MempAddMemoryBlock(LoaderBlock, NlsBasePage, TotalNLSSize, LoaderNlsData); + + // skip them + i += TotalNLSSize; + + // Reset our counter vars + LastPageIndex = i; + LastPageType = MemoryMap[i].PageAllocated; + PagesCount = 1; + + continue; + } else { - // Add the region - MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType); + // Add the resulting region + + // Convert mem types + if (LastPageType == 0) + { + NtType = LoaderFree; + } + else if (LastPageType != 0 && LastPageType != 1) + { + NtType = LoaderFirmwarePermanent; + } + else if (LastPageType == 1) + { + NtType = LoaderSystemCode; + } + else + { + NtType = LoaderFirmwarePermanent; + } + + MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType); // Reset our counter vars LastPageIndex = i; @@ -480,6 +524,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, // Page Tables have been setup, make special handling for PCR and TSS // (which is done in BlSetupFotNt in usual ntldr) +#ifdef _M_IX86 HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1; HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1; HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1; @@ -493,6 +538,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, //DbgPrint((DPRINT_WINDOWS, "VideoMemoryBase: 0x%X\n", VideoMemoryBase)); Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)); +#endif // Fill the memory descriptor list and //PrepareMemoryDescriptorList(); @@ -525,23 +571,29 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, //BS->ExitBootServices(ImageHandle,MapKey); // Disable Interrupts - Ke386DisableInterrupts(); + _disable(); // Re-initalize EFLAGS +#ifdef _M_IX86 Ke386EraseFlags(); +#endif // Set the PDBR - Ke386SetPageTableDirectory((ULONG_PTR)PDE); +#ifdef _M_IX86 + __writecr3((ULONG_PTR)PDE); +#endif // Enable paging by modifying CR0 - Ke386SetCr0(Ke386GetCr0() | CR0_PG); +#ifdef _M_IX86 + __writecr0(__readcr0() | CR0_PG); +#endif // Set processor context - WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)); + WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, 0/*KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)*/); // Zero KI_USER_SHARED_DATA page memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE); -#endif + return TRUE; } diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c index 73ec593c508..6c97762176b 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlregistry.c +++ b/reactos/boot/freeldr/freeldr/windows/wlregistry.c @@ -18,6 +18,23 @@ #define NDEBUG #include +// The only global var here, used to mark mem pages as NLS in WinLdrTurnOnPaging() +ULONG TotalNLSSize = 0; + +BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName, + LPSTR OemName, + LPSTR LangName); + +VOID +WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath); + +BOOLEAN +WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, + LPWSTR RegistryPath, + LPWSTR ImagePath, + LPWSTR ServiceName); + BOOLEAN WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, @@ -96,6 +113,9 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, return TRUE; } + +/* PRIVATE FUNCTIONS ******************************************************/ + // Queries registry for those three file names BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName, LPSTR OemName, @@ -315,6 +335,9 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, MM_SIZE_TO_PAGES(OemFileSize) + MM_SIZE_TO_PAGES(LanguageFileSize); + /* Store it for later marking the pages as NlsData type */ + TotalNLSSize = TotalSize; + NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); if (NlsDataBase == 0) @@ -401,3 +424,317 @@ Failure: UiMessageBox("Error reading NLS file!"); return FALSE; } + +VOID +WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN LPCSTR DirectoryPath) +{ + LONG rc = 0; + FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey; + WCHAR GroupNameBuffer[512]; + WCHAR ServiceName[256]; + ULONG OrderList[128]; + ULONG BufferSize; + ULONG Index; + ULONG TagIndex; + LPWSTR GroupName; + + ULONG ValueSize; + ULONG ValueType; + ULONG StartValue; + ULONG TagValue; + WCHAR DriverGroup[256]; + ULONG DriverGroupSize; + + CHAR ImagePath[256]; + WCHAR TempImagePath[256]; + + BOOLEAN Status; + + /* get 'service group order' key */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder", + &hGroupKey); + if (rc != ERROR_SUCCESS) { + + DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc)); + return; + } + + /* get 'group order list' key */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", + &hOrderKey); + if (rc != ERROR_SUCCESS) { + + DbgPrint((DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc)); + return; + } + + /* enumerate drivers */ + rc = RegOpenKey(NULL, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services", + &hServiceKey); + if (rc != ERROR_SUCCESS) { + + DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc)); + return; + } + + /* Get the Name Group */ + BufferSize = sizeof(GroupNameBuffer); + rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize); + DbgPrint((DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc)); + if (rc != ERROR_SUCCESS) + return; + DbgPrint((DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize)); + DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer)); + + /* Loop through each group */ + GroupName = GroupNameBuffer; + while (*GroupName) + { + DbgPrint((DPRINT_WINDOWS, "Driver group: '%S'\n", GroupName)); + + /* Query the Order */ + BufferSize = sizeof(OrderList); + rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize); + if (rc != ERROR_SUCCESS) OrderList[0] = 0; + + /* enumerate all drivers */ + for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) + { + Index = 0; + + while (TRUE) + { + /* Get the Driver's Name */ + ValueSize = sizeof(ServiceName); + rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize); + //DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc)); + + /* Makre sure it's valid, and check if we're done */ + if (rc == ERROR_NO_MORE_ITEMS) + break; + if (rc != ERROR_SUCCESS) + return; + //DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName)); + + /* open driver Key */ + rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey); + if (rc == ERROR_SUCCESS) + { + /* Read the Start Value */ + ValueSize = sizeof(ULONG); + rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize); + if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1; + //DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue)); + + /* Read the Tag */ + ValueSize = sizeof(ULONG); + rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize); + if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1; + //DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue)); + + /* Read the driver's group */ + DriverGroupSize = sizeof(DriverGroup); + rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize); + //DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup)); + + /* Make sure it should be started */ + if ((StartValue == 0) && + (TagValue == OrderList[TagIndex]) && + (_wcsicmp(DriverGroup, GroupName) == 0)) { + + /* Get the Driver's Location */ + ValueSize = sizeof(TempImagePath); + rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize); + + /* Write the whole path if it suceeded, else prepare to fail */ + if (rc != ERROR_SUCCESS) { + DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n")); + TempImagePath[0] = 0; + sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath, ServiceName); + } else if (TempImagePath[0] != L'\\') { + sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath); + } else { + sprintf(ImagePath, "%S", TempImagePath); + DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath)); + } + + DbgPrint((DPRINT_WINDOWS, " Adding boot driver: '%s'\n", ImagePath)); + + Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", + TempImagePath, + ServiceName); + + if (!Status) + DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n")); + } else + { + //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n", + // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName)); + } + } + + Index++; + } + } + + Index = 0; + while (TRUE) + { + /* Get the Driver's Name */ + ValueSize = sizeof(ServiceName); + rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize); + + //DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc)); + if (rc == ERROR_NO_MORE_ITEMS) + break; + if (rc != ERROR_SUCCESS) + return; + //DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName)); + + /* open driver Key */ + rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey); + if (rc == ERROR_SUCCESS) + { + /* Read the Start Value */ + ValueSize = sizeof(ULONG); + rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize); + if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1; + //DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue)); + + /* Read the Tag */ + ValueSize = sizeof(ULONG); + rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize); + if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1; + //DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue)); + + /* Read the driver's group */ + DriverGroupSize = sizeof(DriverGroup); + rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize); + //DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup)); + + for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) { + if (TagValue == OrderList[TagIndex]) break; + } + + if ((StartValue == 0) && + (TagIndex > OrderList[0]) && + (_wcsicmp(DriverGroup, GroupName) == 0)) { + + ValueSize = sizeof(TempImagePath); + rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize); + if (rc != ERROR_SUCCESS) { + DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n")); + TempImagePath[0] = 0; + sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName); + } else if (TempImagePath[0] != L'\\') { + sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath); + } else { + sprintf(ImagePath, "%S", TempImagePath); + DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath)); + } + DbgPrint((DPRINT_WINDOWS, " Adding boot driver: '%s'\n", ImagePath)); + + Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", + TempImagePath, + ServiceName); + + if (!Status) + DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n")); + } else + { + //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n", + // ServiceName, StartValue, TagValue, DriverGroup, GroupName)); + } + } + + Index++; + } + + /* Move to the next group name */ + GroupName = GroupName + wcslen(GroupName) + 1; + } +} + +BOOLEAN +WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, + LPWSTR RegistryPath, + LPWSTR ImagePath, + LPWSTR ServiceName) +{ + PBOOT_DRIVER_LIST_ENTRY BootDriverEntry; + NTSTATUS Status; + ULONG PathLength; + + BootDriverEntry = MmAllocateMemory(sizeof(BOOT_DRIVER_LIST_ENTRY)); + + if (!BootDriverEntry) + return FALSE; + + // DTE will be filled during actual load of the driver + BootDriverEntry->DataTableEntry = NULL; + + // Check - if we have a valid ImagePath, if not - we need to build it + // like "System32\\Drivers\\blah.sys" + if (ImagePath && (wcslen(ImagePath) > 0)) + { + // Just copy ImagePath to the corresponding field in the structure + PathLength = wcslen(ImagePath) * sizeof(WCHAR); + + BootDriverEntry->FilePath.Length = 0; + BootDriverEntry->FilePath.MaximumLength = PathLength + sizeof(WCHAR); + BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength); + + if (!BootDriverEntry->FilePath.Buffer) + return FALSE; + + Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath); + if (!NT_SUCCESS(Status)) + return FALSE; + } + else + { + // we have to construct ImagePath ourselves + PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");; + BootDriverEntry->FilePath.Length = 0; + BootDriverEntry->FilePath.MaximumLength = PathLength+sizeof(WCHAR); + BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength); + + if (!BootDriverEntry->FilePath.Buffer) + return FALSE; + + Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\"); + if (!NT_SUCCESS(Status)) + return FALSE; + + Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName); + if (!NT_SUCCESS(Status)) + return FALSE; + + Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys"); + if (!NT_SUCCESS(Status)) + return FALSE; + } + + // Add registry path + PathLength = wcslen(RegistryPath)*sizeof(WCHAR); + BootDriverEntry->RegistryPath.Length = 0; + BootDriverEntry->RegistryPath.MaximumLength = PathLength+sizeof(WCHAR); + BootDriverEntry->RegistryPath.Buffer = MmAllocateMemory(PathLength); + if (!BootDriverEntry->RegistryPath.Buffer) + return FALSE; + + Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath); + if (!NT_SUCCESS(Status)) + return FALSE; + + // Insert entry at top of the list + InsertHeadList(BootDriverListHead, &BootDriverEntry->ListEntry); + + return TRUE; +} diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 721721b32c8..0a3684e60bf 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -31,29 +31,30 @@ extern "C" { #endif +#ifdef __GNUC__ #include "intrin.h" +#endif /* ** Definitions specific to this Device Driver Kit */ #define DDKAPI __stdcall -#define DDKFASTAPI __fastcall #define FASTCALL __fastcall #define DDKCDECLAPI __cdecl - -/* FIXME: REMOVE THIS UNCOMPATIBLE CRUFT!!! */ -//#define NTKERNELAPI +#ifndef DDKFASTAPI +#define DDKFASTAPI +#endif +#ifndef NTOSAPI +#define NTOSAPI +#endif #ifdef _NTOSKRNL_ -#define NTKERNELAPI +/* HACKHACKHACK!!! We shouldn't include this header from ntoskrnl! */ +#define NTKERNELAPI #else #define NTKERNELAPI DECLSPEC_IMPORT #endif - -#ifndef NTOSAPI -#define NTOSAPI NTKERNELAPI -#endif #if defined(_NTOSKRNL_) #define DECLARE_INTERNAL_OBJECT(x) typedef struct _##x; typedef struct _##x *P##x; #define DECLARE_INTERNAL_OBJECT2(x,y) typedef struct _##x; typedef struct _##x *P##y; @@ -2629,35 +2630,35 @@ typedef NTSTATUS IN PDEVICE_CONTROL_COMPLETION CompletionRoutine); typedef VOID -(DDKFASTAPI *pHalExamineMBR)( +(FASTCALL *pHalExamineMBR)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MBRTypeIdentifier, OUT PVOID *Buffer); typedef VOID -(DDKFASTAPI *pHalIoAssignDriveLetters)( +(FASTCALL *pHalIoAssignDriveLetters)( IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, IN PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString); typedef NTSTATUS -(DDKFASTAPI *pHalIoReadPartitionTable)( +(FASTCALL *pHalIoReadPartitionTable)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer); typedef NTSTATUS -(DDKFASTAPI *pHalIoSetPartitionInformation)( +(FASTCALL *pHalIoSetPartitionInformation)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType); typedef NTSTATUS -(DDKFASTAPI *pHalIoWritePartitionTable)( +(FASTCALL *pHalIoWritePartitionTable)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, @@ -2665,12 +2666,12 @@ typedef NTSTATUS IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer); typedef PBUS_HANDLER -(DDKFASTAPI *pHalHandlerForBus)( +(FASTCALL *pHalHandlerForBus)( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber); typedef VOID -(DDKFASTAPI *pHalReferenceBusHandler)( +(FASTCALL *pHalReferenceBusHandler)( IN PBUS_HANDLER BusHandler); typedef NTSTATUS @@ -4183,7 +4184,7 @@ typedef struct _RTL_OSVERSIONINFOEXW { UCHAR wReserved; } RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; -NTOSAPI +NTSYSAPI ULONGLONG DDKAPI VerSetConditionMask( @@ -5080,7 +5081,7 @@ typedef struct _DISK_SIGNATURE { } DISK_SIGNATURE, *PDISK_SIGNATURE; typedef VOID -(DDKFASTAPI*PTIME_UPDATE_NOTIFY_ROUTINE)( +(FASTCALL*PTIME_UPDATE_NOTIFY_ROUTINE)( IN HANDLE ThreadId, IN KPROCESSOR_MODE Mode); @@ -5218,9 +5219,9 @@ typedef struct _KFLOATING_SAVE { #define PAGE_SIZE 0x1000 #define PAGE_SHIFT 12L -extern NTOSAPI PVOID MmHighestUserAddress; -extern NTOSAPI PVOID MmSystemRangeStart; -extern NTOSAPI ULONG_PTR MmUserProbeAddress; +extern NTKERNELAPI PVOID MmHighestUserAddress; +extern NTKERNELAPI PVOID MmSystemRangeStart; +extern NTKERNELAPI ULONG_PTR MmUserProbeAddress; #define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress #define MM_SYSTEM_RANGE_START MmSystemRangeStart @@ -5278,36 +5279,36 @@ KeGetCurrentProcessorNumber(VOID) #if !defined(__INTERLOCKED_DECLARED) #define __INTERLOCKED_DECLARED -NTOSAPI +NTKERNELAPI LONG -DDKFASTAPI +FASTCALL InterlockedIncrement( IN OUT LONG volatile *Addend); -NTOSAPI +NTKERNELAPI LONG -DDKFASTAPI +FASTCALL InterlockedDecrement( IN OUT LONG volatile *Addend); -NTOSAPI +NTKERNELAPI LONG -DDKFASTAPI +FASTCALL InterlockedCompareExchange( IN OUT LONG volatile *Destination, IN LONG Exchange, IN LONG Comparand); -NTOSAPI +NTKERNELAPI LONG -DDKFASTAPI +FASTCALL InterlockedExchange( IN OUT LONG volatile *Destination, IN LONG Value); -NTOSAPI +NTKERNELAPI LONG -DDKFASTAPI +FASTCALL InterlockedExchangeAdd( IN OUT LONG volatile *Addend, IN LONG Value); @@ -5337,27 +5338,27 @@ InterlockedExchangeAdd( #endif /* !__INTERLOCKED_DECLARED */ -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL KefAcquireSpinLockAtDpcLevel( IN PKSPIN_LOCK SpinLock); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL KefReleaseSpinLockFromDpcLevel( IN PKSPIN_LOCK SpinLock); NTHALAPI KIRQL -DDKFASTAPI +FASTCALL KfAcquireSpinLock( IN PKSPIN_LOCK SpinLock); NTHALAPI VOID -DDKFASTAPI +FASTCALL KfReleaseSpinLock( IN PKSPIN_LOCK SpinLock, IN KIRQL NewIrql); @@ -5371,7 +5372,10 @@ KfReleaseSpinLock( #define KeGetDcacheFillSize() 1L -#elif defined(_PPC_) +#elif defined(_M_PPC) + +#define PAGE_SIZE 0x1000 +#define PAGE_SHIFT 12L typedef ULONG PFN_NUMBER, *PPFN_NUMBER; @@ -5444,15 +5448,15 @@ typedef struct _KPCR { UCHAR Number; /* 51 */ } KPCR, *PKPCR; /* 54 */ +#if !defined(__INTERLOCKED_DECLARED) +#define __INTERLOCKED_DECLARED + NTHALAPI KIRQL DDKAPI KeGetCurrentIrql( VOID); -#if !defined(__INTERLOCKED_DECLARED) -#define __INTERLOCKED_DECLARED - NTOSAPI LONG DDKFASTAPI @@ -5505,7 +5509,6 @@ InterlockedExchangeAdd( */ #define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \ ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand)) -#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a) #endif /* !__INTERLOCKED_DECLARED */ @@ -5560,10 +5563,6 @@ KeGetCurrentProcessorNumber(VOID) { return 0; // XXX arty fixme } - -#define PAGE_SIZE 0x1000 -#define PAGE_SHIFT 12L - #endif /* _X86_ */ /* @@ -5694,14 +5693,16 @@ extern BOOLEAN NTSYSAPI NLS_MB_OEM_CODE_PAGE_TAG; /** Runtime library routines **/ -static __inline VOID +VOID +FORCEINLINE InitializeListHead( IN PLIST_ENTRY ListHead) { ListHead->Flink = ListHead->Blink = ListHead; } -static __inline VOID +VOID +FORCEINLINE InsertHeadList( IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) @@ -5714,7 +5715,8 @@ InsertHeadList( ListHead->Flink = Entry; } -static __inline VOID +VOID +FORCEINLINE InsertTailList( IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) @@ -5759,7 +5761,8 @@ InsertTailList( (_Entry)->Next = (_ListHead)->Next; \ (_ListHead)->Next = (_Entry); \ -static __inline BOOLEAN +BOOLEAN +FORCEINLINE RemoveEntryList( IN PLIST_ENTRY Entry) { @@ -5773,7 +5776,8 @@ RemoveEntryList( return (OldFlink == OldBlink); } -static __inline PLIST_ENTRY +PLIST_ENTRY +FORCEINLINE RemoveHeadList( IN PLIST_ENTRY ListHead) { @@ -5787,7 +5791,8 @@ RemoveHeadList( return Entry; } -static __inline PLIST_ENTRY +PLIST_ENTRY +FORCEINLINE RemoveTailList( IN PLIST_ENTRY ListHead) { @@ -5803,15 +5808,15 @@ RemoveTailList( #if !defined(_WINBASE_H) || _WIN32_WINNT < 0x0501 -NTOSAPI +NTKERNELAPI PSLIST_ENTRY -DDKFASTAPI +FASTCALL InterlockedPopEntrySList( IN PSLIST_HEADER ListHead); -NTOSAPI +NTKERNELAPI PSLIST_ENTRY -DDKFASTAPI +FASTCALL InterlockedPushEntrySList( IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry); @@ -5828,9 +5833,9 @@ InterlockedPushEntrySList( #define InterlockedFlushSList(ListHead) ExInterlockedFlushSList(ListHead) -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlxAnsiStringToUnicodeSize( IN PCANSI_STRING AnsiString); @@ -5840,106 +5845,106 @@ RtlxAnsiStringToUnicodeSize( ((STRING)->Length + sizeof(ANSI_NULL)) * sizeof(WCHAR) \ ) -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlAnsiStringToUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlAppendUnicodeStringToString( IN OUT PUNICODE_STRING Destination, IN PCUNICODE_STRING Source); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlAppendUnicodeToString( IN OUT PUNICODE_STRING Destination, IN PCWSTR Source); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlAreBitsClear( IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG Length); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlAreBitsSet( IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG Length); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlCharToInteger( IN PCSZ String, IN ULONG Base OPTIONAL, IN OUT PULONG Value); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlCheckBit( IN PRTL_BITMAP BitMapHeader, IN ULONG BitPosition); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlCheckRegistryKey( IN ULONG RelativeTo, IN PWSTR Path); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlClearAllBits( IN PRTL_BITMAP BitMapHeader); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlClearBit( PRTL_BITMAP BitMapHeader, ULONG BitNumber); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlClearBits( IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG NumberToClear); -NTOSAPI +NTSYSAPI SIZE_T -DDKAPI +NTAPI RtlCompareMemory( IN CONST VOID *Source1, IN CONST VOID *Source2, IN SIZE_T Length); -NTOSAPI +NTSYSAPI LONG -DDKAPI +NTAPI RtlCompareString( IN PSTRING String1, IN PSTRING String2, BOOLEAN CaseInSensitive); -NTOSAPI +NTSYSAPI LONG -DDKAPI +NTAPI RtlCompareUnicodeString( IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2, @@ -5956,21 +5961,21 @@ RtlConvertLongToLargeInteger(LONG SignedInteger) return Result; } -NTOSAPI +NTSYSAPI LUID -DDKAPI +NTAPI RtlConvertLongToLuid( IN LONG Long); -NTOSAPI +NTSYSAPI LARGE_INTEGER -DDKAPI +NTAPI RtlConvertUlongToLargeInteger( IN ULONG UnsignedInteger); -NTOSAPI +NTSYSAPI LUID -DDKAPI +NTAPI RtlConvertUlongToLuid( ULONG Ulong); @@ -5990,45 +5995,45 @@ RtlConvertUlongToLuid( #define RtlCopyBytes RtlCopyMemory #endif -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlCopyMemory32( IN VOID UNALIGNED *Destination, IN CONST VOID UNALIGNED *Source, IN ULONG Length); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlCopyString( IN OUT PSTRING DestinationString, IN PSTRING SourceString OPTIONAL); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlCopyUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PCUNICODE_STRING SourceString); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlCreateRegistryKey( IN ULONG RelativeTo, IN PWSTR Path); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlCreateSecurityDescriptor( IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Revision); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlDeleteRegistryValue( IN ULONG RelativeTo, IN PCWSTR Path, @@ -6053,17 +6058,17 @@ RtlDeleteRegistryValue( */ #define RtlEqualMemory(Destination, Source, Length) (!memcmp(Destination, Source, Length)) -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlEqualString( IN PSTRING String1, IN PSTRING String2, IN BOOLEAN CaseInSensitive); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlEqualUnicodeString( IN CONST UNICODE_STRING *String1, IN CONST UNICODE_STRING *String2, @@ -6085,178 +6090,178 @@ RtlEqualUnicodeString( #define RtlFillBytes RtlFillMemory #endif -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindClearBits( IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindClearBitsAndSet( IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindClearRuns( IN PRTL_BITMAP BitMapHeader, OUT PRTL_BITMAP_RUN RunArray, IN ULONG SizeOfRunArray, IN BOOLEAN LocateLongestRuns); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindFirstRunClear( IN PRTL_BITMAP BitMapHeader, OUT PULONG StartingIndex); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindLastBackwardRunClear( IN PRTL_BITMAP BitMapHeader, IN ULONG FromIndex, OUT PULONG StartingRunIndex); -NTOSAPI +NTSYSAPI CCHAR -DDKAPI +NTAPI RtlFindLeastSignificantBit( IN ULONGLONG Set); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindLongestRunClear( IN PRTL_BITMAP BitMapHeader, OUT PULONG StartingIndex); -NTOSAPI +NTSYSAPI CCHAR -DDKAPI +NTAPI RtlFindMostSignificantBit( IN ULONGLONG Set); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindNextForwardRunClear( IN PRTL_BITMAP BitMapHeader, IN ULONG FromIndex, OUT PULONG StartingRunIndex); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindSetBits( IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlFindSetBitsAndClear( IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlFreeAnsiString( IN PANSI_STRING AnsiString); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlFreeUnicodeString( IN PUNICODE_STRING UnicodeString); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlGetCallersAddress( OUT PVOID *CallersAddress, OUT PVOID *CallersCaller); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlGetVersion( IN OUT PRTL_OSVERSIONINFOW lpVersionInformation); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlGUIDFromString( IN PUNICODE_STRING GuidString, OUT GUID *Guid); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlHashUnicodeString( IN CONST UNICODE_STRING *String, IN BOOLEAN CaseInSensitive, IN ULONG HashAlgorithm, OUT PULONG HashValue); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlInitAnsiString( IN OUT PANSI_STRING DestinationString, IN PCSZ SourceString); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlInitializeBitMap( IN PRTL_BITMAP BitMapHeader, IN PULONG BitMapBuffer, IN ULONG SizeOfBitMap); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlInitString( IN OUT PSTRING DestinationString, IN PCSZ SourceString); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlInitUnicodeString( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlInt64ToUnicodeString( IN ULONGLONG Value, IN ULONG Base OPTIONAL, IN OUT PUNICODE_STRING String); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlIntegerToUnicodeString( IN ULONG Value, IN ULONG Base OPTIONAL, IN OUT PUNICODE_STRING String); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlIntPtrToUnicodeString( PLONG Value, ULONG Base OPTIONAL, @@ -6270,15 +6275,15 @@ RtlIntPtrToUnicodeString( #define RtlIsZeroLuid(_L1) \ ((BOOLEAN) ((!(_L1)->LowPart) && (!(_L1)->HighPart))) -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlLengthSecurityDescriptor( IN PSECURITY_DESCRIPTOR SecurityDescriptor); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlMapGenericMask( IN OUT PACCESS_MASK AccessMask, IN PGENERIC_MAPPING GenericMapping); @@ -6292,36 +6297,36 @@ RtlMapGenericMask( */ #define RtlMoveMemory memmove -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlNumberOfClearBits( IN PRTL_BITMAP BitMapHeader); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlNumberOfSetBits( IN PRTL_BITMAP BitMapHeader); -NTOSAPI +NTSYSAPI VOID -DDKFASTAPI +FASTCALL RtlPrefetchMemoryNonTemporal( IN PVOID Source, IN SIZE_T Length); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlPrefixUnicodeString( IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2, IN BOOLEAN CaseInSensitive); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlQueryRegistryValues( IN ULONG RelativeTo, IN PCWSTR Path, @@ -6353,95 +6358,95 @@ RtlQueryRegistryValues( *((PULONG)(DestAddress))=*((PULONG)(SrcAddress)); \ } -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlRetrieveUshort( IN OUT PUSHORT DestinationAddress, IN PUSHORT SourceAddress); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlSetAllBits( IN PRTL_BITMAP BitMapHeader); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlSetBit( PRTL_BITMAP BitMapHeader, ULONG BitNumber); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlSetBits( IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG NumberToSet); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlSetDaclSecurityDescriptor( IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN DaclPresent, IN PACL Dacl OPTIONAL, IN BOOLEAN DaclDefaulted OPTIONAL); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlStoreUlong( IN PULONG Address, IN ULONG Value); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlStoreUlonglong( IN OUT PULONGLONG Address, ULONGLONG Value); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlStoreUlongPtr( IN OUT PULONG_PTR Address, IN ULONG_PTR Value); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlStoreUshort( IN PUSHORT Address, IN USHORT Value); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlStringFromGUID( IN REFGUID Guid, OUT PUNICODE_STRING GuidString); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlTestBit( IN PRTL_BITMAP BitMapHeader, IN ULONG BitNumber); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlTimeFieldsToTime( IN PTIME_FIELDS TimeFields, IN PLARGE_INTEGER Time); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlTimeToTimeFields( IN PLARGE_INTEGER Time, IN PTIME_FIELDS TimeFields); @@ -6462,8 +6467,8 @@ RtlUlonglongByteSwap( ((STRING)->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR) \ ) -FORCEINLINE VOID +FORCEINLINE RtlInitEmptyUnicodeString(OUT PUNICODE_STRING UnicodeString, IN PWSTR Buffer, IN USHORT BufferSize) @@ -6473,45 +6478,56 @@ RtlInitEmptyUnicodeString(OUT PUNICODE_STRING UnicodeString, UnicodeString->Buffer = Buffer; } -NTOSAPI +VOID +FORCEINLINE +RtlInitEmptyAnsiString(OUT PANSI_STRING AnsiString, + IN PCHAR Buffer, + IN USHORT BufferSize) +{ + AnsiString->Length = 0; + AnsiString->MaximumLength = BufferSize; + AnsiString->Buffer = Buffer; +} + +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlUnicodeStringToAnsiString( IN OUT PANSI_STRING DestinationString, IN PCUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlUnicodeStringToInteger( IN PCUNICODE_STRING String, IN ULONG Base OPTIONAL, OUT PULONG Value); -NTOSAPI +NTSYSAPI WCHAR -DDKAPI +NTAPI RtlUpcaseUnicodeChar( IN WCHAR SourceCharacter); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlUpcaseUnicodeString( IN OUT PUNICODE_STRING DestinationString OPTIONAL, IN PCUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString); -NTOSAPI +NTSYSAPI CHAR -DDKAPI +NTAPI RtlUpperChar( IN CHAR Character); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI RtlUpperString( IN OUT PSTRING DestinationString, IN PSTRING SourceString); @@ -6521,46 +6537,46 @@ FASTCALL RtlUshortByteSwap( IN USHORT Source); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlValidRelativeSecurityDescriptor( IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, IN ULONG SecurityDescriptorLength, IN SECURITY_INFORMATION RequiredInformation); -NTOSAPI +NTSYSAPI BOOLEAN -DDKAPI +NTAPI RtlValidSecurityDescriptor( IN PSECURITY_DESCRIPTOR SecurityDescriptor); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlVerifyVersionInfo( IN PRTL_OSVERSIONINFOEXW VersionInfo, IN ULONG TypeMask, IN ULONGLONG ConditionMask); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlVolumeDeviceToDosName( IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlWalkFrameChain( OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI RtlWriteRegistryValue( IN ULONG RelativeTo, IN PCWSTR Path, @@ -6569,9 +6585,9 @@ RtlWriteRegistryValue( IN PVOID ValueData, IN ULONG ValueLength); -NTOSAPI +NTSYSAPI ULONG -DDKAPI +NTAPI RtlxUnicodeStringToAnsiSize( IN PCUNICODE_STRING UnicodeString); @@ -6593,48 +6609,56 @@ RtlxUnicodeStringToAnsiSize( /* Guarded Mutex routines */ +NTKERNELAPI VOID FASTCALL KeAcquireGuardedMutex( IN OUT PKGUARDED_MUTEX GuardedMutex ); +NTKERNELAPI VOID FASTCALL KeAcquireGuardedMutexUnsafe( IN OUT PKGUARDED_MUTEX GuardedMutex ); +NTKERNELAPI VOID NTAPI KeEnterGuardedRegion( VOID ); +NTKERNELAPI VOID NTAPI KeLeaveGuardedRegion( VOID ); +NTKERNELAPI VOID FASTCALL KeInitializeGuardedMutex( OUT PKGUARDED_MUTEX GuardedMutex ); +NTKERNELAPI VOID FASTCALL KeReleaseGuardedMutexUnsafe( IN OUT PKGUARDED_MUTEX GuardedMutex ); +NTKERNELAPI VOID FASTCALL KeReleaseGuardedMutex( IN OUT PKGUARDED_MUTEX GuardedMutex ); +NTKERNELAPI BOOLEAN FASTCALL KeTryToAcquireGuardedMutex( @@ -6650,28 +6674,28 @@ KeTryToAcquireGuardedMutex( KeInitializeEvent(&(_FastMutex)->Gate, SynchronizationEvent, FALSE); \ } -NTOSAPI +NTKERNELAPI VOID FASTCALL ExAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex); -NTOSAPI +NTKERNELAPI VOID FASTCALL ExReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex); #if defined(_NTHAL_) && defined(_X86_) -NTOSAPI +NTKERNELAPI VOID FASTCALL ExiAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); -NTOSAPI +NTKERNELAPI VOID FASTCALL ExiReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex); -NTOSAPI +NTKERNELAPI BOOLEAN FASTCALL ExiTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); @@ -6682,17 +6706,17 @@ ExiTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); #else -NTOSAPI +NTKERNELAPI VOID FASTCALL ExAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); -NTOSAPI +NTKERNELAPI VOID FASTCALL ExReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex); -NTOSAPI +NTKERNELAPI BOOLEAN FASTCALL ExTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); @@ -6700,30 +6724,30 @@ ExTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); /** Executive support routines **/ -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExAcquireResourceExclusiveLite( IN PERESOURCE Resource, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExAcquireResourceSharedLite( IN PERESOURCE Resource, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExAcquireSharedStarveExclusive( IN PERESOURCE Resource, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExAcquireSharedWaitForExclusive( IN PERESOURCE Resource, IN BOOLEAN Wait); @@ -6758,17 +6782,17 @@ ExAllocateFromPagedLookasideList( return Entry; } -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI ExAllocatePoolWithQuotaTag( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI ExAllocatePoolWithTag( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, @@ -6781,67 +6805,67 @@ ExAllocatePoolWithTag( #else /* !POOL_TAGGING */ -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI ExAllocatePool( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI ExAllocatePoolWithQuota( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes); #endif /* POOL_TAGGING */ -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI ExAllocatePoolWithTagPriority( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag, IN EX_POOL_PRIORITY Priority); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExConvertExclusiveToSharedLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ExCreateCallback( OUT PCALLBACK_OBJECT *CallbackObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN BOOLEAN Create, IN BOOLEAN AllowMultipleCallbacks); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExDeleteNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExDeletePagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ExDeleteResourceLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExFreePool( IN PVOID P); @@ -6851,9 +6875,9 @@ ExFreePool( #define ExFreePool(P) ExFreePoolWithTag(P, 0) #endif -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExFreePoolWithTag( IN PVOID P, IN ULONG Tag); @@ -6895,35 +6919,35 @@ ExFreeToPagedLookasideList( */ #define ExGetCurrentResourceThread() ((ERESOURCE_THREAD) PsGetCurrentThread()) -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI ExGetExclusiveWaiterCount( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI KPROCESSOR_MODE -DDKAPI +NTAPI ExGetPreviousMode( VOID); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI ExGetSharedWaiterCount( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeEvent( IN PRKEVENT Event, IN EVENT_TYPE Type, IN BOOLEAN State); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExInitializeNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, @@ -6933,9 +6957,9 @@ ExInitializeNPagedLookasideList( IN ULONG Tag, IN USHORT Depth); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExInitializePagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, @@ -6945,9 +6969,9 @@ ExInitializePagedLookasideList( IN ULONG Tag, IN USHORT Depth); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ExInitializeResourceLite( IN PERESOURCE Resource); @@ -6961,71 +6985,71 @@ ExInitializeResourceLite( #define ExInitializeSListHead InitializeSListHead -NTOSAPI +NTKERNELAPI LARGE_INTEGER -DDKAPI +NTAPI ExInterlockedAddLargeInteger( IN PLARGE_INTEGER Addend, IN LARGE_INTEGER Increment, IN PKSPIN_LOCK Lock); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL ExInterlockedAddLargeStatistic( IN PLARGE_INTEGER Addend, IN ULONG Increment); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI ExInterlockedAddUlong( IN PULONG Addend, IN ULONG Increment, PKSPIN_LOCK Lock); -NTOSAPI +NTKERNELAPI LONGLONG -DDKFASTAPI +FASTCALL ExInterlockedCompareExchange64( IN OUT PLONGLONG Destination, IN PLONGLONG Exchange, IN PLONGLONG Comparand, IN PKSPIN_LOCK Lock); -NTOSAPI +NTKERNELAPI LONGLONG -DDKFASTAPI +FASTCALL ExfInterlockedCompareExchange64( IN OUT LONGLONG volatile *Destination, IN PLONGLONG Exchange, IN PLONGLONG Comperand); -NTOSAPI +NTKERNELAPI PSINGLE_LIST_ENTRY -DDKFASTAPI +FASTCALL ExInterlockedFlushSList( IN PSLIST_HEADER ListHead); -NTOSAPI +NTKERNELAPI PLIST_ENTRY -DDKAPI +NTAPI ExInterlockedInsertHeadList( IN PLIST_ENTRY ListHead, IN PLIST_ENTRY ListEntry, IN PKSPIN_LOCK Lock); -NTOSAPI +NTKERNELAPI PLIST_ENTRY -DDKAPI +NTAPI ExInterlockedInsertTailList( IN PLIST_ENTRY ListHead, IN PLIST_ENTRY ListEntry, IN PKSPIN_LOCK Lock); -NTOSAPI +NTKERNELAPI PSINGLE_LIST_ENTRY -DDKAPI +NTAPI ExInterlockedPopEntryList( IN PSINGLE_LIST_ENTRY ListHead, IN PKSPIN_LOCK Lock); @@ -7040,9 +7064,9 @@ ExInterlockedPopEntryList( _Lock) \ InterlockedPopEntrySList(_ListHead) -NTOSAPI +NTKERNELAPI PSINGLE_LIST_ENTRY -DDKAPI +NTAPI ExInterlockedPushEntryList( IN PSINGLE_LIST_ENTRY ListHead, IN PSINGLE_LIST_ENTRY ListEntry, @@ -7060,139 +7084,139 @@ ExInterlockedPushEntryList( _Lock) \ InterlockedPushEntrySList(_ListHead, _ListEntry) -NTOSAPI +NTKERNELAPI PLIST_ENTRY -DDKAPI +NTAPI ExInterlockedRemoveHeadList( IN PLIST_ENTRY ListHead, IN PKSPIN_LOCK Lock); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExIsProcessorFeaturePresent( IN ULONG ProcessorFeature); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExIsResourceAcquiredExclusiveLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI USHORT -DDKAPI +NTAPI ExIsResourceAcquiredLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI ExIsResourceAcquiredSharedLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExLocalTimeToSystemTime( IN PLARGE_INTEGER LocalTime, OUT PLARGE_INTEGER SystemTime); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExNotifyCallback( IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExRaiseAccessViolation( VOID); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExRaiseDatatypeMisalignment( VOID); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExRaiseStatus( IN NTSTATUS Status); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI ExRegisterCallback( IN PCALLBACK_OBJECT CallbackObject, IN PCALLBACK_FUNCTION CallbackFunction, IN PVOID CallbackContext); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ExReinitializeResourceLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExReleaseResourceForThreadLite( IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL ExReleaseResourceLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExSetResourceOwnerPointer( IN PERESOURCE Resource, IN PVOID OwnerPointer); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI ExSetTimerResolution( IN ULONG DesiredTime, IN BOOLEAN SetResolution); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExSystemTimeToLocalTime( IN PLARGE_INTEGER SystemTime, OUT PLARGE_INTEGER LocalTime); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExTryToAcquireResourceExclusiveLite( IN PERESOURCE Resource); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ExUnregisterCallback( IN PVOID CbRegistration); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ExUuidCreate( OUT UUID *Uuid); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI ExVerifySuite( IN SUITE_TYPE SuiteType); @@ -7211,17 +7235,17 @@ ExVerifySuite( #endif -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ProbeForRead( IN CONST VOID *Address, IN ULONG Length, IN ULONG Alignment); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ProbeForWrite( IN PVOID Address, IN ULONG Length, @@ -7231,17 +7255,17 @@ ProbeForWrite( /** Configuration manager routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI CmRegisterCallback( IN PEX_CALLBACK_FUNCTION Function, IN PVOID Context, IN OUT PLARGE_INTEGER Cookie); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI CmUnRegisterCallback( IN LARGE_INTEGER Cookie); @@ -7249,9 +7273,9 @@ CmUnRegisterCallback( /** Filesystem runtime library routines **/ -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI FsRtlIsTotalDeviceFailure( IN NTSTATUS Status); @@ -7261,13 +7285,13 @@ FsRtlIsTotalDeviceFailure( NTHALAPI BOOLEAN -DDKAPI +NTAPI HalMakeBeep( IN ULONG Frequency); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL HalExamineMBR( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, @@ -7293,7 +7317,7 @@ IoAllocateAdapterChannel( NTHALAPI VOID -DDKAPI +NTAPI READ_PORT_BUFFER_UCHAR( IN PUCHAR Port, IN PUCHAR Buffer, @@ -7301,7 +7325,7 @@ READ_PORT_BUFFER_UCHAR( NTHALAPI VOID -DDKAPI +NTAPI READ_PORT_BUFFER_ULONG( IN PULONG Port, IN PULONG Buffer, @@ -7309,7 +7333,7 @@ READ_PORT_BUFFER_ULONG( NTHALAPI VOID -DDKAPI +NTAPI READ_PORT_BUFFER_USHORT( IN PUSHORT Port, IN PUSHORT Buffer, @@ -7317,67 +7341,67 @@ READ_PORT_BUFFER_USHORT( NTHALAPI UCHAR -DDKAPI +NTAPI READ_PORT_UCHAR( IN PUCHAR Port); NTHALAPI ULONG -DDKAPI +NTAPI READ_PORT_ULONG( IN PULONG Port); NTHALAPI USHORT -DDKAPI +NTAPI READ_PORT_USHORT( IN PUSHORT Port); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI READ_REGISTER_BUFFER_UCHAR( IN PUCHAR Register, IN PUCHAR Buffer, IN ULONG Count); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI READ_REGISTER_BUFFER_ULONG( IN PULONG Register, IN PULONG Buffer, IN ULONG Count); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI READ_REGISTER_BUFFER_USHORT( IN PUSHORT Register, IN PUSHORT Buffer, IN ULONG Count); -NTOSAPI +NTKERNELAPI UCHAR -DDKAPI +NTAPI READ_REGISTER_UCHAR( IN PUCHAR Register); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI READ_REGISTER_ULONG( IN PULONG Register); -NTOSAPI +NTKERNELAPI USHORT -DDKAPI +NTAPI READ_REGISTER_USHORT( IN PUSHORT Register); NTHALAPI VOID -DDKAPI +NTAPI WRITE_PORT_BUFFER_UCHAR( IN PUCHAR Port, IN PUCHAR Buffer, @@ -7385,7 +7409,7 @@ WRITE_PORT_BUFFER_UCHAR( NTHALAPI VOID -DDKAPI +NTAPI WRITE_PORT_BUFFER_ULONG( IN PULONG Port, IN PULONG Buffer, @@ -7393,7 +7417,7 @@ WRITE_PORT_BUFFER_ULONG( NTHALAPI VOID -DDKAPI +NTAPI WRITE_PORT_BUFFER_USHORT( IN PUSHORT Port, IN PUSHORT Buffer, @@ -7401,81 +7425,81 @@ WRITE_PORT_BUFFER_USHORT( NTHALAPI VOID -DDKAPI +NTAPI WRITE_PORT_UCHAR( IN PUCHAR Port, IN UCHAR Value); NTHALAPI VOID -DDKAPI +NTAPI WRITE_PORT_ULONG( IN PULONG Port, IN ULONG Value); NTHALAPI VOID -DDKAPI +NTAPI WRITE_PORT_USHORT( IN PUSHORT Port, IN USHORT Value); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI WRITE_REGISTER_BUFFER_UCHAR( IN PUCHAR Register, IN PUCHAR Buffer, IN ULONG Count); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI WRITE_REGISTER_BUFFER_ULONG( IN PULONG Register, IN PULONG Buffer, IN ULONG Count); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI WRITE_REGISTER_BUFFER_USHORT( IN PUSHORT Register, IN PUSHORT Buffer, IN ULONG Count); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI WRITE_REGISTER_UCHAR( IN PUCHAR Register, IN UCHAR Value); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI WRITE_REGISTER_ULONG( IN PULONG Register, IN ULONG Value); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI WRITE_REGISTER_USHORT( IN PUSHORT Register, IN USHORT Value); /** I/O manager routines **/ -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoAcquireCancelSpinLock( OUT PKIRQL Irql); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoAcquireRemoveLockEx( IN PIO_REMOVE_LOCK RemoveLock, IN OPTIONAL PVOID Tag OPTIONAL, @@ -7512,41 +7536,41 @@ IoAcquireRemoveLockEx( } \ } -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoAllocateController( IN PCONTROLLER_OBJECT ControllerObject, IN PDEVICE_OBJECT DeviceObject, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoAllocateDriverObjectExtension( IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI IoAllocateErrorLogEntry( IN PVOID IoObject, IN UCHAR EntrySize); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoAllocateIrp( IN CCHAR StackSize, IN BOOLEAN ChargeQuota); -NTOSAPI +NTKERNELAPI PMDL -DDKAPI +NTAPI IoAllocateMdl( IN PVOID VirtualAddress, IN ULONG Length, @@ -7554,9 +7578,9 @@ IoAllocateMdl( IN BOOLEAN ChargeQuota, IN OUT PIRP Irp OPTIONAL); -NTOSAPI +NTKERNELAPI PIO_WORKITEM -DDKAPI +NTAPI IoAllocateWorkItem( IN PDEVICE_OBJECT DeviceObject); @@ -7568,24 +7592,24 @@ IoAllocateWorkItem( #define IoAssignArcName(_ArcName, _DeviceName) ( \ IoCreateSymbolicLink((_ArcName), (_DeviceName))) -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoAttachDevice( IN PDEVICE_OBJECT SourceDevice, IN PUNICODE_STRING TargetDevice, OUT PDEVICE_OBJECT *AttachedDevice); -NTOSAPI +NTKERNELAPI PDEVICE_OBJECT -DDKAPI +NTAPI IoAttachDeviceToDeviceStack( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoBuildAsynchronousFsdRequest( IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, @@ -7594,9 +7618,9 @@ IoBuildAsynchronousFsdRequest( IN PLARGE_INTEGER StartingOffset OPTIONAL, IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoBuildDeviceIoControlRequest( IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, @@ -7608,18 +7632,18 @@ IoBuildDeviceIoControlRequest( IN PKEVENT Event, OUT PIO_STATUS_BLOCK IoStatusBlock); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoBuildPartialMdl( IN PMDL SourceMdl, IN OUT PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoBuildSynchronousFsdRequest( IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, @@ -7629,9 +7653,9 @@ IoBuildSynchronousFsdRequest( IN PKEVENT Event, OUT PIO_STATUS_BLOCK IoStatusBlock); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKFASTAPI +FASTCALL IofCallDriver( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); @@ -7644,22 +7668,22 @@ IofCallDriver( */ #define IoCallDriver IofCallDriver -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoCancelFileOpen( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI IoCancelIrp( IN PIRP Irp); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCheckShareAccess( IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, @@ -7667,9 +7691,9 @@ IoCheckShareAccess( IN OUT PSHARE_ACCESS ShareAccess, IN BOOLEAN Update); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL IofCompleteRequest( IN PIRP Irp, IN CCHAR PriorityBoost); @@ -7682,9 +7706,9 @@ IofCompleteRequest( */ #define IoCompleteRequest IofCompleteRequest -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoConnectInterrupt( OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, @@ -7730,15 +7754,15 @@ IoConnectInterrupt( _NextIrpSp->Control = 0; \ } -NTOSAPI +NTKERNELAPI PCONTROLLER_OBJECT -DDKAPI +NTAPI IoCreateController( IN ULONG Size); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCreateDevice( IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, @@ -7748,16 +7772,16 @@ IoCreateDevice( IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCreateDisk( IN PDEVICE_OBJECT DeviceObject, IN PCREATE_DISK Disk); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, @@ -7774,37 +7798,37 @@ IoCreateFile( IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options); -NTOSAPI +NTKERNELAPI PKEVENT -DDKAPI +NTAPI IoCreateNotificationEvent( IN PUNICODE_STRING EventName, OUT PHANDLE EventHandle); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCreateSymbolicLink( IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName); -NTOSAPI +NTKERNELAPI PKEVENT -DDKAPI +NTAPI IoCreateSynchronizationEvent( IN PUNICODE_STRING EventName, OUT PHANDLE EventHandle); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCreateUnprotectedSymbolicLink( IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoCsqInitialize( PIO_CSQ Csq, IN PIO_CSQ_INSERT_IRP CsqInsertIrp, @@ -7814,43 +7838,43 @@ IoCsqInitialize( IN PIO_CSQ_RELEASE_LOCK CsqReleaseLock, IN PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoCsqInsertIrp( IN PIO_CSQ Csq, IN PIRP Irp, IN PIO_CSQ_IRP_CONTEXT Context); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoCsqRemoveIrp( IN PIO_CSQ Csq, IN PIO_CSQ_IRP_CONTEXT Context); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoCsqRemoveNextIrp( IN PIO_CSQ Csq, IN PVOID PeekContext); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoDeleteController( IN PCONTROLLER_OBJECT ControllerObject); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoDeleteDevice( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoDeleteSymbolicLink( IN PUNICODE_STRING SymbolicLinkName); @@ -7861,91 +7885,91 @@ IoDeleteSymbolicLink( */ #define IoDeassignArcName IoDeleteSymbolicLink -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoDetachDevice( IN OUT PDEVICE_OBJECT TargetDevice); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoDisconnectInterrupt( IN PKINTERRUPT InterruptObject); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI IoForwardIrpSynchronously( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); #define IoForwardAndCatchIrp IoForwardIrpSynchronously -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoFreeController( IN PCONTROLLER_OBJECT ControllerObject); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoFreeErrorLogEntry( PVOID ElEntry); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoFreeIrp( IN PIRP Irp); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoFreeMdl( IN PMDL Mdl); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoFreeWorkItem( IN PIO_WORKITEM pIOWorkItem); -NTOSAPI +NTKERNELAPI PDEVICE_OBJECT -DDKAPI +NTAPI IoGetAttachedDevice( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI PDEVICE_OBJECT -DDKAPI +NTAPI IoGetAttachedDeviceReference( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoGetBootDiskInformation( IN OUT PBOOTDISK_INFORMATION BootDiskInformation, IN ULONG Size); -NTOSAPI +NTKERNELAPI PCONFIGURATION_INFORMATION -DDKAPI +NTAPI IoGetConfigurationInformation( VOID); -NTOSAPI +NTKERNELAPI PEPROCESS -DDKAPI +NTAPI IoGetCurrentProcess( VOID); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoGetDeviceInterfaceAlias( IN PUNICODE_STRING SymbolicLinkName, IN CONST GUID *AliasInterfaceClassGuid, @@ -7953,27 +7977,27 @@ IoGetDeviceInterfaceAlias( #define DEVICE_INTERFACE_INCLUDE_NONACTIVE 0x00000001 -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoGetDeviceInterfaces( IN CONST GUID *InterfaceClassGuid, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN ULONG Flags, OUT PWSTR *SymbolicLinkList); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoGetDeviceObjectPointer( IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoGetDeviceProperty( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, @@ -7981,30 +8005,30 @@ IoGetDeviceProperty( OUT PVOID PropertyBuffer, OUT PULONG ResultLength); -NTOSAPI +NTKERNELAPI PDEVICE_OBJECT -DDKAPI +NTAPI IoGetDeviceToVerify( IN PETHREAD Thread); -NTOSAPI +NTKERNELAPI PDMA_ADAPTER -DDKAPI +NTAPI IoGetDmaAdapter( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_DESCRIPTION DeviceDescription, IN OUT PULONG NumberOfMapRegisters); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI IoGetDriverObjectExtension( IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress); -NTOSAPI +NTKERNELAPI PGENERIC_MAPPING -DDKAPI +NTAPI IoGetFileObjectGenericMapping( VOID); @@ -8016,34 +8040,34 @@ IoGetFileObjectGenericMapping( #define IoGetFunctionCodeFromCtlCode(_ControlCode) \ (((_ControlCode) >> 2) & 0x00000FFF) -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI IoGetInitialStack( VOID); -NTOSAPI +NTKERNELAPI PDEVICE_OBJECT -DDKAPI +NTAPI IoGetRelatedDeviceObject( IN PFILE_OBJECT FileObject); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI IoGetRemainingStackSize( VOID); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoGetStackLimits( OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeDpc( IN PRKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, @@ -8061,17 +8085,17 @@ KeInitializeDpc( (PKDEFERRED_ROUTINE) (_DpcRoutine), \ _DeviceObject) -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoInitializeIrp( IN OUT PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoInitializeRemoveLockEx( IN PIO_REMOVE_LOCK Lock, IN ULONG AllocateTag, @@ -8091,30 +8115,30 @@ IoInitializeRemoveLockEx( IoInitializeRemoveLockEx(Lock, AllocateTag, MaxLockedMinutes, \ HighWatermark, sizeof(IO_REMOVE_LOCK)) -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoInitializeTimer( IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoInvalidateDeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoInvalidateDeviceState( IN PDEVICE_OBJECT PhysicalDeviceObject); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI IoIs32bitProcess( IN PIRP Irp OPTIONAL); @@ -8132,16 +8156,16 @@ IoIs32bitProcess( ((Status) == STATUS_UNRECOGNIZED_MEDIA) || \ ((Status) == STATUS_WRONG_VOLUME))) -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI IoIsWdmVersionAvailable( IN UCHAR MajorVersion, IN UCHAR MinorVersion); -NTOSAPI +NTKERNELAPI PIRP -DDKAPI +NTAPI IoMakeAssociatedIrp( IN PIRP Irp, IN CCHAR StackSize); @@ -8154,9 +8178,9 @@ IoMakeAssociatedIrp( #define IoMarkIrpPending(_Irp) \ (IoGetCurrentIrpStackLocation(_Irp)->Control |= SL_PENDING_RETURNED) -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoOpenDeviceInterfaceRegistryKey( IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, @@ -8166,18 +8190,18 @@ IoOpenDeviceInterfaceRegistryKey( #define PLUGPLAY_REGKEY_DRIVER 2 #define PLUGPLAY_REGKEY_CURRENT_HWPROFILE 4 -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoOpenDeviceRegistryKey( IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoQueryDeviceDescription( IN PINTERFACE_TYPE BusType OPTIONAL, IN PULONG BusNumber OPTIONAL, @@ -8188,82 +8212,82 @@ IoQueryDeviceDescription( IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, IN PVOID Context); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoQueueWorkItem( IN PIO_WORKITEM pIOWorkItem, IN PIO_WORKITEM_ROUTINE Routine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoRaiseHardError( IN PIRP Irp, IN PVPB Vpb OPTIONAL, IN PDEVICE_OBJECT RealDeviceObject); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI IoRaiseInformationalHardError( IN NTSTATUS ErrorStatus, IN PUNICODE_STRING String OPTIONAL, IN PKTHREAD Thread OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReadDiskSignature( IN PDEVICE_OBJECT DeviceObject, IN ULONG BytesPerSector, OUT PDISK_SIGNATURE Signature); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReadPartitionTableEx( IN PDEVICE_OBJECT DeviceObject, IN struct _DRIVE_LAYOUT_INFORMATION_EX **PartitionBuffer); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoRegisterBootDriverReinitialization( IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, IN PVOID Context); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoRegisterBootDriverReinitialization( IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, IN PVOID Context); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoRegisterDeviceInterface( IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoRegisterDriverReinitialization( IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, IN PVOID Context); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoRegisterPlugPlayNotification( IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN ULONG EventCategoryFlags, @@ -8273,29 +8297,29 @@ IoRegisterPlugPlayNotification( IN PVOID Context, OUT PVOID *NotificationEntry); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoRegisterShutdownNotification( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoReleaseCancelSpinLock( IN KIRQL Irql); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoReleaseRemoveLockAndWaitEx( IN PIO_REMOVE_LOCK RemoveLock, IN PVOID Tag, IN ULONG RemlockSize); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoReleaseRemoveLockEx( IN PIO_REMOVE_LOCK RemoveLock, IN PVOID Tag, @@ -8321,16 +8345,16 @@ IoReleaseRemoveLockEx( _Tag) \ IoReleaseRemoveLockAndWaitEx(_RemoveLock, _Tag, sizeof(IO_REMOVE_LOCK)) -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoRemoveShareAccess( IN PFILE_OBJECT FileObject, IN OUT PSHARE_ACCESS ShareAccess); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReportDetectedDevice( IN PDRIVER_OBJECT DriverObject, IN INTERFACE_TYPE LegacyBusType, @@ -8341,9 +8365,9 @@ IoReportDetectedDevice( IN BOOLEAN ResourceAssigned, IN OUT PDEVICE_OBJECT *DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReportResourceForDetection( IN PDRIVER_OBJECT DriverObject, IN PCM_RESOURCE_LIST DriverList OPTIONAL, @@ -8353,9 +8377,9 @@ IoReportResourceForDetection( IN ULONG DeviceListSize OPTIONAL, OUT PBOOLEAN ConflictDetected); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReportResourceUsage( IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, @@ -8367,25 +8391,25 @@ IoReportResourceUsage( IN BOOLEAN OverrideConflict, OUT PBOOLEAN ConflictDetected); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReportTargetDeviceChange( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoReportTargetDeviceChangeAsynchronous( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoRequestDeviceEject( IN PDEVICE_OBJECT PhysicalDeviceObject); @@ -8399,9 +8423,9 @@ IoRequestDeviceEject( #define IoRequestDpc(DeviceObject, Irp, Context)( \ KeInsertQueueDpc(&(DeviceObject)->Dpc, (Irp), (Context))) -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoReuseIrp( IN OUT PIRP Irp, IN NTSTATUS Status); @@ -8446,9 +8470,9 @@ IoReuseIrp( if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \ } -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoSetCompletionRoutineEx( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, @@ -8458,16 +8482,16 @@ IoSetCompletionRoutineEx( IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoSetDeviceInterfaceState( IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoSetHardErrorOrVerifyDevice( IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject); @@ -8483,40 +8507,40 @@ IoSetHardErrorOrVerifyDevice( (_Irp)->Tail.Overlay.CurrentStackLocation--; \ } -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoSetPartitionInformationEx( IN PDEVICE_OBJECT DeviceObject, IN ULONG PartitionNumber, IN struct _SET_PARTITION_INFORMATION_EX *PartitionInfo); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoSetShareAccess( IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN OUT PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoSetStartIoAttributes( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoSetSystemPartition( IN PUNICODE_STRING VolumeNameString); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI IoSetThreadHardErrorMode( IN BOOLEAN EnableHardErrors); @@ -8539,100 +8563,100 @@ IoSetThreadHardErrorMode( (_Irp)->Tail.Overlay.CurrentStackLocation++; \ } -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoStartNextPacket( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoStartNextPacketByKey( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable, IN ULONG Key); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoStartPacket( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key OPTIONAL, IN PDRIVER_CANCEL CancelFunction OPTIONAL); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoStartTimer( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoStopTimer( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoUnregisterPlugPlayNotification( IN PVOID NotificationEntry); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoUnregisterShutdownNotification( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoUpdateShareAccess( IN PFILE_OBJECT FileObject, IN OUT PSHARE_ACCESS ShareAccess); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoVerifyPartitionTable( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN FixErrors); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoVolumeDeviceToDosName( IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIAllocateInstanceIds( IN GUID *Guid, IN ULONG InstanceCount, OUT ULONG *FirstInstanceId); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI IoWMIDeviceObjectToProviderId( IN PDEVICE_OBJECT DeviceObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIDeviceObjectToInstanceName( IN PVOID DataBlockObject, IN PDEVICE_OBJECT DeviceObject, OUT PUNICODE_STRING InstanceName); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIExecuteMethod( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, @@ -8641,51 +8665,51 @@ IoWMIExecuteMethod( IN OUT PULONG OutBufferSize, IN OUT PUCHAR InOutBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIHandleToInstanceName( IN PVOID DataBlockObject, IN HANDLE FileHandle, OUT PUNICODE_STRING InstanceName); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIOpenBlock( IN GUID *DataBlockGuid, IN ULONG DesiredAccess, OUT PVOID *DataBlockObject); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIQueryAllData( IN PVOID DataBlockObject, IN OUT ULONG *InOutBufferSize, OUT PVOID OutBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIQueryAllDataMultiple( IN PVOID *DataBlockObjectList, IN ULONG ObjectCount, IN OUT ULONG *InOutBufferSize, OUT PVOID OutBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIQuerySingleInstance( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, IN OUT ULONG *InOutBufferSize, OUT PVOID OutBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIQuerySingleInstanceMultiple( IN PVOID *DataBlockObjectList, IN PUNICODE_STRING InstanceNames, @@ -8693,24 +8717,24 @@ IoWMIQuerySingleInstanceMultiple( IN OUT ULONG *InOutBufferSize, OUT PVOID OutBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIRegistrationControl( IN PDEVICE_OBJECT DeviceObject, IN ULONG Action); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMISetNotificationCallback( IN PVOID Object, IN WMI_NOTIFICATION_CALLBACK Callback, IN PVOID Context); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMISetSingleInstance( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, @@ -8718,9 +8742,9 @@ IoWMISetSingleInstance( IN ULONG ValueBufferSize, IN PVOID ValueBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMISetSingleItem( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, @@ -8729,30 +8753,30 @@ IoWMISetSingleItem( IN ULONG ValueBufferSize, IN PVOID ValueBuffer); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMISuggestInstanceName( IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN PUNICODE_STRING SymbolicLinkName OPTIONAL, IN BOOLEAN CombineNames, OUT PUNICODE_STRING SuggestedInstanceName); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWMIWriteEvent( IN PVOID WnodeEventItem); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI IoWriteErrorLogEntry( IN PVOID ElEntry); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI IoWritePartitionTableEx( IN PDEVICE_OBJECT DeviceObject, IN struct _DRIVE_LAYOUT_INFORMATION_EX *PartitionBuffer); @@ -8763,39 +8787,39 @@ IoWritePartitionTableEx( NTHALAPI VOID -DDKFASTAPI +FASTCALL KeAcquireInStackQueuedSpinLock( IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel( IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle); -NTOSAPI +NTKERNELAPI KIRQL -DDKAPI +NTAPI KeAcquireInterruptSpinLock( IN PKINTERRUPT Interrupt); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeAreApcsDisabled( VOID); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeBugCheck( IN ULONG BugCheckCode); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeBugCheckEx( IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, @@ -8803,35 +8827,35 @@ KeBugCheckEx( IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeCancelTimer( IN PKTIMER Timer); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeClearEvent( IN PRKEVENT Event); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KeDelayExecutionThread( IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeDeregisterBugCheckCallback( IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeEnterCriticalRegion( VOID); @@ -8846,93 +8870,87 @@ KeEnterCriticalRegion( NTHALAPI VOID -DDKAPI +NTAPI KeFlushWriteBuffer(VOID); -NTOSAPI +NTKERNELAPI PRKTHREAD -DDKAPI +NTAPI KeGetCurrentThread( VOID); -NTOSAPI -KPROCESSOR_MODE -DDKAPI -KeGetPreviousMode( - VOID); - -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI KeGetRecommendedSharedDataAlignment( VOID); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeMutex( IN PRKMUTEX Mutex, IN ULONG Level); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeSemaphore( IN PRKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeSpinLock( IN PKSPIN_LOCK SpinLock); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeTimer( IN PKTIMER Timer); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeInitializeTimerEx( IN PKTIMER Timer, IN TIMER_TYPE Type); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeInsertByKeyDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN ULONG SortKey); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeInsertDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeInsertQueueDpc( IN PRKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeLeaveCriticalRegion( VOID); @@ -8962,78 +8980,78 @@ KeMemoryBarrier( #endif -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KePulseEvent( IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI ULONGLONG -DDKAPI +NTAPI KeQueryInterruptTime( VOID); NTHALAPI LARGE_INTEGER -DDKAPI +NTAPI KeQueryPerformanceCounter( OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL); -NTOSAPI +NTKERNELAPI KPRIORITY -DDKAPI +NTAPI KeQueryPriorityThread( IN PRKTHREAD Thread); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeQuerySystemTime( OUT PLARGE_INTEGER CurrentTime); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeQueryTickCount( OUT PLARGE_INTEGER TickCount); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI KeQueryTimeIncrement( VOID); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeReadStateEvent( IN PRKEVENT Event); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeReadStateMutex( IN PRKMUTEX Mutex); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeReadStateSemaphore( IN PRKSEMAPHORE Semaphore); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeReadStateTimer( IN PKTIMER Timer); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeRegisterBugCheckCallback( IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord, IN PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, @@ -9043,170 +9061,170 @@ KeRegisterBugCheckCallback( NTHALAPI VOID -DDKFASTAPI +FASTCALL KeReleaseInStackQueuedSpinLock( IN PKLOCK_QUEUE_HANDLE LockHandle); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel( IN PKLOCK_QUEUE_HANDLE LockHandle); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeReleaseInterruptSpinLock( IN PKINTERRUPT Interrupt, IN KIRQL OldIrql); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeReleaseMutex( IN PRKMUTEX Mutex, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeReleaseSemaphore( IN PRKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI PKDEVICE_QUEUE_ENTRY -DDKAPI +NTAPI KeRemoveByKeyDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey); -NTOSAPI +NTKERNELAPI PKDEVICE_QUEUE_ENTRY -DDKAPI +NTAPI KeRemoveDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeRemoveEntryDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeRemoveQueueDpc( IN PRKDPC Dpc); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeResetEvent( IN PRKEVENT Event); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KeRestoreFloatingPointState( IN PKFLOATING_SAVE FloatSave); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeRevertToUserAffinityThread(VOID); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KeSaveFloatingPointState( OUT PKFLOATING_SAVE FloatSave); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeSetBasePriorityThread( IN PRKTHREAD Thread, IN LONG Increment); -NTOSAPI +NTKERNELAPI LONG -DDKAPI +NTAPI KeSetEvent( IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeSetImportanceDpc( IN PRKDPC Dpc, IN KDPC_IMPORTANCE Importance); -NTOSAPI +NTKERNELAPI KPRIORITY -DDKAPI +NTAPI KeSetPriorityThread( IN PKTHREAD Thread, IN KPRIORITY Priority); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeSetSystemAffinityThread( IN KAFFINITY Affinity); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeSetTargetProcessorDpc( IN PRKDPC Dpc, IN CCHAR Number); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeSetTimer( IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeSetTimerEx( IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period OPTIONAL, IN PKDPC Dpc OPTIONAL); -NTOSAPI +NTKERNELAPI VOID -DDKFASTAPI +FASTCALL KeSetTimeUpdateNotifyRoutine( IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine); NTHALAPI VOID -DDKAPI +NTAPI KeStallExecutionProcessor( IN ULONG MicroSeconds); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI KeSynchronizeExecution( IN PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KeWaitForMultipleObjects( IN ULONG Count, IN PVOID Object[], @@ -9217,9 +9235,9 @@ KeWaitForMultipleObjects( IN PLARGE_INTEGER Timeout OPTIONAL, IN PKWAIT_BLOCK WaitBlockArray OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KeWaitForMutexObject( IN PRKMUTEX Mutex, IN KWAIT_REASON WaitReason, @@ -9227,9 +9245,9 @@ KeWaitForMutexObject( IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KeWaitForSingleObject( IN PVOID Object, IN KWAIT_REASON WaitReason, @@ -9311,45 +9329,49 @@ KeRaiseIrqlToSynchLevel( #else -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI KeLowerIrql( IN KIRQL NewIrql); -NTOSAPI +NTKERNELAPI KIRQL -DDKAPI +NTAPI KeRaiseIrql( IN KIRQL NewIrql); -NTOSAPI +NTKERNELAPI KIRQL -DDKAPI +NTAPI KeRaiseIrqlToDpcLevel( VOID); +#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b) +#define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a) +#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a) + #endif /** Memory manager routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmAdvanceMdl( IN PMDL Mdl, IN ULONG NumberOfBytes); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmAllocateContiguousMemory( IN ULONG NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmAllocateContiguousMemorySpecifyCache( IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress, @@ -9357,37 +9379,37 @@ MmAllocateContiguousMemorySpecifyCache( IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmAllocateMappingAddress( IN SIZE_T NumberOfBytes, IN ULONG PoolTag); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmAllocateNonCachedMemory( IN ULONG NumberOfBytes); -NTOSAPI +NTKERNELAPI PMDL -DDKAPI +NTAPI MmAllocatePagesForMdl( IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmBuildMdlForNonPagedPool( IN OUT PMDL MemoryDescriptorList); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmCreateSection( OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, @@ -9403,44 +9425,44 @@ typedef enum _MMFLUSH_TYPE { MmFlushForWrite } MMFLUSH_TYPE; -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI MmFlushImageSection( IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmFreeContiguousMemory( IN PVOID BaseAddress); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmFreeContiguousMemorySpecifyCache( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmFreeMappingAddress( IN PVOID BaseAddress, IN ULONG PoolTag); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmFreeNonCachedMemory( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmFreePagesFromMdl( IN PMDL MemoryDescriptorList); @@ -9476,27 +9498,27 @@ MmFreePagesFromMdl( #define MmGetMdlVirtualAddress(_Mdl) \ ((PVOID) ((PCHAR) ((_Mdl)->StartVa) + (_Mdl)->ByteOffset)) -NTOSAPI +NTKERNELAPI PHYSICAL_ADDRESS -DDKAPI +NTAPI MmGetPhysicalAddress( IN PVOID BaseAddress); -NTOSAPI +NTKERNELAPI PPHYSICAL_MEMORY_RANGE -DDKAPI +NTAPI MmGetPhysicalMemoryRanges( VOID); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmGetVirtualForPhysical( IN PHYSICAL_ADDRESS PhysicalAddress); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmMapLockedPagesSpecifyCache( IN PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode, @@ -9505,57 +9527,57 @@ MmMapLockedPagesSpecifyCache( IN ULONG BugCheckOnFailure, IN MM_PAGE_PRIORITY Priority); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmMapLockedPagesWithReservedMapping( IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmMapUserAddressesToPage( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN PVOID PageAddress); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmMapVideoDisplay( IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmMapViewInSessionSpace( IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmMapViewInSystemSpace( IN PVOID Section, OUT PVOID *MappedBase, IN PSIZE_T ViewSize); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmMarkPhysicalMemoryAsBad( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmMarkPhysicalMemoryAsGood( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes); @@ -9573,9 +9595,9 @@ MmMarkPhysicalMemoryAsGood( (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \ KernelMode, MmCached, NULL, FALSE, _Priority) -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmGetSystemRoutineAddress( IN PUNICODE_STRING SystemRoutineName); @@ -9610,39 +9632,39 @@ MmGetSystemRoutineAddress( (_MemoryDescriptorList)->ByteCount = (ULONG) _Length; \ } -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI MmIsAddressValid( IN PVOID VirtualAddress); -NTOSAPI +NTKERNELAPI LOGICAL -DDKAPI +NTAPI MmIsDriverVerifying( IN PDRIVER_OBJECT DriverObject); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI MmIsThisAnNtAsSystem( VOID); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmIsVerifierEnabled( OUT PULONG VerifierFlags); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmLockPagableDataSection( IN PVOID AddressWithinSection); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmLockPagableImageSection( IN PVOID AddressWithinSection); @@ -9653,71 +9675,71 @@ MmLockPagableImageSection( */ #define MmLockPagableCodeSection MmLockPagableDataSection -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmLockPagableSectionByHandle( IN PVOID ImageSectionHandle); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmMapIoSpace( IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG NumberOfBytes, IN MEMORY_CACHING_TYPE CacheEnable); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmMapLockedPages( IN PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI MmPageEntireDriver( IN PVOID AddressWithinSection); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmProbeAndLockProcessPages( IN OUT PMDL MemoryDescriptorList, IN PEPROCESS Process, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmProtectMdlSystemAddress( IN PMDL MemoryDescriptorList, IN ULONG NewProtect); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnmapLockedPages( IN PVOID BaseAddress, IN PMDL MemoryDescriptorList); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmUnmapViewInSessionSpace( IN PVOID MappedBase); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmUnmapViewInSystemSpace( IN PVOID MappedBase); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnsecureVirtualMemory( IN HANDLE SecureHandle); @@ -9736,78 +9758,78 @@ MmUnsecureVirtualMemory( } \ } -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmProbeAndLockPages( IN OUT PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation); -NTOSAPI +NTKERNELAPI MM_SYSTEMSIZE -DDKAPI +NTAPI MmQuerySystemSize( VOID); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI MmRemovePhysicalMemory( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmResetDriverPaging( IN PVOID AddressWithinSection); -NTOSAPI +NTKERNELAPI HANDLE -DDKAPI +NTAPI MmSecureVirtualMemory( IN PVOID Address, IN SIZE_T Size, IN ULONG ProbeMode); -NTOSAPI +NTKERNELAPI ULONG -DDKAPI +NTAPI MmSizeOfMdl( IN PVOID Base, IN SIZE_T Length); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnlockPagableImageSection( IN PVOID ImageSectionHandle); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnlockPages( IN PMDL MemoryDescriptorList); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnmapIoSpace( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnmapReservedMapping( IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI MmUnmapVideoDisplay( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes); @@ -9816,25 +9838,25 @@ MmUnmapVideoDisplay( /** Object manager routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObAssignSecurity( IN PACCESS_STATE AccessState, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PVOID Object, IN POBJECT_TYPE Type); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ObDereferenceSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG Count); -NTOSAPI +NTKERNELAPI LONG_PTR -DDKFASTAPI +FASTCALL ObfDereferenceObject( IN PVOID Object); @@ -9845,17 +9867,17 @@ ObfDereferenceObject( */ #define ObDereferenceObject ObfDereferenceObject -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObGetObjectSecurity( IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObInsertObject( IN PVOID Object, IN PACCESS_STATE PassedAccessState OPTIONAL, @@ -9864,15 +9886,15 @@ ObInsertObject( OUT PVOID* ReferencedObject OPTIONAL, OUT PHANDLE Handle); -NTOSAPI +NTKERNELAPI LONG_PTR -DDKFASTAPI +FASTCALL ObfReferenceObject( IN PVOID Object); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObLogSecurityDescriptor( IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, @@ -9884,15 +9906,15 @@ ObLogSecurityDescriptor( */ #define ObReferenceObject ObfReferenceObject -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ObMakeTemporaryObject( IN PVOID Object); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObOpenObjectByName( IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, @@ -9902,9 +9924,9 @@ ObOpenObjectByName( IN OUT PVOID ParseContext OPTIONAL, OUT PHANDLE Handle); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObOpenObjectByPointer( IN PVOID Object, IN ULONG HandleAttributes, @@ -9914,16 +9936,16 @@ ObOpenObjectByPointer( IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObQueryObjectAuditingByHandle( IN HANDLE Handle, OUT PBOOLEAN GenerateOnClose); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObReferenceObjectByHandle( IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, @@ -9932,9 +9954,9 @@ ObReferenceObjectByHandle( OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, @@ -9945,25 +9967,25 @@ ObReferenceObjectByName( IN OUT PVOID ParseContext OPTIONAL, OUT PVOID *Object); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI ObReferenceObjectByPointer( IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ObReferenceSecurityDescriptor( IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI ObReleaseObjectSecurity( IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated); @@ -9972,17 +9994,17 @@ ObReleaseObjectSecurity( /** Process manager routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsCreateSystemProcess( IN PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsCreateSystemThread( OUT PHANDLE ThreadHandle, IN ULONG DesiredAccess, @@ -9998,9 +10020,9 @@ PsCreateSystemThread( */ #define PsGetCurrentProcess IoGetCurrentProcess -NTOSAPI +NTKERNELAPI HANDLE -DDKAPI +NTAPI PsGetCurrentProcessId( VOID); @@ -10011,55 +10033,55 @@ PsGetCurrentProcessId( #define PsGetCurrentThread() \ ((PETHREAD) KeGetCurrentThread()) -NTOSAPI +NTKERNELAPI HANDLE -DDKAPI +NTAPI PsGetCurrentThreadId( VOID); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI PsGetVersion( PULONG MajorVersion OPTIONAL, PULONG MinorVersion OPTIONAL, PULONG BuildNumber OPTIONAL, PUNICODE_STRING CSDVersion OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsRemoveCreateThreadNotifyRoutine( IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsRemoveLoadImageNotifyRoutine( IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsSetCreateProcessNotifyRoutine( IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, IN BOOLEAN Remove); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsSetCreateThreadNotifyRoutine( IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsSetLoadImageNotifyRoutine( IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PsTerminateSystemThread( IN NTSTATUS ExitStatus); @@ -10067,9 +10089,9 @@ PsTerminateSystemThread( /** Security reference monitor routines **/ -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI SeAccessCheck( IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, @@ -10082,9 +10104,9 @@ SeAccessCheck( OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI SeAssignSecurity( IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, @@ -10094,9 +10116,9 @@ SeAssignSecurity( IN PGENERIC_MAPPING GenericMapping, IN POOL_TYPE PoolType); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI SeAssignSecurityEx( IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, @@ -10108,22 +10130,22 @@ SeAssignSecurityEx( IN PGENERIC_MAPPING GenericMapping, IN POOL_TYPE PoolType); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI SeDeassignSecurity( IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI SeSinglePrivilegeCheck( LUID PrivilegeValue, KPROCESSOR_MODE PreviousMode); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI SeValidSecurityDescriptor( IN ULONG Length, IN PSECURITY_DESCRIPTOR SecurityDescriptor); @@ -10132,18 +10154,18 @@ SeValidSecurityDescriptor( /** NtXxx routines **/ -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtOpenProcess( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtQueryInformationProcess( IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, @@ -10155,36 +10177,36 @@ NtQueryInformationProcess( /** NtXxx and ZwXxx routines **/ -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwCancelTimer( IN HANDLE TimerHandle, OUT PBOOLEAN CurrentState OPTIONAL); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtClose( IN HANDLE Handle); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwClose( IN HANDLE Handle); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwCreateDirectoryObject( OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtCreateEvent( OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, @@ -10192,9 +10214,9 @@ NtCreateEvent( IN EVENT_TYPE EventType, IN BOOLEAN InitialState); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwCreateEvent( OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, @@ -10202,9 +10224,9 @@ ZwCreateEvent( IN EVENT_TYPE EventType, IN BOOLEAN InitialState); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, @@ -10218,9 +10240,9 @@ ZwCreateFile( IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwCreateKey( OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, @@ -10230,31 +10252,31 @@ ZwCreateKey( IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwCreateTimer( OUT PHANDLE TimerHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN TIMER_TYPE TimerType); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwDeleteKey( IN HANDLE KeyHandle); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwDeleteValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtDeviceIoControlFile( IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, @@ -10267,9 +10289,9 @@ NtDeviceIoControlFile( OUT PVOID OutputBuffer, IN ULONG OutputBufferSize); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwDeviceIoControlFile( IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, @@ -10282,9 +10304,9 @@ ZwDeviceIoControlFile( OUT PVOID OutputBuffer, IN ULONG OutputBufferSize); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwEnumerateKey( IN HANDLE KeyHandle, IN ULONG Index, @@ -10293,9 +10315,9 @@ ZwEnumerateKey( IN ULONG Length, OUT PULONG ResultLength); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwEnumerateValueKey( IN HANDLE KeyHandle, IN ULONG Index, @@ -10304,21 +10326,21 @@ ZwEnumerateValueKey( IN ULONG Length, OUT PULONG ResultLength); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwFlushKey( IN HANDLE KeyHandle); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwMakeTemporaryObject( IN HANDLE Handle); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtMapViewOfSection( IN HANDLE SectionHandle, IN HANDLE ProcessHandle, @@ -10331,9 +10353,9 @@ NtMapViewOfSection( IN ULONG AllocationType, IN ULONG Protect); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwMapViewOfSection( IN HANDLE SectionHandle, IN HANDLE ProcessHandle, @@ -10346,9 +10368,9 @@ ZwMapViewOfSection( IN ULONG AllocationType, IN ULONG Protect); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtOpenFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, @@ -10357,9 +10379,9 @@ NtOpenFile( IN ULONG ShareAccess, IN ULONG OpenOptions); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwOpenFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, @@ -10368,41 +10390,41 @@ ZwOpenFile( IN ULONG ShareAccess, IN ULONG OpenOptions); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwOpenKey( OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwOpenSection( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwOpenSymbolicLinkObject( OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwOpenTimer( OUT PHANDLE TimerHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwQueryInformationFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, @@ -10410,9 +10432,9 @@ ZwQueryInformationFile( IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwQueryKey( IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, @@ -10420,17 +10442,17 @@ ZwQueryKey( IN ULONG Length, OUT PULONG ResultLength); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwQuerySymbolicLinkObject( IN HANDLE LinkHandle, IN OUT PUNICODE_STRING LinkTarget, OUT PULONG ReturnedLength OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwQueryValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, @@ -10439,9 +10461,9 @@ ZwQueryValueKey( IN ULONG Length, OUT PULONG ResultLength); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtReadFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, @@ -10453,9 +10475,9 @@ NtReadFile( IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwReadFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, @@ -10467,23 +10489,23 @@ ZwReadFile( IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtSetEvent( IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwSetEvent( IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwSetInformationFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, @@ -10491,18 +10513,18 @@ ZwSetInformationFile( IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwSetInformationThread( IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwSetTimer( IN HANDLE TimerHandle, IN PLARGE_INTEGER DueTime, @@ -10512,9 +10534,9 @@ ZwSetTimer( IN LONG Period OPTIONAL, OUT PBOOLEAN PreviousState OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwSetValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, @@ -10528,39 +10550,39 @@ ZwSetValueKey( #define AT_RESERVED 0x20000000 #define AT_ROUND_TO_PAGE 0x40000000 -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtUnmapViewOfSection( IN HANDLE ProcessHandle, IN PVOID BaseAddress); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwUnmapViewOfSection( IN HANDLE ProcessHandle, IN PVOID BaseAddress); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtWaitForSingleObject( IN HANDLE ObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwWaitForSingleObject( IN HANDLE ObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL); -NTOSAPI +NTSYSCALLAPI NTSTATUS -DDKAPI +NTAPI NtWriteFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, @@ -10572,9 +10594,9 @@ NtWriteFile( IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL); -NTOSAPI +NTSYSAPI NTSTATUS -DDKAPI +NTAPI ZwWriteFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, @@ -10590,32 +10612,32 @@ ZwWriteFile( /** Power management support routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PoCallDriver( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); -NTOSAPI +NTKERNELAPI PULONG -DDKAPI +NTAPI PoRegisterDeviceForIdleDetection( IN PDEVICE_OBJECT DeviceObject, IN ULONG ConservationIdleTime, IN ULONG PerformanceIdleTime, IN DEVICE_POWER_STATE State); -NTOSAPI +NTKERNELAPI PVOID -DDKAPI +NTAPI PoRegisterSystemState( IN PVOID StateHandle, IN EXECUTION_STATE Flags); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PoRequestPowerIrp( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, @@ -10624,41 +10646,41 @@ PoRequestPowerIrp( IN PVOID Context, OUT PIRP *Irp OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI PoRequestShutdownEvent( OUT PVOID *Event); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI PoSetDeviceBusy( PULONG IdlePointer); -NTOSAPI +NTKERNELAPI POWER_STATE -DDKAPI +NTAPI PoSetPowerState( IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI PoSetSystemState( IN EXECUTION_STATE Flags); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI PoStartNextPowerIrp( IN PIRP Irp); -NTOSAPI +NTKERNELAPI VOID -DDKAPI +NTAPI PoUnregisterSystemState( IN PVOID StateHandle); @@ -10666,9 +10688,9 @@ PoUnregisterSystemState( /** WMI library support routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI WmiCompleteRequest( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, @@ -10676,9 +10698,9 @@ WmiCompleteRequest( IN ULONG BufferUsed, IN CCHAR PriorityBoost); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI WmiFireEvent( IN PDEVICE_OBJECT DeviceObject, IN LPGUID Guid, @@ -10686,9 +10708,9 @@ WmiFireEvent( IN ULONG EventDataSize, IN PVOID EventData); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI WmiQueryTraceInformation( IN TRACE_INFORMATION_CLASS TraceInformationClass, OUT PVOID TraceInformation, @@ -10696,16 +10718,16 @@ WmiQueryTraceInformation( OUT PULONG RequiredLength OPTIONAL, IN PVOID Buffer OPTIONAL); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI WmiSystemControl( IN PWMILIB_CONTEXT WmiLibInfo, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, OUT PSYSCTL_IRP_DISPOSITION IrpDisposition); -NTOSAPI +NTKERNELAPI NTSTATUS DDKCDECLAPI WmiTraceMessage( @@ -10717,7 +10739,7 @@ WmiTraceMessage( #if 0 /* FIXME: Get va_list from where? */ -NTOSAPI +NTKERNELAPI NTSTATUS DDKCDECLAPI WmiTraceMessageVa( @@ -10731,15 +10753,15 @@ WmiTraceMessageVa( /** Kernel debugger routines **/ -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KdDisableDebugger( VOID); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI KdEnableDebugger( VOID); @@ -10748,9 +10770,9 @@ NTAPI DbgBreakPoint( VOID); -NTOSAPI +NTSYSAPI VOID -DDKAPI +NTAPI DbgBreakPointWithStatus( IN ULONG Status); @@ -10768,23 +10790,23 @@ DbgPrintEx( IN PCCH Format, IN ...); -NTOSAPI +NTKERNELAPI ULONG DDKCDECLAPI DbgPrintReturnControlC( IN PCH Format, IN ...); -NTOSAPI +NTKERNELAPI BOOLEAN -DDKAPI +NTAPI DbgQueryDebugFilterState( IN ULONG ComponentId, IN ULONG Level); -NTOSAPI +NTKERNELAPI NTSTATUS -DDKAPI +NTAPI DbgSetDebugFilterState( IN ULONG ComponentId, IN ULONG Level, @@ -10808,8 +10830,8 @@ DbgSetDebugFilterState( #if defined(_NTDDK_) || defined(_NTHAL_) || defined(_WDMDDK_) || defined(_NTOSP_) -extern NTOSAPI PBOOLEAN KdDebuggerNotPresent; -extern NTOSAPI PBOOLEAN KdDebuggerEnabled; +extern NTKERNELAPI PBOOLEAN KdDebuggerNotPresent; +extern NTKERNELAPI PBOOLEAN KdDebuggerEnabled; #define KD_DEBUGGER_ENABLED *KdDebuggerEnabled #define KD_DEBUGGER_NOT_PRESENT *KdDebuggerNotPresent @@ -10822,53 +10844,6 @@ extern BOOLEAN KdDebuggerEnabled; #endif -#ifdef __GNUC__ - -/* Available as intrinsics on MSVC */ -#ifdef _X86_ -static __inline void _disable(void) {__asm__ __volatile__("cli\n");} -static __inline void _enable(void) {__asm__ __volatile__("sti\n");} - -static __inline ULONG64 __readcr3(void) -{ - ULONG_PTR Ret; - __asm__ __volatile__("movl %%cr3, %0;\n" - :"=r"(Ret)); - return (ULONG64)Ret; -} - -static __inline ULONG64 __readcr4(void) -{ - ULONG_PTR Ret; - __asm__ __volatile__("movl %%cr4, %0; \n" - :"=r"(Ret)); - return (ULONG64)Ret; -} -#elif defined(_PPC_) -#ifndef _ENABLE_DISABLE_DEFINED -#define _ENABLE_DISABLE_DEFINED -static __inline void _disable(void) { - /* Turn off EE bit */ - __asm__ __volatile__ - ("mfmsr 3\n\t" - "xor 4,5,5\n\t" - "addi 4,4,-1\n\t" - "and 0,3,4\n\t" - "mtmsr 0\n\t" - ); -} -static __inline void _enable(void) { - /* Turn on EE bit */ - __asm__ __volatile__ - ("mfmsr 3\n\t" - "ori 0,3,0x8000\n\t" - "mtmsr 0\n\t" - ); -} -#endif -#endif /*_X86_*/ -#endif - #ifdef __cplusplus } #endif diff --git a/reactos/include/ndk/powerpc/ketypes.h b/reactos/include/ndk/powerpc/ketypes.h index 180d3b7ba6b..9ab555aa0a8 100644 --- a/reactos/include/ndk/powerpc/ketypes.h +++ b/reactos/include/ndk/powerpc/ketypes.h @@ -646,4 +646,6 @@ typedef struct _KEXCEPTION_FRAME DOUBLE Fpr31; } KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; +#define KeGetPreviousMode ExGetPreviousMode + #endif diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h index ba0828e22bf..7d54e14e84b 100644 --- a/reactos/include/psdk/winnt.h +++ b/reactos/include/psdk/winnt.h @@ -62,7 +62,7 @@ extern "C" { #elif (_MSC_VER) #define FORCEINLINE __inline #else -#define FORCEINLINE static __inline +#define FORCEINLINE static __attribute__((unused)) #endif #endif diff --git a/reactos/include/reactos/arc/arc.h b/reactos/include/reactos/arc/arc.h index 1ebad32003b..5a1316b5d64 100644 --- a/reactos/include/reactos/arc/arc.h +++ b/reactos/include/reactos/arc/arc.h @@ -65,6 +65,27 @@ typedef struct _MEMORY_ALLOCATION_DESCRIPTOR ULONG PageCount; } MEMORY_ALLOCATION_DESCRIPTOR, *PMEMORY_ALLOCATION_DESCRIPTOR; +typedef struct _BOOT_DRIVER_LIST_ENTRY +{ + LIST_ENTRY ListEntry; + UNICODE_STRING FilePath; + UNICODE_STRING RegistryPath; + struct _LDR_DATA_TABLE_ENTRY *DataTableEntry; +} BOOT_DRIVER_LIST_ENTRY, *PBOOT_DRIVER_LIST_ENTRY; + +typedef struct _ARC_DISK_SIGNATURE +{ + LIST_ENTRY ListEntry; + ULONG Signature; + PCHAR ArcName; + ULONG CheckSum; + BOOLEAN ValidPartitionTable; + BOOLEAN xInt13; + BOOLEAN IsGpt; + BOOLEAN Reserved; + CHAR GptSignature[16]; +} ARC_DISK_SIGNATURE, *PARC_DISK_SIGNATURE; + typedef struct _CONFIGURATION_COMPONENT { CONFIGURATION_CLASS Class; @@ -268,6 +289,11 @@ typedef struct _I386_LOADER_BLOCK ULONG Reserved; } I386_LOADER_BLOCK, *PI386_LOADER_BLOCK; +typedef struct _POWERPC_LOADER_BLOCK +{ + PVOID BootInfo; +} POWERPC_LOADER_BLOCK, *PPOWERPC_LOADER_BLOCK; + // // Loader Parameter Block // @@ -298,6 +324,7 @@ typedef struct _LOADER_PARAMETER_BLOCK I386_LOADER_BLOCK I386; ALPHA_LOADER_BLOCK Alpha; IA64_LOADER_BLOCK Ia64; + POWERPC_LOADER_BLOCK PowerPC; } u; } LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK; diff --git a/reactos/include/reactos/font.h b/reactos/include/reactos/font.h index 1dd1eb80d17..4ea53e74862 100644 --- a/reactos/include/reactos/font.h +++ b/reactos/include/reactos/font.h @@ -1,7 +1,7 @@ #ifndef _ARCH_POWERPC_FONT_H #define _ARCH_POWERPC_FONT_H -font_char BootDigits[16] = { +font_char BootDigits[37] = { " XXXXX " "X X " "X x X " @@ -113,6 +113,146 @@ font_char BootDigits[16] = { " X " " X " " X " + " ", + " XXXX " + " X X " + " X " + " X XX " + " X X " + " XXXXX " + " ", + " X X " + " X X " + " XXXXXX " + " X X " + " X X " + " X X " + " ", + " XXXX " + " XX " + " XX " + " XX " + " XX " + " XXXX " + " ", + " X " + " X " + " X " + " X " + " X X " + " XXXX " + " ", + " X X " + " X X " + " X X " + " XXXX " + " X X " + " X X " + " ", + " X " + " X " + " X " + " X " + " X " + " XXXXXX " + " ", + " X X " + " X XX X " + " X XX X " + " X X " + " X X " + " X X " + " ", + " X X " + " XX X " + " X X X " + " X X X " + " X XX " + " X X " + " ", + " XXXX " + " X X " + " X X " + " X X " + " X X " + " XXXX " + " ", + " XXXXX " + " X X " + " X X " + " XXXXX " + " X " + " X " + " ", + " XXXX " + " X X " + " X X " + " X X X " + " X XXX " + " XXXXX " + " ", + " XXXXX " + " X X " + " X X " + " XXXXX " + " X X " + " X X " + " ", + " XXXXX " + " X " + " XXXX " + " X " + " X " + " XXXXX " + " ", + " XXXXXX " + " XX " + " XX " + " XX " + " XX " + " XX " + " ", + " X X " + " X X " + " X X " + " X X " + " X X " + " XXXX " + " ", + " X X " + " X X " + " X X " + " X X " + " X X " + " XX " + " ", + " X X " + " X X " + " X X " + " X XX X " + " X XX X " + " X X " + " ", + " X X " + " X X " + " XX " + " X X " + " X X " + " X X " + " ", + " X X " + " X X " + " X X " + " XX " + " XX " + " XX " + " ", + " XXXXXX " + " X " + " X " + " X " + " X " + " XXXXXX " " " }; diff --git a/reactos/include/reactos/ppcboot.h b/reactos/include/reactos/ppcboot.h index 460af14eba9..8dc39c24bf8 100644 --- a/reactos/include/reactos/ppcboot.h +++ b/reactos/include/reactos/ppcboot.h @@ -3,6 +3,7 @@ typedef char font_char[57]; typedef struct _boot_infos_t { + void *loaderBlock; int dispDeviceRect[4]; int dispDeviceRowBytes; int dispDeviceDepth; diff --git a/reactos/include/reactos/ppcdebug.h b/reactos/include/reactos/ppcdebug.h new file mode 100644 index 00000000000..0b665a3c158 --- /dev/null +++ b/reactos/include/reactos/ppcdebug.h @@ -0,0 +1,20 @@ +#ifndef _PPCDEBUG_H +#define _PPCDEBUG_H + +#include "ppcboot.h" + +extern struct _boot_infos_t *BootInfo; +extern void DrawNumber(struct _boot_infos_t *, unsigned long, int, int); +extern void DrawString(struct _boot_infos_t *, const char *, int, int); +#define TRACEXY(x,y) do { \ + unsigned long _x_ = (unsigned long)(x), _y_ = (unsigned long)(y); \ + __asm__("ori 0,0,0"); \ + DrawNumber(BootInfo, __LINE__, 10, 160); \ + DrawString(BootInfo, __FILE__, 100, 160); \ + DrawNumber(BootInfo, _x_, 400, 160); \ + DrawNumber(BootInfo, _y_, 490, 160); \ +} while(0) +#define TRACEX(x) TRACEXY(x,0) +#define TRACE TRACEX(0) + +#endif//_PPCDEBUG_H diff --git a/reactos/include/reactos/rosldr.h b/reactos/include/reactos/rosldr.h index 3e456e2ad14..732a32b1c98 100644 --- a/reactos/include/reactos/rosldr.h +++ b/reactos/include/reactos/rosldr.h @@ -42,6 +42,7 @@ typedef struct _ROS_LOADER_PARAMETER_BLOCK ULONG PageDirectoryStart; ULONG PageDirectoryEnd; ULONG KernelBase; + ULONG ArchExtra; } ROS_LOADER_PARAMETER_BLOCK, *PROS_LOADER_PARAMETER_BLOCK; extern ULONG MmFreeLdrMemHigher, MmFreeLdrMemLower; diff --git a/reactos/lib/cmlib/cmdata.h b/reactos/lib/cmlib/cmdata.h index fb6b7110e1f..d0266ee01e5 100644 --- a/reactos/lib/cmlib/cmdata.h +++ b/reactos/lib/cmlib/cmdata.h @@ -1,154 +1,154 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2001 - 2005 Eric Kohl - */ - -#ifndef CMLIB_CMDATA_H -#define CMLIB_CMDATA_H - -#define REG_INIT_BLOCK_LIST_SIZE 32 -#define REG_INIT_HASH_TABLE_SIZE 3 -#define REG_EXTEND_HASH_TABLE_SIZE 4 -#define REG_VALUE_LIST_CELL_MULTIPLE 4 - -#define REG_KEY_CELL_ID 0x6b6e -#define REG_HASH_TABLE_CELL_ID 0x666c -#define REG_VALUE_CELL_ID 0x6b76 -#define REG_SECURITY_CELL_ID 0x6b73 - -#ifndef _CM_ - -#include - -typedef struct _CM_VIEW_OF_FILE -{ - LIST_ENTRY LRUViewList; - LIST_ENTRY PinViewList; - ULONG FileOffset; - ULONG Size; - PULONG ViewAddress; - PVOID Bcb; - ULONG UseCount; -} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE; - -typedef struct _CHILD_LIST -{ - ULONG Count; - HCELL_INDEX List; -} CHILD_LIST, *PCHILD_LIST; - -typedef struct _CM_KEY_NODE -{ - /* Key cell identifier "kn" (0x6b6e) */ - USHORT Id; - - /* Flags */ - USHORT Flags; - - /* Time of last flush */ - LARGE_INTEGER LastWriteTime; - - ULONG Spare; - - /* BlockAddress offset of parent key cell */ - HCELL_INDEX Parent; - - /* Count of sub keys for the key in this key cell (stable & volatile) */ - ULONG SubKeyCounts[HvMaxStorageType]; - - /* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */ - HCELL_INDEX SubKeyLists[HvMaxStorageType]; - - CHILD_LIST ValueList; - - /* BlockAddress offset of security cell */ - HCELL_INDEX SecurityKeyOffset; - - /* BlockAddress offset of registry key class */ - HCELL_INDEX ClassNameOffset; - - ULONG MaxNameLen; - ULONG MaxClassLen; - ULONG MaxValueNameLen; - ULONG MaxValueDataLen; - ULONG WorkVar; - - /* Size in bytes of key name */ - USHORT NameSize; - - /* Size of class name in bytes */ - USHORT ClassSize; - - /* Name of key (not zero terminated) */ - UCHAR Name[0]; -} CM_KEY_NODE, *PCM_KEY_NODE; - -/* CM_KEY_NODE.Flags constants */ -#define REG_KEY_VOLATILE_CELL 0x01 -#define REG_KEY_ROOT_CELL 0x0C -#define REG_KEY_LINK_CELL 0x10 -#define REG_KEY_NAME_PACKED 0x20 - -/* - * Hash record - * - * HashValue: - * packed name: four letters of value's name - * otherwise: Zero! - */ -typedef struct _HASH_RECORD -{ - HCELL_INDEX KeyOffset; - ULONG HashValue; -} HASH_RECORD, *PHASH_RECORD; - -typedef struct _HASH_TABLE_CELL -{ - USHORT Id; - USHORT HashTableSize; - HASH_RECORD Table[0]; -} HASH_TABLE_CELL, *PHASH_TABLE_CELL; - -typedef struct _VALUE_LIST_CELL -{ - HCELL_INDEX ValueOffset[0]; -} VALUE_LIST_CELL, *PVALUE_LIST_CELL; - -typedef struct _CM_KEY_VALUE -{ - USHORT Id; // "kv" - USHORT NameSize; // length of Name - ULONG DataSize; // length of datas in the cell pointed by DataOffset - HCELL_INDEX DataOffset;// datas are here if high bit of DataSize is set - ULONG DataType; - USHORT Flags; - USHORT Unused1; - UCHAR Name[0]; /* warning : not zero terminated */ -} CM_KEY_VALUE, *PCM_KEY_VALUE; - -/* CM_KEY_VALUE.Flags constants */ -#define REG_VALUE_NAME_PACKED 0x0001 - -/* CM_KEY_VALUE.DataSize mask constants */ -#define REG_DATA_SIZE_MASK 0x7FFFFFFF -#define REG_DATA_IN_OFFSET 0x80000000 - -typedef struct _CM_KEY_SECURITY -{ - USHORT Signature; // "sk" - USHORT Reserved; - HCELL_INDEX Flink; - HCELL_INDEX Blink; - ULONG ReferenceCount; - ULONG DescriptorLength; - //SECURITY_DESCRIPTOR_RELATIVE Descriptor; - UCHAR Data[0]; -} CM_KEY_SECURITY, *PCM_KEY_SECURITY; - -#include - -#endif - -#endif /* CMLIB_CMDATA_H */ +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2001 - 2005 Eric Kohl + */ + +#ifndef CMLIB_CMDATA_H +#define CMLIB_CMDATA_H + +#define REG_INIT_BLOCK_LIST_SIZE 32 +#define REG_INIT_HASH_TABLE_SIZE 3 +#define REG_EXTEND_HASH_TABLE_SIZE 4 +#define REG_VALUE_LIST_CELL_MULTIPLE 4 + +#define REG_KEY_CELL_ID 0x6b6e +#define REG_HASH_TABLE_CELL_ID 0x666c +#define REG_VALUE_CELL_ID 0x6b76 +#define REG_SECURITY_CELL_ID 0x6b73 + +#ifndef _CM_ + +#include + +typedef struct _CM_VIEW_OF_FILE +{ + LIST_ENTRY LRUViewList; + LIST_ENTRY PinViewList; + ULONG FileOffset; + ULONG Size; + PULONG ViewAddress; + PVOID Bcb; + ULONG UseCount; +} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE; + +typedef struct _CHILD_LIST +{ + ULONG Count; + HCELL_INDEX List; +} CHILD_LIST, *PCHILD_LIST; + +typedef struct _CM_KEY_NODE +{ + /* Key cell identifier "kn" (0x6b6e) */ + USHORT Id; + + /* Flags */ + USHORT Flags; + + /* Time of last flush */ + LARGE_INTEGER LastWriteTime; + + ULONG Spare; + + /* BlockAddress offset of parent key cell */ + HCELL_INDEX Parent; + + /* Count of sub keys for the key in this key cell (stable & volatile) */ + ULONG SubKeyCounts[HvMaxStorageType]; + + /* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */ + HCELL_INDEX SubKeyLists[HvMaxStorageType]; + + CHILD_LIST ValueList; + + /* BlockAddress offset of security cell */ + HCELL_INDEX SecurityKeyOffset; + + /* BlockAddress offset of registry key class */ + HCELL_INDEX ClassNameOffset; + + ULONG MaxNameLen; + ULONG MaxClassLen; + ULONG MaxValueNameLen; + ULONG MaxValueDataLen; + ULONG WorkVar; + + /* Size in bytes of key name */ + USHORT NameSize; + + /* Size of class name in bytes */ + USHORT ClassSize; + + /* Name of key (not zero terminated) */ + UCHAR Name[0]; +} CM_KEY_NODE, *PCM_KEY_NODE; + +/* CM_KEY_NODE.Flags constants */ +#define REG_KEY_VOLATILE_CELL 0x01 +#define REG_KEY_ROOT_CELL 0x0C +#define REG_KEY_LINK_CELL 0x10 +#define REG_KEY_NAME_PACKED 0x20 + +/* + * Hash record + * + * HashValue: + * packed name: four letters of value's name + * otherwise: Zero! + */ +typedef struct _HASH_RECORD +{ + HCELL_INDEX KeyOffset; + ULONG HashValue; +} HASH_RECORD, *PHASH_RECORD; + +typedef struct _HASH_TABLE_CELL +{ + USHORT Id; + USHORT HashTableSize; + HASH_RECORD Table[0]; +} HASH_TABLE_CELL, *PHASH_TABLE_CELL; + +typedef struct _VALUE_LIST_CELL +{ + HCELL_INDEX ValueOffset[0]; +} VALUE_LIST_CELL, *PVALUE_LIST_CELL; + +typedef struct _CM_KEY_VALUE +{ + USHORT Id; // "kv" + USHORT NameSize; // length of Name + ULONG DataSize; // length of datas in the cell pointed by DataOffset + HCELL_INDEX DataOffset;// datas are here if high bit of DataSize is set + ULONG DataType; + USHORT Flags; + USHORT Unused1; + UCHAR Name[0]; /* warning : not zero terminated */ +} CM_KEY_VALUE, *PCM_KEY_VALUE; + +/* CM_KEY_VALUE.Flags constants */ +#define REG_VALUE_NAME_PACKED 0x0001 + +/* CM_KEY_VALUE.DataSize mask constants */ +#define REG_DATA_SIZE_MASK 0x7FFFFFFF +#define REG_DATA_IN_OFFSET 0x80000000 + +typedef struct _CM_KEY_SECURITY +{ + USHORT Signature; // "sk" + USHORT Reserved; + HCELL_INDEX Flink; + HCELL_INDEX Blink; + ULONG ReferenceCount; + ULONG DescriptorLength; + //SECURITY_DESCRIPTOR_RELATIVE Descriptor; + UCHAR Data[0]; +} CM_KEY_SECURITY, *PCM_KEY_SECURITY; + +#include + +#endif + +#endif /* CMLIB_CMDATA_H */ diff --git a/reactos/lib/cmlib/cminit.c b/reactos/lib/cmlib/cminit.c index c4013960508..ac4a41314f6 100644 --- a/reactos/lib/cmlib/cminit.c +++ b/reactos/lib/cmlib/cminit.c @@ -1,82 +1,82 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2001 - 2005 Eric Kohl - */ - -#include "cmlib.h" - -BOOLEAN CMAPI -CmCreateRootNode( - PHHIVE Hive, - PCWSTR Name) -{ - PCM_KEY_NODE KeyCell; - HCELL_INDEX RootCellIndex; - SIZE_T NameSize; - - NameSize = wcslen(Name) * sizeof(WCHAR); - RootCellIndex = HvAllocateCell(Hive, sizeof(CM_KEY_NODE) + NameSize, HvStable); - if (RootCellIndex == HCELL_NULL) - return FALSE; - - Hive->HiveHeader->RootCell = RootCellIndex; - Hive->HiveHeader->Checksum = HvpHiveHeaderChecksum(Hive->HiveHeader); - - KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex); - KeyCell->Id = REG_KEY_CELL_ID; - KeyCell->Flags = REG_KEY_ROOT_CELL; - KeyCell->LastWriteTime.QuadPart = 0; - KeyCell->Parent = HCELL_NULL; - KeyCell->SubKeyCounts[0] = 0; - KeyCell->SubKeyCounts[1] = 0; - KeyCell->SubKeyLists[0] = HCELL_NULL; - KeyCell->SubKeyLists[1] = HCELL_NULL; - KeyCell->ValueList.Count = 0; - KeyCell->ValueList.List = HCELL_NULL; - KeyCell->SecurityKeyOffset = HCELL_NULL; - KeyCell->ClassNameOffset = HCELL_NULL; - KeyCell->NameSize = (USHORT)NameSize; - KeyCell->ClassSize = 0; - memcpy(KeyCell->Name, Name, NameSize); - - return TRUE; -} - -static VOID CMAPI -CmpPrepareKey( - PHHIVE RegistryHive, - PCM_KEY_NODE KeyCell) -{ - PCM_KEY_NODE SubKeyCell; - PHASH_TABLE_CELL HashCell; - ULONG i; - - ASSERT(KeyCell->Id == REG_KEY_CELL_ID); - - KeyCell->SubKeyLists[HvVolatile] = HCELL_NULL; - KeyCell->SubKeyCounts[HvVolatile] = 0; - - /* Enumerate and add subkeys */ - if (KeyCell->SubKeyCounts[HvStable] > 0) - { - HashCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[HvStable]); - - for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++) - { - SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset); - CmpPrepareKey(RegistryHive, SubKeyCell); - } - } -} - -VOID CMAPI -CmPrepareHive( - PHHIVE RegistryHive) -{ - PCM_KEY_NODE RootCell; - - RootCell = HvGetCell(RegistryHive, RegistryHive->HiveHeader->RootCell); - CmpPrepareKey(RegistryHive, RootCell); -} +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2001 - 2005 Eric Kohl + */ + +#include "cmlib.h" + +BOOLEAN CMAPI +CmCreateRootNode( + PHHIVE Hive, + PCWSTR Name) +{ + PCM_KEY_NODE KeyCell; + HCELL_INDEX RootCellIndex; + SIZE_T NameSize; + + NameSize = wcslen(Name) * sizeof(WCHAR); + RootCellIndex = HvAllocateCell(Hive, sizeof(CM_KEY_NODE) + NameSize, HvStable); + if (RootCellIndex == HCELL_NULL) + return FALSE; + + Hive->HiveHeader->RootCell = RootCellIndex; + Hive->HiveHeader->Checksum = HvpHiveHeaderChecksum(Hive->HiveHeader); + + KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex); + KeyCell->Id = REG_KEY_CELL_ID; + KeyCell->Flags = REG_KEY_ROOT_CELL; + KeyCell->LastWriteTime.QuadPart = 0; + KeyCell->Parent = HCELL_NULL; + KeyCell->SubKeyCounts[0] = 0; + KeyCell->SubKeyCounts[1] = 0; + KeyCell->SubKeyLists[0] = HCELL_NULL; + KeyCell->SubKeyLists[1] = HCELL_NULL; + KeyCell->ValueList.Count = 0; + KeyCell->ValueList.List = HCELL_NULL; + KeyCell->SecurityKeyOffset = HCELL_NULL; + KeyCell->ClassNameOffset = HCELL_NULL; + KeyCell->NameSize = (USHORT)NameSize; + KeyCell->ClassSize = 0; + memcpy(KeyCell->Name, Name, NameSize); + + return TRUE; +} + +static VOID CMAPI +CmpPrepareKey( + PHHIVE RegistryHive, + PCM_KEY_NODE KeyCell) +{ + PCM_KEY_NODE SubKeyCell; + PHASH_TABLE_CELL HashCell; + ULONG i; + + ASSERT(KeyCell->Id == REG_KEY_CELL_ID); + + KeyCell->SubKeyLists[HvVolatile] = HCELL_NULL; + KeyCell->SubKeyCounts[HvVolatile] = 0; + + /* Enumerate and add subkeys */ + if (KeyCell->SubKeyCounts[HvStable] > 0) + { + HashCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[HvStable]); + + for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++) + { + SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset); + CmpPrepareKey(RegistryHive, SubKeyCell); + } + } +} + +VOID CMAPI +CmPrepareHive( + PHHIVE RegistryHive) +{ + PCM_KEY_NODE RootCell; + + RootCell = HvGetCell(RegistryHive, RegistryHive->HiveHeader->RootCell); + CmpPrepareKey(RegistryHive, RootCell); +} diff --git a/reactos/lib/cmlib/cmlib.h b/reactos/lib/cmlib/cmlib.h index f691c45c7af..7e590c2cd58 100644 --- a/reactos/lib/cmlib/cmlib.h +++ b/reactos/lib/cmlib/cmlib.h @@ -1,237 +1,237 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2001 - 2005 Eric Kohl - */ - -#ifndef CMLIB_H -#define CMLIB_H - -#define WIN32_NO_STATUS -#include -#include "hivedata.h" -#include "cmdata.h" - -#ifndef ROUND_UP -#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b)) -#define ROUND_DOWN(a,b) (((a)/(b))*(b)) -#endif - -#define CMAPI NTAPI - -struct _HHIVE; - -typedef PVOID (CMAPI *PGET_CELL_ROUTINE)( - struct _HHIVE *Hive, - HCELL_INDEX Cell); - -typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)( - struct _HHIVE *Hive, - HCELL_INDEX Cell); - -typedef PVOID (CMAPI *PALLOCATE_ROUTINE)( - SIZE_T Size, - BOOLEAN Paged); - -typedef VOID (CMAPI *PFREE_ROUTINE)( - PVOID Ptr); - -typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)( - struct _HHIVE *RegistryHive, - ULONG FileType, - ULONGLONG FileOffset, - PVOID Buffer, - SIZE_T BufferLength); - -typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)( - struct _HHIVE *RegistryHive, - ULONG FileType, - ULONGLONG FileOffset, - PVOID Buffer, - SIZE_T BufferLength); - -typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)( - struct _HHIVE *RegistryHive, - ULONG FileType, - ULONGLONG FileSize); - -typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)( - struct _HHIVE *RegistryHive, - ULONG FileType); - -typedef struct _HMAP_ENTRY -{ - ULONG_PTR Bin; - ULONG_PTR Block; - struct _CM_VIEW_OF_FILE *CmHive; - ULONG MemAlloc; -} HMAP_ENTRY, *PHMAP_ENTRY; - -typedef struct _HMAP_TABLE -{ - HMAP_ENTRY Table[512]; -} HMAP_TABLE, *PHMAP_TABLE; - -typedef struct _HMAP_DIRECTORY -{ - PHMAP_TABLE Directory[2048]; -} HMAP_DIRECTORY, *PHMAP_DIRECTORY; - -typedef struct _DUAL -{ - ULONG Length; - PHMAP_DIRECTORY Map; - PHMAP_ENTRY BlockList; // PHMAP_TABLE SmallDir; - ULONG Guard; - HCELL_INDEX FreeDisplay[24]; //FREE_DISPLAY FreeDisplay[24]; - ULONG FreeSummary; - LIST_ENTRY FreeBins; -} DUAL, *PDUAL; - -typedef struct _HHIVE -{ - ULONG Signature; - PGET_CELL_ROUTINE GetCellRoutine; - PRELEASE_CELL_ROUTINE ReleaseCellRoutine; - PALLOCATE_ROUTINE Allocate; - PFREE_ROUTINE Free; - PFILE_READ_ROUTINE FileRead; - PFILE_WRITE_ROUTINE FileWrite; - PFILE_SET_SIZE_ROUTINE FileSetSize; - PFILE_FLUSH_ROUTINE FileFlush; - PHBASE_BLOCK HiveHeader; - RTL_BITMAP DirtyVector; - ULONG DirtyCount; - ULONG DirtyAlloc; - ULONG BaseBlockAlloc; - ULONG Cluster; - BOOLEAN Flat; - BOOLEAN ReadOnly; - BOOLEAN Log; - BOOLEAN DirtyFlag; - ULONG HvBinHeadersUse; - ULONG HvFreeCellsUse; - ULONG HvUsedcellsUse; - ULONG CmUsedCellsUse; - ULONG HiveFlags; - ULONG LogSize; - ULONG RefreshCount; - ULONG StorageTypeCount; - ULONG Version; - DUAL Storage[HvMaxStorageType]; -} HHIVE, *PHHIVE; - -#ifndef _CM_ -typedef struct _EREGISTRY_HIVE -{ - HHIVE Hive; - LIST_ENTRY HiveList; - UNICODE_STRING HiveFileName; - UNICODE_STRING LogFileName; - PCM_KEY_SECURITY RootSecurityCell; - ULONG Flags; - HANDLE HiveHandle; - HANDLE LogHandle; -} EREGISTRY_HIVE, *PEREGISTRY_HIVE; -#endif - -/* - * Public functions. - */ - -#define HV_OPERATION_CREATE_HIVE 0 -#define HV_OPERATION_MEMORY 1 -#define HV_OPERATION_MEMORY_INPLACE 3 - -NTSTATUS CMAPI -HvInitialize( - PHHIVE RegistryHive, - ULONG Operation, - ULONG_PTR HiveData OPTIONAL, - ULONG Cluster OPTIONAL, - ULONG Flags, - ULONG FileType, - PALLOCATE_ROUTINE Allocate, - PFREE_ROUTINE Free, - PFILE_READ_ROUTINE FileRead, - PFILE_WRITE_ROUTINE FileWrite, - PFILE_SET_SIZE_ROUTINE FileSetSize, - PFILE_FLUSH_ROUTINE FileFlush, - IN PUNICODE_STRING FileName); - -VOID CMAPI -HvFree( - PHHIVE RegistryHive); - -PVOID CMAPI -HvGetCell( - PHHIVE RegistryHive, - HCELL_INDEX CellOffset); - -#define HvReleaseCell(h, c) \ - if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c) - -LONG CMAPI -HvGetCellSize( - PHHIVE RegistryHive, - PVOID Cell); - -HCELL_INDEX CMAPI -HvAllocateCell( - PHHIVE RegistryHive, - SIZE_T Size, - HV_STORAGE_TYPE Storage); - -HCELL_INDEX CMAPI -HvReallocateCell( - PHHIVE RegistryHive, - HCELL_INDEX CellOffset, - ULONG Size); - -VOID CMAPI -HvFreeCell( - PHHIVE RegistryHive, - HCELL_INDEX CellOffset); - -VOID CMAPI -HvMarkCellDirty( - PHHIVE RegistryHive, - HCELL_INDEX CellOffset); - -BOOLEAN CMAPI -HvSyncHive( - PHHIVE RegistryHive); - -BOOLEAN CMAPI -HvWriteHive( - PHHIVE RegistryHive); - -BOOLEAN CMAPI -CmCreateRootNode( - PHHIVE Hive, - PCWSTR Name); - -VOID CMAPI -CmPrepareHive( - PHHIVE RegistryHive); - -/* - * Private functions. - */ - -PHBIN CMAPI -HvpAddBin( - PHHIVE RegistryHive, - ULONG Size, - HV_STORAGE_TYPE Storage); - -NTSTATUS CMAPI -HvpCreateHiveFreeCellList( - PHHIVE Hive); - -ULONG CMAPI -HvpHiveHeaderChecksum( - PHBASE_BLOCK HiveHeader); - -#endif /* CMLIB_H */ +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2001 - 2005 Eric Kohl + */ + +#ifndef CMLIB_H +#define CMLIB_H + +#define WIN32_NO_STATUS +#include +#include "hivedata.h" +#include "cmdata.h" + +#ifndef ROUND_UP +#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b)) +#define ROUND_DOWN(a,b) (((a)/(b))*(b)) +#endif + +#define CMAPI NTAPI + +struct _HHIVE; + +typedef PVOID (CMAPI *PGET_CELL_ROUTINE)( + struct _HHIVE *Hive, + HCELL_INDEX Cell); + +typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)( + struct _HHIVE *Hive, + HCELL_INDEX Cell); + +typedef PVOID (CMAPI *PALLOCATE_ROUTINE)( + SIZE_T Size, + BOOLEAN Paged); + +typedef VOID (CMAPI *PFREE_ROUTINE)( + PVOID Ptr); + +typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)( + struct _HHIVE *RegistryHive, + ULONG FileType, + ULONGLONG FileOffset, + PVOID Buffer, + SIZE_T BufferLength); + +typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)( + struct _HHIVE *RegistryHive, + ULONG FileType, + ULONGLONG FileOffset, + PVOID Buffer, + SIZE_T BufferLength); + +typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)( + struct _HHIVE *RegistryHive, + ULONG FileType, + ULONGLONG FileSize); + +typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)( + struct _HHIVE *RegistryHive, + ULONG FileType); + +typedef struct _HMAP_ENTRY +{ + ULONG_PTR Bin; + ULONG_PTR Block; + struct _CM_VIEW_OF_FILE *CmHive; + ULONG MemAlloc; +} HMAP_ENTRY, *PHMAP_ENTRY; + +typedef struct _HMAP_TABLE +{ + HMAP_ENTRY Table[512]; +} HMAP_TABLE, *PHMAP_TABLE; + +typedef struct _HMAP_DIRECTORY +{ + PHMAP_TABLE Directory[2048]; +} HMAP_DIRECTORY, *PHMAP_DIRECTORY; + +typedef struct _DUAL +{ + ULONG Length; + PHMAP_DIRECTORY Map; + PHMAP_ENTRY BlockList; // PHMAP_TABLE SmallDir; + ULONG Guard; + HCELL_INDEX FreeDisplay[24]; //FREE_DISPLAY FreeDisplay[24]; + ULONG FreeSummary; + LIST_ENTRY FreeBins; +} DUAL, *PDUAL; + +typedef struct _HHIVE +{ + ULONG Signature; + PGET_CELL_ROUTINE GetCellRoutine; + PRELEASE_CELL_ROUTINE ReleaseCellRoutine; + PALLOCATE_ROUTINE Allocate; + PFREE_ROUTINE Free; + PFILE_READ_ROUTINE FileRead; + PFILE_WRITE_ROUTINE FileWrite; + PFILE_SET_SIZE_ROUTINE FileSetSize; + PFILE_FLUSH_ROUTINE FileFlush; + PHBASE_BLOCK HiveHeader; + RTL_BITMAP DirtyVector; + ULONG DirtyCount; + ULONG DirtyAlloc; + ULONG BaseBlockAlloc; + ULONG Cluster; + BOOLEAN Flat; + BOOLEAN ReadOnly; + BOOLEAN Log; + BOOLEAN DirtyFlag; + ULONG HvBinHeadersUse; + ULONG HvFreeCellsUse; + ULONG HvUsedcellsUse; + ULONG CmUsedCellsUse; + ULONG HiveFlags; + ULONG LogSize; + ULONG RefreshCount; + ULONG StorageTypeCount; + ULONG Version; + DUAL Storage[HvMaxStorageType]; +} HHIVE, *PHHIVE; + +#ifndef _CM_ +typedef struct _EREGISTRY_HIVE +{ + HHIVE Hive; + LIST_ENTRY HiveList; + UNICODE_STRING HiveFileName; + UNICODE_STRING LogFileName; + PCM_KEY_SECURITY RootSecurityCell; + ULONG Flags; + HANDLE HiveHandle; + HANDLE LogHandle; +} EREGISTRY_HIVE, *PEREGISTRY_HIVE; +#endif + +/* + * Public functions. + */ + +#define HV_OPERATION_CREATE_HIVE 0 +#define HV_OPERATION_MEMORY 1 +#define HV_OPERATION_MEMORY_INPLACE 3 + +NTSTATUS CMAPI +HvInitialize( + PHHIVE RegistryHive, + ULONG Operation, + ULONG_PTR HiveData OPTIONAL, + ULONG Cluster OPTIONAL, + ULONG Flags, + ULONG FileType, + PALLOCATE_ROUTINE Allocate, + PFREE_ROUTINE Free, + PFILE_READ_ROUTINE FileRead, + PFILE_WRITE_ROUTINE FileWrite, + PFILE_SET_SIZE_ROUTINE FileSetSize, + PFILE_FLUSH_ROUTINE FileFlush, + IN PUNICODE_STRING FileName); + +VOID CMAPI +HvFree( + PHHIVE RegistryHive); + +PVOID CMAPI +HvGetCell( + PHHIVE RegistryHive, + HCELL_INDEX CellOffset); + +#define HvReleaseCell(h, c) \ + if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c) + +LONG CMAPI +HvGetCellSize( + PHHIVE RegistryHive, + PVOID Cell); + +HCELL_INDEX CMAPI +HvAllocateCell( + PHHIVE RegistryHive, + SIZE_T Size, + HV_STORAGE_TYPE Storage); + +HCELL_INDEX CMAPI +HvReallocateCell( + PHHIVE RegistryHive, + HCELL_INDEX CellOffset, + ULONG Size); + +VOID CMAPI +HvFreeCell( + PHHIVE RegistryHive, + HCELL_INDEX CellOffset); + +VOID CMAPI +HvMarkCellDirty( + PHHIVE RegistryHive, + HCELL_INDEX CellOffset); + +BOOLEAN CMAPI +HvSyncHive( + PHHIVE RegistryHive); + +BOOLEAN CMAPI +HvWriteHive( + PHHIVE RegistryHive); + +BOOLEAN CMAPI +CmCreateRootNode( + PHHIVE Hive, + PCWSTR Name); + +VOID CMAPI +CmPrepareHive( + PHHIVE RegistryHive); + +/* + * Private functions. + */ + +PHBIN CMAPI +HvpAddBin( + PHHIVE RegistryHive, + ULONG Size, + HV_STORAGE_TYPE Storage); + +NTSTATUS CMAPI +HvpCreateHiveFreeCellList( + PHHIVE Hive); + +ULONG CMAPI +HvpHiveHeaderChecksum( + PHBASE_BLOCK HiveHeader); + +#endif /* CMLIB_H */ diff --git a/reactos/lib/cmlib/cmlib.mak b/reactos/lib/cmlib/cmlib.mak index bc9aae444f0..e35e3ccc01c 100644 --- a/reactos/lib/cmlib/cmlib.mak +++ b/reactos/lib/cmlib/cmlib.mak @@ -1,72 +1,72 @@ -CMLIB_BASE = $(LIB_BASE_)cmlib -CMLIB_BASE_ = $(CMLIB_BASE)$(SEP) -CMLIB_INT = $(INTERMEDIATE_)$(CMLIB_BASE)_host -CMLIB_INT_ = $(INTERMEDIATE_)$(CMLIB_BASE)_host$(SEP) -CMLIB_OUT = $(OUTPUT_)$(CMLIB_BASE)_host -CMLIB_OUT_ = $(OUTPUT_)$(CMLIB_BASE)_host$(SEP) - -$(CMLIB_INT): | $(LIB_INT) - $(ECHO_MKDIR) - ${mkdir} $@ - -ifneq ($(INTERMEDIATE),$(OUTPUT)) -$(CMLIB_OUT): | $(OUTPUT_)$(LIB_BASE) - $(ECHO_MKDIR) - ${mkdir} $@ -endif - -CMLIB_HOST_TARGET = \ - $(CMLIB_OUT)$(SEP)cmlib.a - -CMLIB_HOST_SOURCES = $(addprefix $(CMLIB_BASE_), \ - cminit.c \ - hivebin.c \ - hivecell.c \ - hiveinit.c \ - hivesum.c \ - hivewrt.c \ - ) - -CMLIB_HOST_OBJECTS = \ - $(subst $(CMLIB_BASE), $(CMLIB_INT), $(CMLIB_HOST_SOURCES:.c=.o)) - -CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith \ - -D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_\ - -DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk -Iinclude/crt \ - -D__NO_CTYPE_INLINES - -$(CMLIB_HOST_TARGET): $(CMLIB_HOST_OBJECTS) | $(CMLIB_OUT) - $(ECHO_AR) - $(host_ar) -r $@ $(CMLIB_HOST_OBJECTS) - -$(CMLIB_INT_)cminit.o: $(CMLIB_BASE_)cminit.c | $(CMLIB_INT) - $(ECHO_CC) - ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ - -$(CMLIB_INT_)hivebin.o: $(CMLIB_BASE_)hivebin.c | $(CMLIB_INT) - $(ECHO_CC) - ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ - -$(CMLIB_INT_)hivecell.o: $(CMLIB_BASE_)hivecell.c | $(CMLIB_INT) - $(ECHO_CC) - ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ - -$(CMLIB_INT_)hiveinit.o: $(CMLIB_BASE_)hiveinit.c | $(CMLIB_INT) - $(ECHO_CC) - ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ - -$(CMLIB_INT_)hivesum.o: $(CMLIB_BASE_)hivesum.c | $(CMLIB_INT) - $(ECHO_CC) - ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ - -$(CMLIB_INT_)hivewrt.o: $(CMLIB_BASE_)hivewrt.c | $(CMLIB_INT) - $(ECHO_CC) - ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ - -.PHONY: cmlib_host -cmlib_host: $(CMLIB_HOST_TARGET) - -.PHONY: cmlib_host_clean -cmlib_host_clean: - -@$(rm) $(CMLIB_HOST_TARGET) $(CMLIB_HOST_OBJECTS) 2>$(NUL) -clean: cmlib_host_clean +CMLIB_BASE = $(LIB_BASE_)cmlib +CMLIB_BASE_ = $(CMLIB_BASE)$(SEP) +CMLIB_INT = $(INTERMEDIATE_)$(CMLIB_BASE)_host +CMLIB_INT_ = $(INTERMEDIATE_)$(CMLIB_BASE)_host$(SEP) +CMLIB_OUT = $(OUTPUT_)$(CMLIB_BASE)_host +CMLIB_OUT_ = $(OUTPUT_)$(CMLIB_BASE)_host$(SEP) + +$(CMLIB_INT): | $(LIB_INT) + $(ECHO_MKDIR) + ${mkdir} $@ + +ifneq ($(INTERMEDIATE),$(OUTPUT)) +$(CMLIB_OUT): | $(OUTPUT_)$(LIB_BASE) + $(ECHO_MKDIR) + ${mkdir} $@ +endif + +CMLIB_HOST_TARGET = \ + $(CMLIB_OUT)$(SEP)cmlib.a + +CMLIB_HOST_SOURCES = $(addprefix $(CMLIB_BASE_), \ + cminit.c \ + hivebin.c \ + hivecell.c \ + hiveinit.c \ + hivesum.c \ + hivewrt.c \ + ) + +CMLIB_HOST_OBJECTS = \ + $(subst $(CMLIB_BASE), $(CMLIB_INT), $(CMLIB_HOST_SOURCES:.c=.o)) + +CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith \ + -D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_ -D_NTSYSTEM_ \ + -DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk -Iinclude/crt \ + -D__NO_CTYPE_INLINES + +$(CMLIB_HOST_TARGET): $(CMLIB_HOST_OBJECTS) | $(CMLIB_OUT) + $(ECHO_AR) + $(host_ar) -r $@ $(CMLIB_HOST_OBJECTS) + +$(CMLIB_INT_)cminit.o: $(CMLIB_BASE_)cminit.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +$(CMLIB_INT_)hivebin.o: $(CMLIB_BASE_)hivebin.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +$(CMLIB_INT_)hivecell.o: $(CMLIB_BASE_)hivecell.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +$(CMLIB_INT_)hiveinit.o: $(CMLIB_BASE_)hiveinit.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +$(CMLIB_INT_)hivesum.o: $(CMLIB_BASE_)hivesum.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +$(CMLIB_INT_)hivewrt.o: $(CMLIB_BASE_)hivewrt.c | $(CMLIB_INT) + $(ECHO_CC) + ${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@ + +.PHONY: cmlib_host +cmlib_host: $(CMLIB_HOST_TARGET) + +.PHONY: cmlib_host_clean +cmlib_host_clean: + -@$(rm) $(CMLIB_HOST_TARGET) $(CMLIB_HOST_OBJECTS) 2>$(NUL) +clean: cmlib_host_clean diff --git a/reactos/lib/cmlib/hivebin.c b/reactos/lib/cmlib/hivebin.c index f973ef114cc..5a70b8d4aa1 100644 --- a/reactos/lib/cmlib/hivebin.c +++ b/reactos/lib/cmlib/hivebin.c @@ -1,98 +1,98 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2005 Hartmut Birr - * Copyright 2001 - 2005 Eric Kohl - */ - -#include "cmlib.h" - -PHBIN CMAPI -HvpAddBin( - PHHIVE RegistryHive, - ULONG Size, - HV_STORAGE_TYPE Storage) -{ - PHMAP_ENTRY BlockList; - PHBIN Bin; - SIZE_T BinSize; - ULONG i; - ULONG BitmapSize; - ULONG BlockCount; - ULONG OldBlockListSize; - PHCELL Block; - - BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE); - BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE); - - Bin = RegistryHive->Allocate(BinSize, TRUE); - if (Bin == NULL) - return NULL; - RtlZeroMemory(Bin, BinSize); - - Bin->Signature = HV_BIN_SIGNATURE; - Bin->FileOffset = RegistryHive->Storage[Storage].Length * - HV_BLOCK_SIZE; - Bin->Size = (ULONG)BinSize; - - /* Allocate new block list */ - OldBlockListSize = RegistryHive->Storage[Storage].Length; - BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) * - (OldBlockListSize + BlockCount), TRUE); - if (BlockList == NULL) - { - RegistryHive->Free(Bin); - return NULL; - } - - if (OldBlockListSize > 0) - { - RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList, - OldBlockListSize * sizeof(HMAP_ENTRY)); - RegistryHive->Free(RegistryHive->Storage[Storage].BlockList); - } - - RegistryHive->Storage[Storage].BlockList = BlockList; - RegistryHive->Storage[Storage].Length += BlockCount; - - for (i = 0; i < BlockCount; i++) - { - RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Block = - ((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE)); - RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Bin = (ULONG_PTR)Bin; - } - - /* Initialize a free block in this heap. */ - Block = (PHCELL)(Bin + 1); - Block->Size = (LONG)(BinSize - sizeof(HBIN)); - - if (Storage == HvStable) - { - /* Calculate bitmap size in bytes (always a multiple of 32 bits). */ - BitmapSize = ROUND_UP(RegistryHive->Storage[HvStable].Length, - sizeof(ULONG) * 8) / 8; - - /* Grow bitmap if necessary. */ - if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8) - { - PULONG BitmapBuffer; - - BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE); - RtlZeroMemory(BitmapBuffer, BitmapSize); - RtlCopyMemory(BitmapBuffer, - RegistryHive->DirtyVector.Buffer, - RegistryHive->DirtyVector.SizeOfBitMap / 8); - RegistryHive->Free(RegistryHive->DirtyVector.Buffer); - RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer, - BitmapSize * 8); - } - - /* Mark new bin dirty. */ - RtlSetBits(&RegistryHive->DirtyVector, - Bin->FileOffset / HV_BLOCK_SIZE, - BlockCount); - } - - return Bin; -} +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2005 Hartmut Birr + * Copyright 2001 - 2005 Eric Kohl + */ + +#include "cmlib.h" + +PHBIN CMAPI +HvpAddBin( + PHHIVE RegistryHive, + ULONG Size, + HV_STORAGE_TYPE Storage) +{ + PHMAP_ENTRY BlockList; + PHBIN Bin; + SIZE_T BinSize; + ULONG i; + ULONG BitmapSize; + ULONG BlockCount; + ULONG OldBlockListSize; + PHCELL Block; + + BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE); + BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE); + + Bin = RegistryHive->Allocate(BinSize, TRUE); + if (Bin == NULL) + return NULL; + RtlZeroMemory(Bin, BinSize); + + Bin->Signature = HV_BIN_SIGNATURE; + Bin->FileOffset = RegistryHive->Storage[Storage].Length * + HV_BLOCK_SIZE; + Bin->Size = (ULONG)BinSize; + + /* Allocate new block list */ + OldBlockListSize = RegistryHive->Storage[Storage].Length; + BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) * + (OldBlockListSize + BlockCount), TRUE); + if (BlockList == NULL) + { + RegistryHive->Free(Bin); + return NULL; + } + + if (OldBlockListSize > 0) + { + RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList, + OldBlockListSize * sizeof(HMAP_ENTRY)); + RegistryHive->Free(RegistryHive->Storage[Storage].BlockList); + } + + RegistryHive->Storage[Storage].BlockList = BlockList; + RegistryHive->Storage[Storage].Length += BlockCount; + + for (i = 0; i < BlockCount; i++) + { + RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Block = + ((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE)); + RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Bin = (ULONG_PTR)Bin; + } + + /* Initialize a free block in this heap. */ + Block = (PHCELL)(Bin + 1); + Block->Size = (LONG)(BinSize - sizeof(HBIN)); + + if (Storage == HvStable) + { + /* Calculate bitmap size in bytes (always a multiple of 32 bits). */ + BitmapSize = ROUND_UP(RegistryHive->Storage[HvStable].Length, + sizeof(ULONG) * 8) / 8; + + /* Grow bitmap if necessary. */ + if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8) + { + PULONG BitmapBuffer; + + BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE); + RtlZeroMemory(BitmapBuffer, BitmapSize); + RtlCopyMemory(BitmapBuffer, + RegistryHive->DirtyVector.Buffer, + RegistryHive->DirtyVector.SizeOfBitMap / 8); + RegistryHive->Free(RegistryHive->DirtyVector.Buffer); + RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer, + BitmapSize * 8); + } + + /* Mark new bin dirty. */ + RtlSetBits(&RegistryHive->DirtyVector, + Bin->FileOffset / HV_BLOCK_SIZE, + BlockCount); + } + + return Bin; +} diff --git a/reactos/lib/cmlib/hivecell.c b/reactos/lib/cmlib/hivecell.c index 1e84baff5ec..d829bc895f3 100644 --- a/reactos/lib/cmlib/hivecell.c +++ b/reactos/lib/cmlib/hivecell.c @@ -1,429 +1,429 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2001 - 2005 Eric Kohl - */ - -#include "cmlib.h" -#define NDEBUG -#include - -static PHCELL __inline CMAPI -HvpGetCellHeader( - PHHIVE RegistryHive, - HCELL_INDEX CellIndex) -{ - PVOID Block; - - ASSERT(CellIndex != HCELL_NULL); - if (!RegistryHive->Flat) - { - ULONG CellType; - ULONG CellBlock; - ULONG CellOffset; - - CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; - CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; - CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT; - ASSERT(CellBlock < RegistryHive->Storage[CellType].Length); - Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].Block; - ASSERT(Block != NULL); - return (PVOID)((ULONG_PTR)Block + CellOffset); - } - else - { - ASSERT((CellIndex & HCELL_TYPE_MASK) == HvStable); - return (PVOID)((ULONG_PTR)RegistryHive->HiveHeader + HV_BLOCK_SIZE + - CellIndex); - } -} - -PVOID CMAPI -HvGetCell( - PHHIVE RegistryHive, - HCELL_INDEX CellIndex) -{ - return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1); -} - -static LONG __inline CMAPI -HvpGetCellFullSize( - PHHIVE RegistryHive, - PVOID Cell) -{ - return ((PHCELL)Cell - 1)->Size; -} - -LONG CMAPI -HvGetCellSize( - PHHIVE RegistryHive, - PVOID Cell) -{ - PHCELL CellHeader; - - CellHeader = (PHCELL)Cell - 1; - if (CellHeader->Size < 0) - return CellHeader->Size + sizeof(HCELL); - else - return CellHeader->Size - sizeof(HCELL); -} - -VOID CMAPI -HvMarkCellDirty( - PHHIVE RegistryHive, - HCELL_INDEX CellIndex) -{ - LONG CellSize; - ULONG CellBlock; - ULONG CellLastBlock; - - ASSERT(RegistryHive->ReadOnly == FALSE); - - if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != HvStable) - return; - - CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; - CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; - - CellSize = HvpGetCellFullSize(RegistryHive, HvGetCell(RegistryHive, CellIndex)); - if (CellSize < 0) - CellSize = -CellSize; - - RtlSetBits(&RegistryHive->DirtyVector, - CellBlock, CellLastBlock - CellBlock); -} - -static ULONG __inline CMAPI -HvpComputeFreeListIndex( - ULONG Size) -{ - ULONG Index; - static CCHAR FindFirstSet[256] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; - - Index = (Size >> 3) - 1; - if (Index >= 16) - { - if (Index > 255) - Index = 23; - else - Index = FindFirstSet[Index] + 7; - } - - return Index; -} - -static NTSTATUS CMAPI -HvpAddFree( - PHHIVE RegistryHive, - PHCELL FreeBlock, - HCELL_INDEX FreeIndex) -{ - PHCELL_INDEX FreeBlockData; - HV_STORAGE_TYPE Storage; - ULONG Index; - - ASSERT(RegistryHive != NULL); - ASSERT(FreeBlock != NULL); - - Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; - Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size); - - FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1); - *FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index]; - RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex; - - /* FIXME: Eventually get rid of free bins. */ - - return STATUS_SUCCESS; -} - -static VOID CMAPI -HvpRemoveFree( - PHHIVE RegistryHive, - PHCELL CellBlock, - HCELL_INDEX CellIndex) -{ - PHCELL_INDEX FreeCellData; - PHCELL_INDEX pFreeCellOffset; - HV_STORAGE_TYPE Storage; - ULONG Index; - - ASSERT(RegistryHive->ReadOnly == FALSE); - - Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; - Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size); - - pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index]; - while (*pFreeCellOffset != HCELL_NULL) - { - FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); - if (*pFreeCellOffset == CellIndex) - { - *pFreeCellOffset = *FreeCellData; - return; - } - pFreeCellOffset = FreeCellData; - } - - ASSERT(FALSE); -} - -static HCELL_INDEX CMAPI -HvpFindFree( - PHHIVE RegistryHive, - ULONG Size, - HV_STORAGE_TYPE Storage) -{ - PHCELL_INDEX FreeCellData; - HCELL_INDEX FreeCellOffset; - PHCELL_INDEX pFreeCellOffset; - ULONG Index; - - for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++) - { - pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index]; - while (*pFreeCellOffset != HCELL_NULL) - { - FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); - if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size) - { - FreeCellOffset = *pFreeCellOffset; - *pFreeCellOffset = *FreeCellData; - return FreeCellOffset; - } - pFreeCellOffset = FreeCellData; - } - } - - return HCELL_NULL; -} - -NTSTATUS CMAPI -HvpCreateHiveFreeCellList( - PHHIVE Hive) -{ - HCELL_INDEX BlockOffset; - PHCELL FreeBlock; - ULONG BlockIndex; - ULONG FreeOffset; - PHBIN Bin; - NTSTATUS Status; - ULONG Index; - - /* Initialize the free cell list */ - for (Index = 0; Index < 24; Index++) - { - Hive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL; - Hive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL; - } - - BlockOffset = 0; - BlockIndex = 0; - while (BlockIndex < Hive->Storage[HvStable].Length) - { - Bin = (PHBIN)Hive->Storage[HvStable].BlockList[BlockIndex].Bin; - - /* Search free blocks and add to list */ - FreeOffset = sizeof(HBIN); - while (FreeOffset < Bin->Size) - { - FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset); - if (FreeBlock->Size > 0) - { - Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset); - if (!NT_SUCCESS(Status)) - return Status; - - FreeOffset += FreeBlock->Size; - } - else - { - FreeOffset -= FreeBlock->Size; - } - } - - BlockIndex += Bin->Size / HV_BLOCK_SIZE; - BlockOffset += Bin->Size; - } - - return STATUS_SUCCESS; -} - -HCELL_INDEX CMAPI -HvAllocateCell( - PHHIVE RegistryHive, - ULONG Size, - HV_STORAGE_TYPE Storage) -{ - PHCELL FreeCell; - HCELL_INDEX FreeCellOffset; - PHCELL NewCell; - PHBIN Bin; - - ASSERT(RegistryHive->ReadOnly == FALSE); - - /* Round to 16 bytes multiple. */ - Size = ROUND_UP(Size + sizeof(HCELL), 16); - - /* First search in free blocks. */ - FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage); - - /* If no free cell was found we need to extend the hive file. */ - if (FreeCellOffset == HCELL_NULL) - { - Bin = HvpAddBin(RegistryHive, Size, Storage); - if (Bin == NULL) - return HCELL_NULL; - FreeCellOffset = Bin->FileOffset + sizeof(HBIN); - FreeCellOffset |= Storage << HCELL_TYPE_SHIFT; - } - - FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset); - - /* Split the block in two parts */ - /* FIXME: There is some minimal cell size that we must respect. */ - if ((ULONG)FreeCell->Size > Size + sizeof(HCELL_INDEX)) - { - NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size); - NewCell->Size = FreeCell->Size - Size; - FreeCell->Size = Size; - HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size); - if (Storage == HvStable) - HvMarkCellDirty(RegistryHive, FreeCellOffset + Size); - } - - if (Storage == HvStable) - HvMarkCellDirty(RegistryHive, FreeCellOffset); - FreeCell->Size = -FreeCell->Size; - RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL)); - - return FreeCellOffset; -} - -HCELL_INDEX CMAPI -HvReallocateCell( - PHHIVE RegistryHive, - HCELL_INDEX CellIndex, - ULONG Size) -{ - PVOID OldCell; - PVOID NewCell; - LONG OldCellSize; - HCELL_INDEX NewCellIndex; - HV_STORAGE_TYPE Storage; - - ASSERT(CellIndex != HCELL_NULL); - - Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; - - OldCell = HvGetCell(RegistryHive, CellIndex); - OldCellSize = HvGetCellSize(RegistryHive, OldCell); - ASSERT(OldCellSize < 0); - - /* - * If new data size is larger than the current, destroy current - * data block and allocate a new one. - * - * FIXME: Merge with adjacent free cell if possible. - * FIXME: Implement shrinking. - */ - if (Size > (ULONG)-OldCellSize) - { - NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage); - if (NewCellIndex == HCELL_NULL) - return HCELL_NULL; - - NewCell = HvGetCell(RegistryHive, NewCellIndex); - RtlCopyMemory(NewCell, OldCell, (SIZE_T)-OldCellSize); - - HvFreeCell(RegistryHive, CellIndex); - - return NewCellIndex; - } - - return CellIndex; -} - -VOID CMAPI -HvFreeCell( - PHHIVE RegistryHive, - HCELL_INDEX CellIndex) -{ - PHCELL Free; - PHCELL Neighbor; - PHBIN Bin; - ULONG CellType; - ULONG CellBlock; - - ASSERT(RegistryHive->ReadOnly == FALSE); - - Free = HvpGetCellHeader(RegistryHive, CellIndex); - - ASSERT(Free->Size < 0); - - Free->Size = -Free->Size; - - CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; - CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; - - /* FIXME: Merge free blocks */ - Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].Bin; - - if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size < - Bin->FileOffset + Bin->Size) - { - Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size); - if (Neighbor->Size > 0) - { - HvpRemoveFree(RegistryHive, Neighbor, - ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + - Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK)); - Free->Size += Neighbor->Size; - } - } - - Neighbor = (PHCELL)(Bin + 1); - while (Neighbor < Free) - { - if (Neighbor->Size > 0) - { - if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free) - { - Neighbor->Size += Free->Size; - if (CellType == HvStable) - HvMarkCellDirty(RegistryHive, - (HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + - Bin->FileOffset)); - return; - } - Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size); - } - else - { - Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size); - } - } - - /* Add block to the list of free blocks */ - HvpAddFree(RegistryHive, Free, CellIndex); - - if (CellType == HvStable) - HvMarkCellDirty(RegistryHive, CellIndex); -} +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2001 - 2005 Eric Kohl + */ + +#include "cmlib.h" +#define NDEBUG +#include + +static PHCELL __inline CMAPI +HvpGetCellHeader( + PHHIVE RegistryHive, + HCELL_INDEX CellIndex) +{ + PVOID Block; + + ASSERT(CellIndex != HCELL_NULL); + if (!RegistryHive->Flat) + { + ULONG CellType; + ULONG CellBlock; + ULONG CellOffset; + + CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; + CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; + CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT; + ASSERT(CellBlock < RegistryHive->Storage[CellType].Length); + Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].Block; + ASSERT(Block != NULL); + return (PVOID)((ULONG_PTR)Block + CellOffset); + } + else + { + ASSERT((CellIndex & HCELL_TYPE_MASK) == HvStable); + return (PVOID)((ULONG_PTR)RegistryHive->HiveHeader + HV_BLOCK_SIZE + + CellIndex); + } +} + +PVOID CMAPI +HvGetCell( + PHHIVE RegistryHive, + HCELL_INDEX CellIndex) +{ + return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1); +} + +static LONG __inline CMAPI +HvpGetCellFullSize( + PHHIVE RegistryHive, + PVOID Cell) +{ + return ((PHCELL)Cell - 1)->Size; +} + +LONG CMAPI +HvGetCellSize( + PHHIVE RegistryHive, + PVOID Cell) +{ + PHCELL CellHeader; + + CellHeader = (PHCELL)Cell - 1; + if (CellHeader->Size < 0) + return CellHeader->Size + sizeof(HCELL); + else + return CellHeader->Size - sizeof(HCELL); +} + +VOID CMAPI +HvMarkCellDirty( + PHHIVE RegistryHive, + HCELL_INDEX CellIndex) +{ + LONG CellSize; + ULONG CellBlock; + ULONG CellLastBlock; + + ASSERT(RegistryHive->ReadOnly == FALSE); + + if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != HvStable) + return; + + CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; + CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; + + CellSize = HvpGetCellFullSize(RegistryHive, HvGetCell(RegistryHive, CellIndex)); + if (CellSize < 0) + CellSize = -CellSize; + + RtlSetBits(&RegistryHive->DirtyVector, + CellBlock, CellLastBlock - CellBlock); +} + +static ULONG __inline CMAPI +HvpComputeFreeListIndex( + ULONG Size) +{ + ULONG Index; + static CCHAR FindFirstSet[256] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + + Index = (Size >> 3) - 1; + if (Index >= 16) + { + if (Index > 255) + Index = 23; + else + Index = FindFirstSet[Index] + 7; + } + + return Index; +} + +static NTSTATUS CMAPI +HvpAddFree( + PHHIVE RegistryHive, + PHCELL FreeBlock, + HCELL_INDEX FreeIndex) +{ + PHCELL_INDEX FreeBlockData; + HV_STORAGE_TYPE Storage; + ULONG Index; + + ASSERT(RegistryHive != NULL); + ASSERT(FreeBlock != NULL); + + Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; + Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size); + + FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1); + *FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index]; + RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex; + + /* FIXME: Eventually get rid of free bins. */ + + return STATUS_SUCCESS; +} + +static VOID CMAPI +HvpRemoveFree( + PHHIVE RegistryHive, + PHCELL CellBlock, + HCELL_INDEX CellIndex) +{ + PHCELL_INDEX FreeCellData; + PHCELL_INDEX pFreeCellOffset; + HV_STORAGE_TYPE Storage; + ULONG Index; + + ASSERT(RegistryHive->ReadOnly == FALSE); + + Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; + Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size); + + pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index]; + while (*pFreeCellOffset != HCELL_NULL) + { + FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); + if (*pFreeCellOffset == CellIndex) + { + *pFreeCellOffset = *FreeCellData; + return; + } + pFreeCellOffset = FreeCellData; + } + + ASSERT(FALSE); +} + +static HCELL_INDEX CMAPI +HvpFindFree( + PHHIVE RegistryHive, + ULONG Size, + HV_STORAGE_TYPE Storage) +{ + PHCELL_INDEX FreeCellData; + HCELL_INDEX FreeCellOffset; + PHCELL_INDEX pFreeCellOffset; + ULONG Index; + + for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++) + { + pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index]; + while (*pFreeCellOffset != HCELL_NULL) + { + FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); + if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size) + { + FreeCellOffset = *pFreeCellOffset; + *pFreeCellOffset = *FreeCellData; + return FreeCellOffset; + } + pFreeCellOffset = FreeCellData; + } + } + + return HCELL_NULL; +} + +NTSTATUS CMAPI +HvpCreateHiveFreeCellList( + PHHIVE Hive) +{ + HCELL_INDEX BlockOffset; + PHCELL FreeBlock; + ULONG BlockIndex; + ULONG FreeOffset; + PHBIN Bin; + NTSTATUS Status; + ULONG Index; + + /* Initialize the free cell list */ + for (Index = 0; Index < 24; Index++) + { + Hive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL; + Hive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL; + } + + BlockOffset = 0; + BlockIndex = 0; + while (BlockIndex < Hive->Storage[HvStable].Length) + { + Bin = (PHBIN)Hive->Storage[HvStable].BlockList[BlockIndex].Bin; + + /* Search free blocks and add to list */ + FreeOffset = sizeof(HBIN); + while (FreeOffset < Bin->Size) + { + FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset); + if (FreeBlock->Size > 0) + { + Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset); + if (!NT_SUCCESS(Status)) + return Status; + + FreeOffset += FreeBlock->Size; + } + else + { + FreeOffset -= FreeBlock->Size; + } + } + + BlockIndex += Bin->Size / HV_BLOCK_SIZE; + BlockOffset += Bin->Size; + } + + return STATUS_SUCCESS; +} + +HCELL_INDEX CMAPI +HvAllocateCell( + PHHIVE RegistryHive, + ULONG Size, + HV_STORAGE_TYPE Storage) +{ + PHCELL FreeCell; + HCELL_INDEX FreeCellOffset; + PHCELL NewCell; + PHBIN Bin; + + ASSERT(RegistryHive->ReadOnly == FALSE); + + /* Round to 16 bytes multiple. */ + Size = ROUND_UP(Size + sizeof(HCELL), 16); + + /* First search in free blocks. */ + FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage); + + /* If no free cell was found we need to extend the hive file. */ + if (FreeCellOffset == HCELL_NULL) + { + Bin = HvpAddBin(RegistryHive, Size, Storage); + if (Bin == NULL) + return HCELL_NULL; + FreeCellOffset = Bin->FileOffset + sizeof(HBIN); + FreeCellOffset |= Storage << HCELL_TYPE_SHIFT; + } + + FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset); + + /* Split the block in two parts */ + /* FIXME: There is some minimal cell size that we must respect. */ + if ((ULONG)FreeCell->Size > Size + sizeof(HCELL_INDEX)) + { + NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size); + NewCell->Size = FreeCell->Size - Size; + FreeCell->Size = Size; + HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size); + if (Storage == HvStable) + HvMarkCellDirty(RegistryHive, FreeCellOffset + Size); + } + + if (Storage == HvStable) + HvMarkCellDirty(RegistryHive, FreeCellOffset); + FreeCell->Size = -FreeCell->Size; + RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL)); + + return FreeCellOffset; +} + +HCELL_INDEX CMAPI +HvReallocateCell( + PHHIVE RegistryHive, + HCELL_INDEX CellIndex, + ULONG Size) +{ + PVOID OldCell; + PVOID NewCell; + LONG OldCellSize; + HCELL_INDEX NewCellIndex; + HV_STORAGE_TYPE Storage; + + ASSERT(CellIndex != HCELL_NULL); + + Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; + + OldCell = HvGetCell(RegistryHive, CellIndex); + OldCellSize = HvGetCellSize(RegistryHive, OldCell); + ASSERT(OldCellSize < 0); + + /* + * If new data size is larger than the current, destroy current + * data block and allocate a new one. + * + * FIXME: Merge with adjacent free cell if possible. + * FIXME: Implement shrinking. + */ + if (Size > (ULONG)-OldCellSize) + { + NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage); + if (NewCellIndex == HCELL_NULL) + return HCELL_NULL; + + NewCell = HvGetCell(RegistryHive, NewCellIndex); + RtlCopyMemory(NewCell, OldCell, (SIZE_T)-OldCellSize); + + HvFreeCell(RegistryHive, CellIndex); + + return NewCellIndex; + } + + return CellIndex; +} + +VOID CMAPI +HvFreeCell( + PHHIVE RegistryHive, + HCELL_INDEX CellIndex) +{ + PHCELL Free; + PHCELL Neighbor; + PHBIN Bin; + ULONG CellType; + ULONG CellBlock; + + ASSERT(RegistryHive->ReadOnly == FALSE); + + Free = HvpGetCellHeader(RegistryHive, CellIndex); + + ASSERT(Free->Size < 0); + + Free->Size = -Free->Size; + + CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; + CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; + + /* FIXME: Merge free blocks */ + Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].Bin; + + if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size < + Bin->FileOffset + Bin->Size) + { + Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size); + if (Neighbor->Size > 0) + { + HvpRemoveFree(RegistryHive, Neighbor, + ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + + Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK)); + Free->Size += Neighbor->Size; + } + } + + Neighbor = (PHCELL)(Bin + 1); + while (Neighbor < Free) + { + if (Neighbor->Size > 0) + { + if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free) + { + Neighbor->Size += Free->Size; + if (CellType == HvStable) + HvMarkCellDirty(RegistryHive, + (HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + + Bin->FileOffset)); + return; + } + Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size); + } + else + { + Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size); + } + } + + /* Add block to the list of free blocks */ + HvpAddFree(RegistryHive, Free, CellIndex); + + if (CellType == HvStable) + HvMarkCellDirty(RegistryHive, CellIndex); +} diff --git a/reactos/lib/cmlib/hivedata.h b/reactos/lib/cmlib/hivedata.h index 3857158bc1c..751c0243a2b 100644 --- a/reactos/lib/cmlib/hivedata.h +++ b/reactos/lib/cmlib/hivedata.h @@ -30,7 +30,6 @@ * the other bits specify index into the hive file. The value HCELL_NULL * (-1) is reserved for marking invalid cells. */ - typedef ULONG HCELL_INDEX, *PHCELL_INDEX; #define HCELL_NULL ((HCELL_INDEX)-1) diff --git a/reactos/lib/cmlib/hiveinit.c b/reactos/lib/cmlib/hiveinit.c index 56997b6ca65..4b44e5ce63e 100644 --- a/reactos/lib/cmlib/hiveinit.c +++ b/reactos/lib/cmlib/hiveinit.c @@ -1,390 +1,391 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2001 - 2005 Eric Kohl - */ - -#include "cmlib.h" -#define NDEBUG -#include - -/** - * @name HvpVerifyHiveHeader - * - * Internal function to verify that a hive header has valid format. - */ - -BOOLEAN CMAPI -HvpVerifyHiveHeader( - PHBASE_BLOCK HiveHeader) -{ - if (HiveHeader->Signature != HV_SIGNATURE || - HiveHeader->Major != HV_MAJOR_VER || - HiveHeader->Minor < HV_MINOR_VER || - HiveHeader->Type != HV_TYPE_PRIMARY || - HiveHeader->Format != HV_FORMAT_MEMORY || - HiveHeader->Cluster != 1 || - HiveHeader->Sequence1 != HiveHeader->Sequence2 || - HvpHiveHeaderChecksum(HiveHeader) != HiveHeader->Checksum) - { - DPRINT1("Verify Hive Header failed: \n"); - DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n", - HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER); - DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n", - HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY); - DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n", - HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster); - DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n", - HiveHeader->Sequence1, HiveHeader->Sequence2, - HvpHiveHeaderChecksum(HiveHeader), HiveHeader->Checksum); - return FALSE; - } - - return TRUE; -} - -/** - * @name HvpFreeHiveBins - * - * Internal function to free all bin storage associated with hive - * descriptor. - */ - -VOID CMAPI -HvpFreeHiveBins( - PHHIVE Hive) -{ - ULONG i; - PHBIN Bin; - ULONG Storage; - - for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) - { - Bin = NULL; - for (i = 0; i < Hive->Storage[Storage].Length; i++) - { - if (Hive->Storage[Storage].BlockList[i].Bin == (ULONG_PTR)NULL) - continue; - if (Hive->Storage[Storage].BlockList[i].Bin != (ULONG_PTR)Bin) - { - Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].Bin; - Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].Bin); - } - Hive->Storage[Storage].BlockList[i].Bin = (ULONG_PTR)NULL; - Hive->Storage[Storage].BlockList[i].Block = (ULONG_PTR)NULL; - } - - if (Hive->Storage[Storage].Length) - Hive->Free(Hive->Storage[Storage].BlockList); - } -} - -/** - * @name HvpCreateHive - * - * Internal helper function to initalize hive descriptor structure for - * newly created hive. - * - * @see HvInitialize - */ - -NTSTATUS CMAPI -HvpCreateHive( - PHHIVE RegistryHive) -{ - PHBASE_BLOCK HiveHeader; - ULONG Index; - - HiveHeader = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE); - if (HiveHeader == NULL) - return STATUS_NO_MEMORY; - RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK)); - HiveHeader->Signature = HV_SIGNATURE; - HiveHeader->Major = HV_MAJOR_VER; - HiveHeader->Minor = HV_MINOR_VER; - HiveHeader->Type = HV_TYPE_PRIMARY; - HiveHeader->Format = HV_FORMAT_MEMORY; - HiveHeader->Cluster = 1; - HiveHeader->RootCell = HCELL_NULL; - HiveHeader->Length = HV_BLOCK_SIZE; - HiveHeader->Sequence1 = 1; - HiveHeader->Sequence2 = 1; - /* FIXME: Fill in the file name */ - HiveHeader->Checksum = HvpHiveHeaderChecksum(HiveHeader); - - RegistryHive->HiveHeader = HiveHeader; - for (Index = 0; Index < 24; Index++) - { - RegistryHive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL; - RegistryHive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL; - } - RtlInitializeBitMap(&RegistryHive->DirtyVector, NULL, 0); - - return STATUS_SUCCESS; -} - -/** - * @name HvpInitializeMemoryHive - * - * Internal helper function to initalize hive descriptor structure for - * a hive stored in memory. The data of the hive are copied and it is - * prepared for read/write access. - * - * @see HvInitialize - */ - -NTSTATUS CMAPI -HvpInitializeMemoryHive( - PHHIVE Hive, - ULONG_PTR ChunkBase) -{ - SIZE_T BlockIndex; - PHBIN Bin, NewBin; - ULONG i; - ULONG BitmapSize; - PULONG BitmapBuffer; - SIZE_T ChunkSize; - - // - // This hack is similar in magnitude to the US's National Debt - // - ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length; - ((PHBASE_BLOCK)ChunkBase)->Length = HV_BLOCK_SIZE; - DPRINT("ChunkSize: %lx\n", ChunkSize); - - if (ChunkSize < sizeof(HBASE_BLOCK) || - !HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) - { - DPRINT1("Registry is corrupt: ChunkSize %d < sizeof(HBASE_BLOCK) %d, " - "or HvpVerifyHiveHeader() failed\n", ChunkSize, sizeof(HBASE_BLOCK)); - return STATUS_REGISTRY_CORRUPT; - } - - Hive->HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE); - if (Hive->HiveHeader == NULL) - { - return STATUS_NO_MEMORY; - } - RtlCopyMemory(Hive->HiveHeader, (PVOID)ChunkBase, sizeof(HBASE_BLOCK)); - - /* - * Build a block list from the in-memory chunk and copy the data as - * we go. - */ - - Hive->Storage[HvStable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1; - Hive->Storage[HvStable].BlockList = - Hive->Allocate(Hive->Storage[HvStable].Length * - sizeof(HMAP_ENTRY), FALSE); - if (Hive->Storage[HvStable].BlockList == NULL) - { - DPRINT1("Allocating block list failed\n"); - Hive->Free(Hive->HiveHeader); - return STATUS_NO_MEMORY; - } - - for (BlockIndex = 0; BlockIndex < Hive->Storage[HvStable].Length; ) - { - Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE); - if (Bin->Signature != HV_BIN_SIGNATURE || - (Bin->Size % HV_BLOCK_SIZE) != 0) - { - Hive->Free(Hive->HiveHeader); - Hive->Free(Hive->Storage[HvStable].BlockList); - return STATUS_REGISTRY_CORRUPT; - } - - NewBin = Hive->Allocate(Bin->Size, TRUE); - if (NewBin == NULL) - { - Hive->Free(Hive->HiveHeader); - Hive->Free(Hive->Storage[HvStable].BlockList); - return STATUS_NO_MEMORY; - } - - Hive->Storage[HvStable].BlockList[BlockIndex].Bin = (ULONG_PTR)NewBin; - Hive->Storage[HvStable].BlockList[BlockIndex].Block = (ULONG_PTR)NewBin; - - RtlCopyMemory(NewBin, Bin, Bin->Size); - - if (Bin->Size > HV_BLOCK_SIZE) - { - for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++) - { - Hive->Storage[HvStable].BlockList[BlockIndex + i].Bin = (ULONG_PTR)NewBin; - Hive->Storage[HvStable].BlockList[BlockIndex + i].Block = - ((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE)); - } - } - - BlockIndex += Bin->Size / HV_BLOCK_SIZE; - } - - if (HvpCreateHiveFreeCellList(Hive)) - { - HvpFreeHiveBins(Hive); - Hive->Free(Hive->HiveHeader); - return STATUS_NO_MEMORY; - } - - BitmapSize = ROUND_UP(Hive->Storage[HvStable].Length, - sizeof(ULONG) * 8) / 8; - BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE); - if (BitmapBuffer == NULL) - { - HvpFreeHiveBins(Hive); - Hive->Free(Hive->HiveHeader); - return STATUS_NO_MEMORY; - } - - RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8); - RtlClearAllBits(&Hive->DirtyVector); - - return STATUS_SUCCESS; -} - -/** - * @name HvpInitializeMemoryInplaceHive - * - * Internal helper function to initalize hive descriptor structure for - * a hive stored in memory. The in-memory data of the hive are directly - * used and it is read-only accessible. - * - * @see HvInitialize - */ - -NTSTATUS CMAPI -HvpInitializeMemoryInplaceHive( - PHHIVE Hive, - ULONG_PTR ChunkBase) -{ - if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) - { - return STATUS_REGISTRY_CORRUPT; - } - - Hive->HiveHeader = (PHBASE_BLOCK)ChunkBase; - Hive->ReadOnly = TRUE; - Hive->Flat = TRUE; - - return STATUS_SUCCESS; -} - -/** - * @name HvInitialize - * - * Allocate a new hive descriptor structure and intialize it. - * - * @param RegistryHive - * Output variable to store pointer to the hive descriptor. - * @param Operation - * - HV_OPERATION_CREATE_HIVE - * Create a new hive for read/write access. - * - HV_OPERATION_MEMORY - * Load and copy in-memory hive for read/write access. The - * pointer to data passed to this routine can be freed after - * the function is executed. - * - HV_OPERATION_MEMORY_INPLACE - * Load an in-memory hive for read-only access. The pointer - * to data passed to this routine MUSTN'T be freed until - * HvFree is called. - * @param ChunkBase - * Pointer to hive data. - * @param ChunkSize - * Size of passed hive data. - * - * @return - * STATUS_NO_MEMORY - A memory allocation failed. - * STATUS_REGISTRY_CORRUPT - Registry corruption was detected. - * STATUS_SUCCESS - * - * @see HvFree - */ - -NTSTATUS CMAPI -HvInitialize( - PHHIVE RegistryHive, - ULONG Operation, - ULONG HiveType, - ULONG HiveFlags, - ULONG_PTR HiveData OPTIONAL, - ULONG Cluster OPTIONAL, - PALLOCATE_ROUTINE Allocate, - PFREE_ROUTINE Free, - PFILE_READ_ROUTINE FileRead, - PFILE_WRITE_ROUTINE FileWrite, - PFILE_SET_SIZE_ROUTINE FileSetSize, - PFILE_FLUSH_ROUTINE FileFlush, - IN PUNICODE_STRING FileName) -{ - NTSTATUS Status; - PHHIVE Hive = RegistryHive; - - /* - * Create a new hive structure that will hold all the maintenance data. - */ - - RtlZeroMemory(Hive, sizeof(HHIVE)); - - Hive->Allocate = Allocate; - Hive->Free = Free; - Hive->FileRead = FileRead; - Hive->FileWrite = FileWrite; - Hive->FileSetSize = FileSetSize; - Hive->FileFlush = FileFlush; - - switch (Operation) - { - case HV_OPERATION_CREATE_HIVE: - Status = HvpCreateHive(Hive); - break; - - case HV_OPERATION_MEMORY: - Status = HvpInitializeMemoryHive(Hive, HiveData); - break; - - case HV_OPERATION_MEMORY_INPLACE: - Status = HvpInitializeMemoryInplaceHive(Hive, HiveData); - break; - - default: - /* FIXME: A better return status value is needed */ - Status = STATUS_NOT_IMPLEMENTED; - ASSERT(FALSE); - } - - if (!NT_SUCCESS(Status)) - { - Hive->Free(Hive); - return Status; - } - - return Status; -} - -/** - * @name HvFree - * - * Free all stroage and handles associated with hive descriptor. - */ - -VOID CMAPI -HvFree( - PHHIVE RegistryHive) -{ - if (!RegistryHive->ReadOnly) - { - /* Release hive bitmap */ - if (RegistryHive->DirtyVector.Buffer) - { - RegistryHive->Free(RegistryHive->DirtyVector.Buffer); - } - - HvpFreeHiveBins(RegistryHive); - } - - RegistryHive->Free(RegistryHive); -} - -/* EOF */ +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2001 - 2005 Eric Kohl + */ + +#include "cmlib.h" +#define NDEBUG +#include + +/** + * @name HvpVerifyHiveHeader + * + * Internal function to verify that a hive header has valid format. + */ + +BOOLEAN CMAPI +HvpVerifyHiveHeader( + PHBASE_BLOCK HiveHeader) +{ + if (HiveHeader->Signature != HV_SIGNATURE || + HiveHeader->Major != HV_MAJOR_VER || + HiveHeader->Minor < HV_MINOR_VER || + HiveHeader->Type != HV_TYPE_PRIMARY || + HiveHeader->Format != HV_FORMAT_MEMORY || + HiveHeader->Cluster != 1 || + HiveHeader->Sequence1 != HiveHeader->Sequence2 || + HvpHiveHeaderChecksum(HiveHeader) != HiveHeader->Checksum) + { + DPRINT1("Verify Hive Header failed: \n"); + DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n", + HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER); + DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n", + HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY); + DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n", + HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster); + DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n", + HiveHeader->Sequence1, HiveHeader->Sequence2, + HvpHiveHeaderChecksum(HiveHeader), HiveHeader->Checksum); + return FALSE; + } + + return TRUE; +} + +/** + * @name HvpFreeHiveBins + * + * Internal function to free all bin storage associated with hive + * descriptor. + */ + +VOID CMAPI +HvpFreeHiveBins( + PHHIVE Hive) +{ + ULONG i; + PHBIN Bin; + ULONG Storage; + + for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) + { + Bin = NULL; + for (i = 0; i < Hive->Storage[Storage].Length; i++) + { + if (Hive->Storage[Storage].BlockList[i].Bin == (ULONG_PTR)NULL) + continue; + if (Hive->Storage[Storage].BlockList[i].Bin != (ULONG_PTR)Bin) + { + Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].Bin; + Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].Bin); + } + Hive->Storage[Storage].BlockList[i].Bin = (ULONG_PTR)NULL; + Hive->Storage[Storage].BlockList[i].Block = (ULONG_PTR)NULL; + } + + if (Hive->Storage[Storage].Length) + Hive->Free(Hive->Storage[Storage].BlockList); + } +} + +/** + * @name HvpCreateHive + * + * Internal helper function to initalize hive descriptor structure for + * newly created hive. + * + * @see HvInitialize + */ + +NTSTATUS CMAPI +HvpCreateHive( + PHHIVE RegistryHive) +{ + PHBASE_BLOCK HiveHeader; + ULONG Index; + + HiveHeader = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE); + if (HiveHeader == NULL) + return STATUS_NO_MEMORY; + RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK)); + HiveHeader->Signature = HV_SIGNATURE; + HiveHeader->Major = HV_MAJOR_VER; + HiveHeader->Minor = HV_MINOR_VER; + HiveHeader->Type = HV_TYPE_PRIMARY; + HiveHeader->Format = HV_FORMAT_MEMORY; + HiveHeader->Cluster = 1; + HiveHeader->RootCell = HCELL_NULL; + HiveHeader->Length = HV_BLOCK_SIZE; + HiveHeader->Sequence1 = 1; + HiveHeader->Sequence2 = 1; + /* FIXME: Fill in the file name */ + HiveHeader->Checksum = HvpHiveHeaderChecksum(HiveHeader); + + RegistryHive->HiveHeader = HiveHeader; + for (Index = 0; Index < 24; Index++) + { + RegistryHive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL; + RegistryHive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL; + } + RtlInitializeBitMap(&RegistryHive->DirtyVector, NULL, 0); + + return STATUS_SUCCESS; +} + +/** + * @name HvpInitializeMemoryHive + * + * Internal helper function to initalize hive descriptor structure for + * a hive stored in memory. The data of the hive are copied and it is + * prepared for read/write access. + * + * @see HvInitialize + */ + +NTSTATUS CMAPI +HvpInitializeMemoryHive( + PHHIVE Hive, + ULONG_PTR ChunkBase) +{ + SIZE_T BlockIndex; + PHBIN Bin, NewBin; + ULONG i; + ULONG BitmapSize; + PULONG BitmapBuffer; + SIZE_T ChunkSize; + + // + // This hack is similar in magnitude to the US's National Debt + // + ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length; + ((PHBASE_BLOCK)ChunkBase)->Length = HV_BLOCK_SIZE; + DPRINT("ChunkSize: %lx\n", ChunkSize); + + if (ChunkSize < sizeof(HBASE_BLOCK) || + !HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) + { + DPRINT1("Registry is corrupt: ChunkSize %d < sizeof(HBASE_BLOCK) %d, " + "or HvpVerifyHiveHeader() failed\n", ChunkSize, sizeof(HBASE_BLOCK)); + return STATUS_REGISTRY_CORRUPT; + } + + Hive->HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE); + if (Hive->HiveHeader == NULL) + { + return STATUS_NO_MEMORY; + } + RtlCopyMemory(Hive->HiveHeader, (PVOID)ChunkBase, sizeof(HBASE_BLOCK)); + + /* + * Build a block list from the in-memory chunk and copy the data as + * we go. + */ + + Hive->Storage[HvStable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1; + Hive->Storage[HvStable].BlockList = + Hive->Allocate(Hive->Storage[HvStable].Length * + sizeof(HMAP_ENTRY), FALSE); + if (Hive->Storage[HvStable].BlockList == NULL) + { + DPRINT1("Allocating block list failed\n"); + Hive->Free(Hive->HiveHeader); + return STATUS_NO_MEMORY; + } + + for (BlockIndex = 0; BlockIndex < Hive->Storage[HvStable].Length; ) + { + Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE); + if (Bin->Signature != HV_BIN_SIGNATURE || + (Bin->Size % HV_BLOCK_SIZE) != 0) + { + Hive->Free(Hive->HiveHeader); + Hive->Free(Hive->Storage[HvStable].BlockList); + return STATUS_REGISTRY_CORRUPT; + } + + NewBin = Hive->Allocate(Bin->Size, TRUE); + if (NewBin == NULL) + { + Hive->Free(Hive->HiveHeader); + Hive->Free(Hive->Storage[HvStable].BlockList); + return STATUS_NO_MEMORY; + } + + Hive->Storage[HvStable].BlockList[BlockIndex].Bin = (ULONG_PTR)NewBin; + Hive->Storage[HvStable].BlockList[BlockIndex].Block = (ULONG_PTR)NewBin; + + RtlCopyMemory(NewBin, Bin, Bin->Size); + + if (Bin->Size > HV_BLOCK_SIZE) + { + for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++) + { + Hive->Storage[HvStable].BlockList[BlockIndex + i].Bin = (ULONG_PTR)NewBin; + Hive->Storage[HvStable].BlockList[BlockIndex + i].Block = + ((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE)); + } + } + + BlockIndex += Bin->Size / HV_BLOCK_SIZE; + } + + if (HvpCreateHiveFreeCellList(Hive)) + { + HvpFreeHiveBins(Hive); + Hive->Free(Hive->HiveHeader); + return STATUS_NO_MEMORY; + } + + BitmapSize = ROUND_UP(Hive->Storage[HvStable].Length, + sizeof(ULONG) * 8) / 8; + BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE); + if (BitmapBuffer == NULL) + { + HvpFreeHiveBins(Hive); + Hive->Free(Hive->HiveHeader); + return STATUS_NO_MEMORY; + } + + RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8); + RtlClearAllBits(&Hive->DirtyVector); + + return STATUS_SUCCESS; +} + +/** + * @name HvpInitializeMemoryInplaceHive + * + * Internal helper function to initalize hive descriptor structure for + * a hive stored in memory. The in-memory data of the hive are directly + * used and it is read-only accessible. + * + * @see HvInitialize + */ + +NTSTATUS CMAPI +HvpInitializeMemoryInplaceHive( + PHHIVE Hive, + ULONG_PTR ChunkBase) +{ + if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) + { + return STATUS_REGISTRY_CORRUPT; + } + + Hive->HiveHeader = (PHBASE_BLOCK)ChunkBase; + Hive->ReadOnly = TRUE; + Hive->Flat = TRUE; + + return STATUS_SUCCESS; +} + +/** + * @name HvInitialize + * + * Allocate a new hive descriptor structure and intialize it. + * + * @param RegistryHive + * Output variable to store pointer to the hive descriptor. + * @param Operation + * - HV_OPERATION_CREATE_HIVE + * Create a new hive for read/write access. + * - HV_OPERATION_MEMORY + * Load and copy in-memory hive for read/write access. The + * pointer to data passed to this routine can be freed after + * the function is executed. + * - HV_OPERATION_MEMORY_INPLACE + * Load an in-memory hive for read-only access. The pointer + * to data passed to this routine MUSTN'T be freed until + * HvFree is called. + * @param ChunkBase + * Pointer to hive data. + * @param ChunkSize + * Size of passed hive data. + * + * @return + * STATUS_NO_MEMORY - A memory allocation failed. + * STATUS_REGISTRY_CORRUPT - Registry corruption was detected. + * STATUS_SUCCESS + * + * @see HvFree + */ + +NTSTATUS CMAPI +HvInitialize( + PHHIVE RegistryHive, + ULONG Operation, + ULONG HiveType, + ULONG HiveFlags, + ULONG_PTR HiveData OPTIONAL, + ULONG Cluster OPTIONAL, + PALLOCATE_ROUTINE Allocate, + PFREE_ROUTINE Free, + PFILE_READ_ROUTINE FileRead, + PFILE_WRITE_ROUTINE FileWrite, + PFILE_SET_SIZE_ROUTINE FileSetSize, + PFILE_FLUSH_ROUTINE FileFlush, + IN PUNICODE_STRING FileName) +{ + NTSTATUS Status; + PHHIVE Hive = RegistryHive; + + /* + * Create a new hive structure that will hold all the maintenance data. + */ + + RtlZeroMemory(Hive, sizeof(HHIVE)); + + Hive->Allocate = Allocate; + Hive->Free = Free; + Hive->FileRead = FileRead; + Hive->FileWrite = FileWrite; + Hive->FileSetSize = FileSetSize; + Hive->FileFlush = FileFlush; + Hive->StorageTypeCount = 2; + + switch (Operation) + { + case HV_OPERATION_CREATE_HIVE: + Status = HvpCreateHive(Hive); + break; + + case HV_OPERATION_MEMORY: + Status = HvpInitializeMemoryHive(Hive, HiveData); + break; + + case HV_OPERATION_MEMORY_INPLACE: + Status = HvpInitializeMemoryInplaceHive(Hive, HiveData); + break; + + default: + /* FIXME: A better return status value is needed */ + Status = STATUS_NOT_IMPLEMENTED; + ASSERT(FALSE); + } + + if (!NT_SUCCESS(Status)) + { + Hive->Free(Hive); + return Status; + } + + return Status; +} + +/** + * @name HvFree + * + * Free all stroage and handles associated with hive descriptor. + */ + +VOID CMAPI +HvFree( + PHHIVE RegistryHive) +{ + if (!RegistryHive->ReadOnly) + { + /* Release hive bitmap */ + if (RegistryHive->DirtyVector.Buffer) + { + RegistryHive->Free(RegistryHive->DirtyVector.Buffer); + } + + HvpFreeHiveBins(RegistryHive); + } + + RegistryHive->Free(RegistryHive); +} + +/* EOF */ diff --git a/reactos/lib/cmlib/hivewrt.c b/reactos/lib/cmlib/hivewrt.c index 62fcfe75522..e1d1c11e752 100644 --- a/reactos/lib/cmlib/hivewrt.c +++ b/reactos/lib/cmlib/hivewrt.c @@ -1,277 +1,277 @@ -/* - * PROJECT: registry manipulation library - * LICENSE: GPL - See COPYING in the top level directory - * COPYRIGHT: Copyright 2005 Filip Navara - * Copyright 2001 - 2005 Eric Kohl - */ - -#include "cmlib.h" -#define NDEBUG -#include - -static BOOLEAN CMAPI -HvpWriteLog( - PHHIVE RegistryHive) -{ - ULONGLONG FileOffset; - SIZE_T BufferSize; - SIZE_T BitmapSize; - PUCHAR Buffer; - PUCHAR Ptr; - ULONG BlockIndex; - ULONG LastIndex; - PVOID BlockPtr; - BOOLEAN Success; - - ASSERT(RegistryHive->ReadOnly == FALSE); - - DPRINT("HvpWriteLog called\n"); - - if (RegistryHive->HiveHeader->Sequence1 != - RegistryHive->HiveHeader->Sequence2) - { - return FALSE; - } - - BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap; - BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize; - BufferSize = ROUND_UP(BufferSize, HV_BLOCK_SIZE); - - DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize); - - Buffer = RegistryHive->Allocate(BufferSize, TRUE); - if (Buffer == NULL) - { - return FALSE; - } - - /* Update first update counter and checksum */ - RegistryHive->HiveHeader->Type = HV_TYPE_LOG; - RegistryHive->HiveHeader->Sequence1++; - RegistryHive->HiveHeader->Checksum = - HvpHiveHeaderChecksum(RegistryHive->HiveHeader); - - /* Copy hive header */ - RtlCopyMemory(Buffer, RegistryHive->HiveHeader, HV_LOG_HEADER_SIZE); - Ptr = Buffer + HV_LOG_HEADER_SIZE; - RtlCopyMemory(Ptr, "DIRT", 4); - Ptr += 4; - RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize); - - /* Write hive block and block bitmap */ - Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, - 0, Buffer, BufferSize); - if (!Success) - { - return FALSE; - } - - RegistryHive->Free(Buffer); - - /* Write dirty blocks */ - FileOffset = BufferSize; - BlockIndex = 0; - while (BlockIndex < RegistryHive->Storage[HvStable].Length) - { - LastIndex = BlockIndex; - BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex); - if (BlockIndex == ~0 || BlockIndex < LastIndex) - { - break; - } - - BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block; - - /* Write hive block */ - Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, - FileOffset, BlockPtr, - HV_BLOCK_SIZE); - if (!Success) - { - return FALSE; - } - - BlockIndex++; - FileOffset += HV_BLOCK_SIZE; - } - - Success = RegistryHive->FileSetSize(RegistryHive, HV_TYPE_LOG, FileOffset); - if (!Success) - { - DPRINT("FileSetSize failed\n"); - return FALSE; - } - - /* Flush the log file */ - Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG); - if (!Success) - { - DPRINT("FileFlush failed\n"); - } - - /* Update first and second update counter and checksum. */ - RegistryHive->HiveHeader->Sequence2++; - RegistryHive->HiveHeader->Checksum = - HvpHiveHeaderChecksum(RegistryHive->HiveHeader); - - /* Write hive header again with updated sequence counter. */ - Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, - 0, RegistryHive->HiveHeader, - HV_LOG_HEADER_SIZE); - if (!Success) - { - return FALSE; - } - - /* Flush the log file */ - Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG); - if (!Success) - { - DPRINT("FileFlush failed\n"); - } - - return TRUE; -} - -static BOOLEAN CMAPI -HvpWriteHive( - PHHIVE RegistryHive, - BOOLEAN OnlyDirty) -{ - ULONGLONG FileOffset; - ULONG BlockIndex; - ULONG LastIndex; - PVOID BlockPtr; - BOOLEAN Success; - - ASSERT(RegistryHive->ReadOnly == FALSE); - - DPRINT("HvpWriteHive called\n"); - - if (RegistryHive->HiveHeader->Sequence1 != - RegistryHive->HiveHeader->Sequence2) - { - return FALSE; - } - - /* Update first update counter and checksum */ - RegistryHive->HiveHeader->Type = HV_TYPE_PRIMARY; - RegistryHive->HiveHeader->Sequence1++; - RegistryHive->HiveHeader->Checksum = - HvpHiveHeaderChecksum(RegistryHive->HiveHeader); - - /* Write hive block */ - Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, - 0, RegistryHive->HiveHeader, - sizeof(HBASE_BLOCK)); - if (!Success) - { - return FALSE; - } - - BlockIndex = 0; - while (BlockIndex < RegistryHive->Storage[HvStable].Length) - { - if (OnlyDirty) - { - LastIndex = BlockIndex; - BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex); - if (BlockIndex == ~0 || BlockIndex < LastIndex) - { - break; - } - } - - BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block; - FileOffset = (ULONGLONG)(BlockIndex + 1) * (ULONGLONG)HV_BLOCK_SIZE; - - /* Write hive block */ - Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, - FileOffset, BlockPtr, - HV_BLOCK_SIZE); - if (!Success) - { - return FALSE; - } - - BlockIndex++; - } - - Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY); - if (!Success) - { - DPRINT("FileFlush failed\n"); - } - - /* Update second update counter and checksum */ - RegistryHive->HiveHeader->Sequence2++; - RegistryHive->HiveHeader->Checksum = - HvpHiveHeaderChecksum(RegistryHive->HiveHeader); - - /* Write hive block */ - Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, - 0, RegistryHive->HiveHeader, - sizeof(HBASE_BLOCK)); - if (!Success) - { - return FALSE; - } - - Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY); - if (!Success) - { - DPRINT("FileFlush failed\n"); - } - - return TRUE; -} - -BOOLEAN CMAPI -HvSyncHive( - PHHIVE RegistryHive) -{ - ASSERT(RegistryHive->ReadOnly == FALSE); - - if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0) - { - return TRUE; - } - - /* Update hive header modification time */ - KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp); - - /* Update log file */ - if (!HvpWriteLog(RegistryHive)) - { - return FALSE; - } - - /* Update hive file */ - if (!HvpWriteHive(RegistryHive, TRUE)) - { - return FALSE; - } - - /* Clear dirty bitmap. */ - RtlClearAllBits(&RegistryHive->DirtyVector); - - return TRUE; -} - -BOOLEAN CMAPI -HvWriteHive( - PHHIVE RegistryHive) -{ - ASSERT(RegistryHive->ReadOnly == FALSE); - - /* Update hive header modification time */ - KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp); - - /* Update hive file */ - if (!HvpWriteHive(RegistryHive, FALSE)) - { - return FALSE; - } - - return TRUE; -} +/* + * PROJECT: registry manipulation library + * LICENSE: GPL - See COPYING in the top level directory + * COPYRIGHT: Copyright 2005 Filip Navara + * Copyright 2001 - 2005 Eric Kohl + */ + +#include "cmlib.h" +#define NDEBUG +#include + +static BOOLEAN CMAPI +HvpWriteLog( + PHHIVE RegistryHive) +{ + ULONGLONG FileOffset; + SIZE_T BufferSize; + SIZE_T BitmapSize; + PUCHAR Buffer; + PUCHAR Ptr; + ULONG BlockIndex; + ULONG LastIndex; + PVOID BlockPtr; + BOOLEAN Success; + + ASSERT(RegistryHive->ReadOnly == FALSE); + + DPRINT("HvpWriteLog called\n"); + + if (RegistryHive->HiveHeader->Sequence1 != + RegistryHive->HiveHeader->Sequence2) + { + return FALSE; + } + + BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap; + BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize; + BufferSize = ROUND_UP(BufferSize, HV_BLOCK_SIZE); + + DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize); + + Buffer = RegistryHive->Allocate(BufferSize, TRUE); + if (Buffer == NULL) + { + return FALSE; + } + + /* Update first update counter and checksum */ + RegistryHive->HiveHeader->Type = HV_TYPE_LOG; + RegistryHive->HiveHeader->Sequence1++; + RegistryHive->HiveHeader->Checksum = + HvpHiveHeaderChecksum(RegistryHive->HiveHeader); + + /* Copy hive header */ + RtlCopyMemory(Buffer, RegistryHive->HiveHeader, HV_LOG_HEADER_SIZE); + Ptr = Buffer + HV_LOG_HEADER_SIZE; + RtlCopyMemory(Ptr, "DIRT", 4); + Ptr += 4; + RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize); + + /* Write hive block and block bitmap */ + Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, + 0, Buffer, BufferSize); + if (!Success) + { + return FALSE; + } + + RegistryHive->Free(Buffer); + + /* Write dirty blocks */ + FileOffset = BufferSize; + BlockIndex = 0; + while (BlockIndex < RegistryHive->Storage[HvStable].Length) + { + LastIndex = BlockIndex; + BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex); + if (BlockIndex == ~0 || BlockIndex < LastIndex) + { + break; + } + + BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block; + + /* Write hive block */ + Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, + FileOffset, BlockPtr, + HV_BLOCK_SIZE); + if (!Success) + { + return FALSE; + } + + BlockIndex++; + FileOffset += HV_BLOCK_SIZE; + } + + Success = RegistryHive->FileSetSize(RegistryHive, HV_TYPE_LOG, FileOffset); + if (!Success) + { + DPRINT("FileSetSize failed\n"); + return FALSE; + } + + /* Flush the log file */ + Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG); + if (!Success) + { + DPRINT("FileFlush failed\n"); + } + + /* Update first and second update counter and checksum. */ + RegistryHive->HiveHeader->Sequence2++; + RegistryHive->HiveHeader->Checksum = + HvpHiveHeaderChecksum(RegistryHive->HiveHeader); + + /* Write hive header again with updated sequence counter. */ + Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, + 0, RegistryHive->HiveHeader, + HV_LOG_HEADER_SIZE); + if (!Success) + { + return FALSE; + } + + /* Flush the log file */ + Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG); + if (!Success) + { + DPRINT("FileFlush failed\n"); + } + + return TRUE; +} + +static BOOLEAN CMAPI +HvpWriteHive( + PHHIVE RegistryHive, + BOOLEAN OnlyDirty) +{ + ULONGLONG FileOffset; + ULONG BlockIndex; + ULONG LastIndex; + PVOID BlockPtr; + BOOLEAN Success; + + ASSERT(RegistryHive->ReadOnly == FALSE); + + DPRINT("HvpWriteHive called\n"); + + if (RegistryHive->HiveHeader->Sequence1 != + RegistryHive->HiveHeader->Sequence2) + { + return FALSE; + } + + /* Update first update counter and checksum */ + RegistryHive->HiveHeader->Type = HV_TYPE_PRIMARY; + RegistryHive->HiveHeader->Sequence1++; + RegistryHive->HiveHeader->Checksum = + HvpHiveHeaderChecksum(RegistryHive->HiveHeader); + + /* Write hive block */ + Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, + 0, RegistryHive->HiveHeader, + sizeof(HBASE_BLOCK)); + if (!Success) + { + return FALSE; + } + + BlockIndex = 0; + while (BlockIndex < RegistryHive->Storage[HvStable].Length) + { + if (OnlyDirty) + { + LastIndex = BlockIndex; + BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex); + if (BlockIndex == ~0 || BlockIndex < LastIndex) + { + break; + } + } + + BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block; + FileOffset = (ULONGLONG)(BlockIndex + 1) * (ULONGLONG)HV_BLOCK_SIZE; + + /* Write hive block */ + Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, + FileOffset, BlockPtr, + HV_BLOCK_SIZE); + if (!Success) + { + return FALSE; + } + + BlockIndex++; + } + + Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY); + if (!Success) + { + DPRINT("FileFlush failed\n"); + } + + /* Update second update counter and checksum */ + RegistryHive->HiveHeader->Sequence2++; + RegistryHive->HiveHeader->Checksum = + HvpHiveHeaderChecksum(RegistryHive->HiveHeader); + + /* Write hive block */ + Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, + 0, RegistryHive->HiveHeader, + sizeof(HBASE_BLOCK)); + if (!Success) + { + return FALSE; + } + + Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY); + if (!Success) + { + DPRINT("FileFlush failed\n"); + } + + return TRUE; +} + +BOOLEAN CMAPI +HvSyncHive( + PHHIVE RegistryHive) +{ + ASSERT(RegistryHive->ReadOnly == FALSE); + + if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0) + { + return TRUE; + } + + /* Update hive header modification time */ + KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp); + + /* Update log file */ + if (!HvpWriteLog(RegistryHive)) + { + return FALSE; + } + + /* Update hive file */ + if (!HvpWriteHive(RegistryHive, TRUE)) + { + return FALSE; + } + + /* Clear dirty bitmap. */ + RtlClearAllBits(&RegistryHive->DirtyVector); + + return TRUE; +} + +BOOLEAN CMAPI +HvWriteHive( + PHHIVE RegistryHive) +{ + ASSERT(RegistryHive->ReadOnly == FALSE); + + /* Update hive header modification time */ + KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp); + + /* Update hive file */ + if (!HvpWriteHive(RegistryHive, FALSE)) + { + return FALSE; + } + + return TRUE; +} diff --git a/reactos/ntoskrnl/ex/rundown.c b/reactos/ntoskrnl/ex/rundown.c index 2fc1e5d0f04..0176cbb6500 100644 --- a/reactos/ntoskrnl/ex/rundown.c +++ b/reactos/ntoskrnl/ex/rundown.c @@ -13,6 +13,10 @@ #define NDEBUG #include +#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b) +#define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a) +#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a) + /* FUNCTIONS *****************************************************************/ /*++ diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index c0f4de6b140..b73ae275d7c 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -194,9 +194,6 @@ } \ } -#undef FORCEINLINE -#define FORCEINLINE - // // Recalculates the due time // diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 607dadb55e5..f4227735ef0 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -23,6 +23,11 @@ #include "i386/fpu.h" #include "i386/v86m.h" #elif defined(_M_PPC) +#ifndef InterlockedExchangeAddSizeT +#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b) +#define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a) +#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a) +#endif #include "powerpc/mm.h" #else #error "Unknown CPU" @@ -332,4 +337,9 @@ C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_P C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA); #endif +#ifdef _M_PPC +#include +#include +#endif + #endif /* INCLUDE_INTERNAL_NTOSKRNL_H */ diff --git a/reactos/ntoskrnl/include/internal/powerpc/ke.h b/reactos/ntoskrnl/include/internal/powerpc/ke.h index 9cf39b4395c..af43e4106a7 100644 --- a/reactos/ntoskrnl/include/internal/powerpc/ke.h +++ b/reactos/ntoskrnl/include/internal/powerpc/ke.h @@ -131,19 +131,19 @@ __asm__ __volatile__("mfmsr 0\n\t" \ #define KeArchEraseFlags() #define KeArchDisableInterrupts() KePPCDisableInterrupts() -static __inline struct _KPRCB * KeGetCurrentPrcb( +FORCEINLINE struct _KPRCB * KeGetCurrentPrcb( VOID) { return (struct _KPRCB *)__readfsdword(0x20); } -__inline struct _KPCR * NTHALAPI KeGetCurrentKPCR( +FORCEINLINE struct _KPCR * NTHALAPI KeGetCurrentKPCR( VOID) { return (struct _KPCR *)__readfsdword(0x1c); } -__inline KIRQL NTHALAPI KeGetCurrentIrql( +FORCEINLINE KIRQL NTHALAPI KeGetCurrentIrql( VOID) { return ((KIPCR *)KeGetCurrentKPCR())->CurrentIrql; diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index ca22de75ee8..7b789a3355b 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -9,6 +9,7 @@ /* INCLUDES *****************************************************************/ #include + #define NDEBUG #include @@ -48,6 +49,14 @@ MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[64]; WCHAR BldrModuleStrings[64][260]; NLS_DATA_BLOCK BldrNlsDataBlock; SETUP_LOADER_BLOCK BldrSetupBlock; +struct _boot_infos_t *BootInfo; + +#ifdef _M_PPC +#include "font.h" +boot_infos_t PpcEarlybootInfo; +#endif + +#define KSEG0_BASE 0x80000000 /* FUNCTIONS *****************************************************************/ @@ -294,6 +303,7 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, { ULONG i; ULONG size; + ULONG StartKernelBase; ULONG HalBase; ULONG DriverBase; ULONG DriverSize; @@ -303,6 +313,20 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, PKTSS Tss; PKGDTENTRY TssEntry; #endif +#ifdef _M_PPC + { + __asm__("ori 0,0,0"); + char *nk = "ntoskrnl is here"; + boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra; + memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(PpcEarlybootInfo)); + PpcEarlybootInfo.dispFont = BootDigits; + BootInfo = (struct _boot_infos_t *)&PpcEarlybootInfo; + DrawNumber(BootInfo, 0x1234abcd, 10, 100); + DrawNumber(BootInfo, (ULONG)nk, 10 , 150); + DrawString(BootInfo, nk, 100, 150); + __asm__("ori 0,0,0"); + } +#endif #ifdef _M_IX86 /* Load the GDT and IDT */ @@ -320,12 +344,19 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24); #endif + DrawNumber(BootInfo, 0xb0071f03, 190, 90); + DrawNumber(BootInfo, (ULONG)BootInfo, 190, 100); + /* Copy the Loader Block Data locally since Low-Memory will be wiped */ + TRACE; memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK)); + TRACE; memcpy(&KeLoaderModules[0], (PVOID)KeRosLoaderBlock.ModsAddr, sizeof(LOADER_MODULE) * KeRosLoaderBlock.ModsCount); + TRACE; KeRosLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules; + TRACE; /* Check for BIOS memory map */ KeMemoryMapRangeCount = 0; @@ -335,6 +366,8 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, size = *((PULONG)(KeRosLoaderBlock.MmapAddr - sizeof(ULONG))); i = 0; + TRACEXY(size, KeRosLoaderBlock.MmapLength); + /* Map it until we run out of size */ while (i < KeRosLoaderBlock.MmapLength) { @@ -361,16 +394,23 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, KeRosLoaderBlock.MmapLength = 0; KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap; } + TRACE; /* Save the Base Address */ MmSystemRangeStart = (PVOID)KeRosLoaderBlock.KernelBase; + TRACEXY((ULONG)KeLoaderCommandLine, (ULONG)LoaderBlock->CommandLine); /* Set the Command Line */ strcpy(KeLoaderCommandLine, (PCHAR)LoaderBlock->CommandLine); KeRosLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine; + TRACE; + + /* Get the address of ntoskrnl in openfirmware memory */ + StartKernelBase = KeLoaderModules[0].ModStart; + TRACE; /* Create a block for each module */ - for (i = 1; i < KeRosLoaderBlock.ModsCount; i++) + for (i = 0; i < KeRosLoaderBlock.ModsCount; i++) { /* Check if we have to copy the path or not */ if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0) @@ -382,7 +422,18 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String); } -#ifdef _M_IX86 +#ifdef _M_PPC + if(i == 0) { + DrawNumber(BootInfo, KeLoaderModules[i].ModStart, 10, 200); + DrawNumber(BootInfo, KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart, 100, 200); + DrawNumber(BootInfo, KeLoaderModules[i].ModEnd, 190, 200); + DrawNumber(BootInfo, KeLoaderModules[i+1].ModStart, 10, 210); + DrawNumber(BootInfo, KeLoaderModules[i+1].ModEnd - KeLoaderModules[i+1].ModStart, 100, 210); + DrawNumber(BootInfo, KeLoaderModules[i+1].ModEnd, 190, 210); + } + KeLoaderModules[i].ModStart += KSEG0_BASE - StartKernelBase; + KeLoaderModules[i].ModEnd += KSEG0_BASE - StartKernelBase; +#else /* Substract the base Address in Physical Memory */ KeLoaderModules[i].ModStart -= 0x200000; @@ -399,10 +450,12 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, /* Select the proper String */ KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i]; } + TRACE; /* Choose last module address as the final kernel address */ MmFreeLdrLastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd); + TRACE; /* Select the HAL Base */ HalBase = KeLoaderModules[1].ModStart; @@ -410,11 +463,13 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, /* Choose Driver Base */ DriverBase = MmFreeLdrLastKernelAddress; LdrHalBase = (ULONG_PTR)DriverBase; + TRACE; /* Initialize Module Management */ LdrInitModuleManagement((PVOID)KeLoaderModules[0].ModStart); /* Load HAL.DLL with the PE Loader */ + TRACE; LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)KeLoaderModules[0].ModStart, @@ -429,15 +484,18 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, // // This dirty hack fixes it, and should make symbol lookup work too. // + TRACE; HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject. DllBase)-> OptionalHeader.SizeOfImage; /* Increase the last kernel address with the size of HAL */ + TRACE; MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize); #ifdef _M_IX86 /* Now select the final beginning and ending Kernel Addresses */ + TRACE; MmFreeLdrFirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KSEG0_BASE + 0x200000; MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - @@ -445,22 +503,28 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, #endif /* Setup the IDT */ + TRACE; KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP! + TRACE; KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL /* Load the Kernel with the PE Loader */ + TRACE; LdrSafePEProcessModule((PVOID)KeLoaderModules[0].ModStart, (PVOID)KeLoaderModules[0].ModStart, (PVOID)DriverBase, &DriverSize); /* Sets up the VDM Data */ + TRACE; NtEarlyInitVdm(); /* Convert the loader block */ + TRACE; KiRosFrldrLpbToNtLpb(&KeRosLoaderBlock, &NtLoaderBlock); /* Do general System Startup */ + TRACE; KiSystemStartup(NtLoaderBlock); } diff --git a/reactos/ntoskrnl/ke/powerpc/main_asm.S b/reactos/ntoskrnl/ke/powerpc/main_asm.S index d8be8a8a995..8b39ec87bdd 100644 --- a/reactos/ntoskrnl/ke/powerpc/main_asm.S +++ b/reactos/ntoskrnl/ke/powerpc/main_asm.S @@ -30,30 +30,37 @@ _kernel_trap_stack_top: .globl NtProcessStartup .globl KiSystemStartup .globl KiRosPrepareForSystemStartup + .globl DrawNumber + NtProcessStartup: - lis 0,AP_MAGIC@ha - ori 0,0,AP_MAGIC@l - cmpw 0,0,3 + lis 30,AP_MAGIC@ha + ori 30,30,AP_MAGIC@l + cmpw 0,30,3 bne .m1 - + + /* + * Set a normal MSR value + */ + xor 0,0,0 + ori 30,0,0x3031 + mtmsr 30 + /* * Reserve space for the floating point save area. */ addi 1,1,-SIZEOF_FX_SAVE_AREA - /* - * Call the application processor initialization code - */ - bl KiSystemStartup - -.m1: + /* Bye bye asm land! */ + mr 4,3 + bl KiRosPrepareForSystemStartup + +.m1: /* Load the initial kernel stack */ lis 1,_kernel_stack_top@ha ori 1,1,_kernel_stack_top@l addi 1,1,-SIZEOF_FX_SAVE_AREA /* Call the main kernel initialization */ - mr 3,5 - mr 4,6 + mr 4,3 bl KiRosPrepareForSystemStartup diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 60b62007dc9..5138ba4d2cd 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -825,17 +825,6 @@ KeGetCurrentThread(VOID) #endif } -/* - * @implemented - */ -KPROCESSOR_MODE -NTAPI -KeGetPreviousMode(VOID) -{ - /* Return the previous mode of this thread */ - return KeGetCurrentThread()->PreviousMode; -} - /* * @implemented */ diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 1e07e06c23d..3802f6ab117 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -112,8 +112,11 @@ LdrInitModuleManagement ( PVOID KernelBase ) PIMAGE_NT_HEADERS NtHeader; /* Initialize the module list and spinlock */ + TRACEX(&ModuleListHead); InitializeListHead(&ModuleListHead); + TRACE; KeInitializeSpinLock(&ModuleListLock); + TRACE; /* Initialize ModuleObject for NTOSKRNL */ RtlZeroMemory(&NtoskrnlModuleObject, sizeof(LDR_DATA_TABLE_ENTRY)); @@ -121,25 +124,37 @@ LdrInitModuleManagement ( PVOID KernelBase ) RtlInitUnicodeString(&NtoskrnlModuleObject.FullDllName, KERNEL_MODULE_NAME); LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseDllName, &NtoskrnlModuleObject.FullDllName); + TRACEXY(&RtlImageNtHeader,KernelBase); NtHeader = RtlImageNtHeader((PVOID)KernelBase); + TRACE; NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint); + TRACE; DPRINT("ModuleObject:%08x entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint); NtoskrnlModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; + TRACE; InsertTailList(&ModuleListHead, &NtoskrnlModuleObject.InLoadOrderLinks); /* Initialize ModuleObject for HAL */ + TRACE; RtlZeroMemory(&HalModuleObject, sizeof(LDR_DATA_TABLE_ENTRY)); HalModuleObject.DllBase = (PVOID) LdrHalBase; + TRACE; RtlInitUnicodeString(&HalModuleObject.FullDllName, HAL_MODULE_NAME); LdrpBuildModuleBaseName(&HalModuleObject.BaseDllName, &HalModuleObject.FullDllName); + TRACEX(LdrHalBase); NtHeader = RtlImageNtHeader((PVOID)LdrHalBase); + if(!NtHeader) + { + KeBugCheck(0); + } HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint); DPRINT("ModuleObject:%08x entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint); HalModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; + TRACE; InsertTailList(&ModuleListHead, &HalModuleObject.InLoadOrderLinks); } @@ -362,15 +377,19 @@ LdrProcessModule( { PIMAGE_DOS_HEADER PEDosHeader; + TRACE; + /* If MZ header exists */ PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase; if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE && PEDosHeader->e_lfanew != 0L) { + TRACE; return LdrPEProcessModule(ModuleLoadBase, ModuleName, ModuleObject); } + TRACE; CPRINT("Module wasn't PE\n"); return STATUS_UNSUCCESSFUL; } diff --git a/reactos/tools/ppc.lost+found/link-freeldr b/reactos/tools/ppc.lost+found/link-freeldr index 2951365aba0..0e724669eff 100755 --- a/reactos/tools/ppc.lost+found/link-freeldr +++ b/reactos/tools/ppc.lost+found/link-freeldr @@ -1,10 +1,72 @@ #!/bin/sh -v export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin -powerpc-unknown-linux-gnu-ld -EL -g -nostartfiles -nostdlib -N -Ttext=0xe17000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/windows/conversion.o obj-ppc/boot/freeldr/freeldr/windows/peloader.o obj-ppc/boot/freeldr/freeldr/windows/winldr.o obj-ppc/boot/freeldr/freeldr/windows/wlmemory.o obj-ppc/boot/freeldr/freeldr/windows/wlregistry.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/cmlib/cmlib.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a +powerpc-unknown-linux-gnu-ld \ + -EL -g -nostartfiles -nostdlib -N -Ttext=0xe17000 \ + -o freeldr.elf \ + obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o \ + obj-ppc/boot/freeldr/freeldr/cache/blocklist.o \ + obj-ppc/boot/freeldr/freeldr/cache/cache.o \ + obj-ppc/boot/freeldr/freeldr/comm/rs232.o \ + obj-ppc/boot/freeldr/freeldr/disk/disk.o \ + obj-ppc/boot/freeldr/freeldr/disk/partition.o \ + obj-ppc/boot/freeldr/freeldr/fs/ext2.o \ + obj-ppc/boot/freeldr/freeldr/fs/fat.o \ + obj-ppc/boot/freeldr/freeldr/fs/fs.o \ + obj-ppc/boot/freeldr/freeldr/fs/fsrec.o \ + obj-ppc/boot/freeldr/freeldr/fs/iso.o \ + obj-ppc/boot/freeldr/freeldr/fs/ntfs.o \ + obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o \ + obj-ppc/boot/freeldr/freeldr/inifile/inifile.o \ + obj-ppc/boot/freeldr/freeldr/inifile/parse.o \ + obj-ppc/boot/freeldr/freeldr/math/libgcc2.o \ + obj-ppc/boot/freeldr/freeldr/mm/meminit.o \ + obj-ppc/boot/freeldr/freeldr/mm/mm.o \ + obj-ppc/boot/freeldr/freeldr/reactos/registry.o \ + obj-ppc/boot/freeldr/freeldr/reactos/binhive.o \ + obj-ppc/boot/freeldr/freeldr/reactos/arcname.o \ + obj-ppc/boot/freeldr/freeldr/reactos/reactos.o \ + obj-ppc/boot/freeldr/freeldr/rtl/list.o \ + obj-ppc/boot/freeldr/freeldr/rtl/libsupp.o \ + obj-ppc/boot/freeldr/freeldr/ui/gui.o \ + obj-ppc/boot/freeldr/freeldr/ui/tui.o \ + obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o \ + obj-ppc/boot/freeldr/freeldr/ui/ui.o \ + obj-ppc/boot/freeldr/freeldr/video/bank.o \ + obj-ppc/boot/freeldr/freeldr/video/fade.o \ + obj-ppc/boot/freeldr/freeldr/video/palette.o \ + obj-ppc/boot/freeldr/freeldr/video/pixel.o \ + obj-ppc/boot/freeldr/freeldr/video/video.o \ + obj-ppc/boot/freeldr/freeldr/freeldr.o \ + obj-ppc/boot/freeldr/freeldr/debug.o \ + obj-ppc/boot/freeldr/freeldr/version.o \ + obj-ppc/boot/freeldr/freeldr/cmdline.o \ + obj-ppc/boot/freeldr/freeldr/machine.o \ + obj-ppc/boot/freeldr/freeldr/windows/conversion.o \ + obj-ppc/boot/freeldr/freeldr/windows/peloader.o \ + obj-ppc/boot/freeldr/freeldr/windows/winldr.o \ + obj-ppc/boot/freeldr/freeldr/windows/wlmemory.o \ + obj-ppc/boot/freeldr/freeldr/windows/wlregistry.o \ + obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o \ + obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o \ + obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o \ + obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o \ + obj-ppc/boot/freeldr/freeldr/bootmgr.o \ + obj-ppc/boot/freeldr/freeldr/drivemap.o \ + obj-ppc/boot/freeldr/freeldr/miscboot.o \ + obj-ppc/boot/freeldr/freeldr/options.o \ + obj-ppc/boot/freeldr/freeldr/linuxboot.o \ + obj-ppc/boot/freeldr/freeldr/oslist.o \ + obj-ppc/boot/freeldr/freeldr/custom.o \ + obj-ppc/lib/rossym/rossym.a \ + obj-ppc/lib/cmlib/cmlib.a \ + obj-ppc/lib/string/string.a \ + obj-ppc/lib/rtl/rtl.a \ + /usr/local/pkg/reactos-powerpc/lib/libgcc.a powerpc-unknown-linux-gnu-objcopy -O binary freeldr.elf freeldr.tmp.le output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp +(dd if=/dev/zero bs=4k count=16 ; echo 'byebye') >> freeldr.tmp powerpc-unknown-linux-gnu-objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s boot/freeldr/bootsect/ofw_util.s boot/freeldr/bootsect/ofw.s powerpc-unknown-linux-gnu-ld -EB -Ttext 0xe00000 -Tdata 0xe17000 -e _begin -o ofwldr.x ofwboot.o ofwldr.payload -powerpc-unknown-linux-gnu-objcopy --only-section=.text --only-section=.data ofwldr.x ofwldr +powerpc-unknown-linux-gnu-objcopy --only-section=.text --only-section=.data --only-section=.bss ofwldr.x ofwldr From 2d0a9e6ffaec4d705866a98d126fce2d999b1a34 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 2 Jan 2007 08:31:10 +0000 Subject: [PATCH 60/81] Removed now unneeded-tracing, added hal address. We can see hal from here. svn path=/branches/powerpc/; revision=25273 --- reactos/ntoskrnl/ke/freeldr.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 7b789a3355b..714bc780ff2 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -348,15 +348,11 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, DrawNumber(BootInfo, (ULONG)BootInfo, 190, 100); /* Copy the Loader Block Data locally since Low-Memory will be wiped */ - TRACE; memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK)); - TRACE; memcpy(&KeLoaderModules[0], (PVOID)KeRosLoaderBlock.ModsAddr, sizeof(LOADER_MODULE) * KeRosLoaderBlock.ModsCount); - TRACE; KeRosLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules; - TRACE; /* Check for BIOS memory map */ KeMemoryMapRangeCount = 0; @@ -366,8 +362,6 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, size = *((PULONG)(KeRosLoaderBlock.MmapAddr - sizeof(ULONG))); i = 0; - TRACEXY(size, KeRosLoaderBlock.MmapLength); - /* Map it until we run out of size */ while (i < KeRosLoaderBlock.MmapLength) { @@ -394,20 +388,16 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, KeRosLoaderBlock.MmapLength = 0; KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap; } - TRACE; /* Save the Base Address */ MmSystemRangeStart = (PVOID)KeRosLoaderBlock.KernelBase; - TRACEXY((ULONG)KeLoaderCommandLine, (ULONG)LoaderBlock->CommandLine); /* Set the Command Line */ strcpy(KeLoaderCommandLine, (PCHAR)LoaderBlock->CommandLine); KeRosLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine; - TRACE; /* Get the address of ntoskrnl in openfirmware memory */ StartKernelBase = KeLoaderModules[0].ModStart; - TRACE; /* Create a block for each module */ for (i = 0; i < KeRosLoaderBlock.ModsCount; i++) @@ -450,26 +440,28 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, /* Select the proper String */ KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i]; } - TRACE; /* Choose last module address as the final kernel address */ MmFreeLdrLastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd); - TRACE; +#ifndef _M_PPC /* Select the HAL Base */ HalBase = KeLoaderModules[1].ModStart; /* Choose Driver Base */ DriverBase = MmFreeLdrLastKernelAddress; LdrHalBase = (ULONG_PTR)DriverBase; - TRACE; +#else + HalBase = KeLoaderModules[1].ModStart; + DriverBase = MmFreeLdrLastKernelAddress; + LdrHalBase = KeLoaderModules[1].ModStart; +#endif /* Initialize Module Management */ LdrInitModuleManagement((PVOID)KeLoaderModules[0].ModStart); /* Load HAL.DLL with the PE Loader */ - TRACE; LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)KeLoaderModules[0].ModStart, @@ -484,18 +476,15 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, // // This dirty hack fixes it, and should make symbol lookup work too. // - TRACE; HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject. DllBase)-> OptionalHeader.SizeOfImage; /* Increase the last kernel address with the size of HAL */ - TRACE; MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize); #ifdef _M_IX86 /* Now select the final beginning and ending Kernel Addresses */ - TRACE; MmFreeLdrFirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KSEG0_BASE + 0x200000; MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - @@ -503,28 +492,24 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, #endif /* Setup the IDT */ - TRACE; KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP! - TRACE; KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL /* Load the Kernel with the PE Loader */ - TRACE; LdrSafePEProcessModule((PVOID)KeLoaderModules[0].ModStart, (PVOID)KeLoaderModules[0].ModStart, (PVOID)DriverBase, &DriverSize); /* Sets up the VDM Data */ - TRACE; +#ifdef _M_IX86 NtEarlyInitVdm(); +#endif /* Convert the loader block */ - TRACE; KiRosFrldrLpbToNtLpb(&KeRosLoaderBlock, &NtLoaderBlock); /* Do general System Startup */ - TRACE; KiSystemStartup(NtLoaderBlock); } From 87541c1edb8a40437f419f62070f4bc74a41613b Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Tue, 2 Jan 2007 08:32:52 +0000 Subject: [PATCH 61/81] Removed tracking. svn path=/branches/powerpc/; revision=25274 --- reactos/ntoskrnl/ldr/loader.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 3802f6ab117..f971608e0ed 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -112,11 +112,8 @@ LdrInitModuleManagement ( PVOID KernelBase ) PIMAGE_NT_HEADERS NtHeader; /* Initialize the module list and spinlock */ - TRACEX(&ModuleListHead); InitializeListHead(&ModuleListHead); - TRACE; KeInitializeSpinLock(&ModuleListLock); - TRACE; /* Initialize ModuleObject for NTOSKRNL */ RtlZeroMemory(&NtoskrnlModuleObject, sizeof(LDR_DATA_TABLE_ENTRY)); @@ -124,27 +121,20 @@ LdrInitModuleManagement ( PVOID KernelBase ) RtlInitUnicodeString(&NtoskrnlModuleObject.FullDllName, KERNEL_MODULE_NAME); LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseDllName, &NtoskrnlModuleObject.FullDllName); - TRACEXY(&RtlImageNtHeader,KernelBase); NtHeader = RtlImageNtHeader((PVOID)KernelBase); - TRACE; NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint); - TRACE; DPRINT("ModuleObject:%08x entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint); NtoskrnlModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; - TRACE; InsertTailList(&ModuleListHead, &NtoskrnlModuleObject.InLoadOrderLinks); /* Initialize ModuleObject for HAL */ - TRACE; RtlZeroMemory(&HalModuleObject, sizeof(LDR_DATA_TABLE_ENTRY)); HalModuleObject.DllBase = (PVOID) LdrHalBase; - TRACE; RtlInitUnicodeString(&HalModuleObject.FullDllName, HAL_MODULE_NAME); LdrpBuildModuleBaseName(&HalModuleObject.BaseDllName, &HalModuleObject.FullDllName); - TRACEX(LdrHalBase); NtHeader = RtlImageNtHeader((PVOID)LdrHalBase); if(!NtHeader) { @@ -154,7 +144,6 @@ LdrInitModuleManagement ( PVOID KernelBase ) DPRINT("ModuleObject:%08x entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint); HalModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; - TRACE; InsertTailList(&ModuleListHead, &HalModuleObject.InLoadOrderLinks); } @@ -377,19 +366,15 @@ LdrProcessModule( { PIMAGE_DOS_HEADER PEDosHeader; - TRACE; - /* If MZ header exists */ PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase; if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE && PEDosHeader->e_lfanew != 0L) { - TRACE; return LdrPEProcessModule(ModuleLoadBase, ModuleName, ModuleObject); } - TRACE; CPRINT("Module wasn't PE\n"); return STATUS_UNSUCCESSFUL; } @@ -1077,7 +1062,6 @@ LdrSafePEProcessModule ( /* For ntoskrnl, we must stop after the bss section */ break; } - } return DriverBase; From 9c3817045b4b85de85524839bf9c1f1197d934e3 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Wed, 3 Jan 2007 09:31:26 +0000 Subject: [PATCH 62/81] - Reserve and map a page for Pcr - Some stubs (KeInitExceptions, KeInitInterrupts, ...) - Normalize segments and bats svn path=/branches/powerpc/; revision=25280 --- reactos/ntoskrnl/ke/powerpc/cpu.c | 277 ++++++++++ reactos/ntoskrnl/ke/powerpc/exp.c | 114 ++++ reactos/ntoskrnl/ke/powerpc/kiinit.c | 339 ++++++++++++ reactos/ntoskrnl/ke/powerpc/mmu.c | 397 ++++++++++++++ reactos/ntoskrnl/ke/powerpc/ppc_irq.c | 739 ++++++++++++++++++++++++++ reactos/ntoskrnl/ntoskrnl.rbuild | 3 + 6 files changed, 1869 insertions(+) create mode 100644 reactos/ntoskrnl/ke/powerpc/cpu.c create mode 100644 reactos/ntoskrnl/ke/powerpc/exp.c create mode 100644 reactos/ntoskrnl/ke/powerpc/kiinit.c create mode 100644 reactos/ntoskrnl/ke/powerpc/mmu.c create mode 100644 reactos/ntoskrnl/ke/powerpc/ppc_irq.c diff --git a/reactos/ntoskrnl/ke/powerpc/cpu.c b/reactos/ntoskrnl/ke/powerpc/cpu.c new file mode 100644 index 00000000000..30203dfcb98 --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/cpu.c @@ -0,0 +1,277 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/i386/cpu.c + * PURPOSE: Routines for CPU-level support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +/* CPU Features and Flags */ +ULONG KeProcessorArchitecture; +ULONG KeProcessorLevel; +ULONG KeProcessorRevision; +ULONG KeFeatureBits; +ULONG KeLargestCacheLine = 0x40; +ULONG KeDcacheFlushCount = 0; +ULONG KeIcacheFlushCount = 0; +ULONG KiDmaIoCoherency = 0; +CHAR KeNumberProcessors; +KAFFINITY KeActiveProcessors = 1; +BOOLEAN KiSMTProcessorsPresent; + +/* CPU Signatures */ +#if 0 +CHAR CmpIntelID[] = "GenuineIntel"; +CHAR CmpAmdID[] = "AuthenticAMD"; +CHAR CmpCyrixID[] = "CyrixInstead"; +CHAR CmpTransmetaID[] = "GenuineTMx86"; +CHAR CmpCentaurID[] = "CentaurHauls"; +CHAR CmpRiseID[] = "RiseRiseRise"; +#endif + +/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/ + +VOID +NTAPI +CPUID(IN ULONG CpuInfo[4], + IN ULONG InfoType) +{ + RtlZeroMemory(CpuInfo, sizeof(CpuInfo)); +} + +VOID +WRMSR(IN ULONG Register, + IN LONGLONG Value) +{ +} + +LONGLONG +RDMSR(IN ULONG Register) +{ + LARGE_INTEGER LargeVal; + LargeVal.QuadPart = 0; + return LargeVal.QuadPart; +} + +/* FUNCTIONS *****************************************************************/ + +VOID +NTAPI +KiSetProcessorType(VOID) +{ +} + +ULONG +NTAPI +KiGetCpuVendor(VOID) +{ + return 0; +} + +ULONG +NTAPI +KiGetFeatureBits(VOID) +{ + ULONG FeatureBits = 0; + /* Return the Feature Bits */ + return FeatureBits; +} + +VOID +NTAPI +KiGetCacheInformation(VOID) +{ +} + +VOID +NTAPI +KiSetCR0Bits(VOID) +{ +} + +VOID +NTAPI +KiInitializeTSS2(IN PKTSS Tss, + IN PKGDTENTRY TssEntry OPTIONAL) +{ +} + +VOID +NTAPI +KiInitializeTSS(IN PKTSS Tss) +{ +} + +VOID +FASTCALL +Ki386InitializeTss(IN PKTSS Tss, + IN PKIDTENTRY Idt, + IN PKGDTENTRY Gdt) +{ +} + +VOID +NTAPI +KeFlushCurrentTb(VOID) +{ +} + +VOID +NTAPI +KiSaveProcessorControlState(IN PKPROCESSOR_STATE ProcessorState) +{ +} + +VOID +NTAPI +KiInitializeMachineType(VOID) +{ +} + +ULONG_PTR +NTAPI +KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context) +{ + return 0; +} + +VOID +NTAPI +KiRestoreFastSyscallReturnState(VOID) +{ +} + +ULONG_PTR +NTAPI +Ki386EnableDE(IN ULONG_PTR Context) +{ + return 0; +} + +ULONG_PTR +NTAPI +Ki386EnableFxsr(IN ULONG_PTR Context) +{ + return 0; +} + +ULONG_PTR +NTAPI +Ki386EnableXMMIExceptions(IN ULONG_PTR Context) +{ + /* FIXME: Support this */ + DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n"); + return 0; +} + +VOID +NTAPI +KiI386PentiumLockErrataFixup(VOID) +{ + /* FIXME: Support this */ + DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n"); +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save) +{ + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) +{ + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +ULONG +NTAPI +KeGetRecommendedSharedDataAlignment(VOID) +{ + /* Return the global variable */ + return KeLargestCacheLine; +} + +/* + * @implemented + */ +VOID +NTAPI +KeFlushEntireTb(IN BOOLEAN Invalid, + IN BOOLEAN AllProcessors) +{ + KIRQL OldIrql; + + /* Raise the IRQL for the TB Flush */ + OldIrql = KeRaiseIrqlToSynchLevel(); + +#ifdef CONFIG_SMP + /* FIXME: Support IPI Flush */ +#error Not yet implemented! +#endif + + /* Flush the TB for the Current CPU */ + //KeFlushCurrentTb(); + + /* Return to Original IRQL */ + KeLowerIrql(OldIrql); +} + +/* + * @implemented + */ +VOID +NTAPI +KeSetDmaIoCoherency(IN ULONG Coherency) +{ + /* Save the coherency globally */ + KiDmaIoCoherency = Coherency; +} + +/* + * @implemented + */ +KAFFINITY +NTAPI +KeQueryActiveProcessors(VOID) +{ + PAGED_CODE(); + + /* Simply return the number of active processors */ + return KeActiveProcessors; +} + +/* + * @implemented + */ +VOID +__cdecl +KeSaveStateForHibernate(IN PKPROCESSOR_STATE State) +{ + /* Capture the context */ + RtlCaptureContext(&State->ContextFrame); + + /* Capture the control state */ + KiSaveProcessorControlState(State); +} diff --git a/reactos/ntoskrnl/ke/powerpc/exp.c b/reactos/ntoskrnl/ke/powerpc/exp.c new file mode 100644 index 00000000000..148f8efea9b --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/exp.c @@ -0,0 +1,114 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/i386/exp.c + * PURPOSE: Exception Dispatching and Context<->Trap Frame Conversion + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Gregor Anich + * Skywing (skywing@valhallalegends.com) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +_SEH_DEFINE_LOCALS(KiCopyInfo) +{ + volatile EXCEPTION_RECORD SehExceptRecord; +}; + +_SEH_FILTER(KiCopyInformation) +{ + _SEH_ACCESS_LOCALS(KiCopyInfo); + + /* Copy the exception records and return to the handler */ + RtlMoveMemory((PVOID)&_SEH_VAR(SehExceptRecord), + _SEH_GetExceptionPointers()->ExceptionRecord, + sizeof(EXCEPTION_RECORD)); + return EXCEPTION_EXECUTE_HANDLER; +} + +VOID +INIT_FUNCTION +NTAPI +KeInitExceptions(VOID) +{ +} + +ULONG +NTAPI +KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame) +{ + return 0; +} + +VOID +NTAPI +KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, + IN ULONG Esp) +{ +} + +ULONG +NTAPI +KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame) +{ + return 0; +} + +VOID +NTAPI +KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame, + IN ULONG Ss) +{ +} + +USHORT +NTAPI +KiTagWordFnsaveToFxsave(USHORT TagWord) +{ + return 0; +} + +VOID +NTAPI +KeContextToTrapFrame(IN PCONTEXT Context, + IN OUT PKEXCEPTION_FRAME ExceptionFrame, + IN OUT PKTRAP_FRAME TrapFrame, + IN ULONG ContextFlags, + IN KPROCESSOR_MODE PreviousMode) +{ +} + +VOID +NTAPI +KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN OUT PCONTEXT Context) +{ +} + +VOID +NTAPI +KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame, + IN KPROCESSOR_MODE PreviousMode, + IN BOOLEAN FirstChance) +{ +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeRaiseUserException(IN NTSTATUS ExceptionCode) +{ + return STATUS_SUCCESS; +} + diff --git a/reactos/ntoskrnl/ke/powerpc/kiinit.c b/reactos/ntoskrnl/ke/powerpc/kiinit.c new file mode 100644 index 00000000000..c2036558836 --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/kiinit.c @@ -0,0 +1,339 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/powerpc/kiinit.c + * PURPOSE: Kernel Initialization for x86 CPUs + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Art Yerkes (ayerkes@speakeasy.net) + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +extern LOADER_MODULE KeLoaderModules[64]; +extern ULONG KeLoaderModuleCount; +KPRCB PrcbData[MAXIMUM_PROCESSORS]; + +/* FUNCTIONS *****************************************************************/ + +extern void SetPhysByte(ULONG_PTR address, char value); + +VOID +DrawDigit(struct _boot_infos_t *BootInfo, ULONG Digit, int x, int y) +{ + int i,j,k; + + for( i = 0; i < 7; i++ ) { + for( j = 0; j < 8; j++ ) { + for( k = 0; k < BootInfo->dispDeviceDepth/8; k++ ) { + SetPhysByte(((ULONG_PTR)BootInfo->dispDeviceBase)+ + k + + (((j+x) * (BootInfo->dispDeviceDepth/8)) + + ((i+y) * (BootInfo->dispDeviceRowBytes))), + BootInfo->dispFont[Digit][i*8+j] == 'X' ? 255 : 0); + } + } + } +} + +VOID +DrawNumber(struct _boot_infos_t *BootInfo, ULONG Number, int x, int y) +{ + int i; + + for( i = 0; i < 8; i++, Number<<=4 ) { + DrawDigit(BootInfo,(Number>>28)&0xf,x+(i*8),y); + } +} + +VOID +DrawString(struct _boot_infos_t *BootInfo, const char *str, int x, int y) +{ + int i, xx; + + for( i = 0; str[i]; i++ ) { + xx = x + (i * 8); + if( str[i] >= '0' && str[i] <= '9' ) + DrawDigit(BootInfo, str[i] - '0', xx, y); + else if( str[i] >= 'A' && str[i] <= 'Z' ) + DrawDigit(BootInfo, str[i] - 'A' + 10, xx, y); + else if( str[i] >= 'a' && str[i] <= 'z' ) + DrawDigit(BootInfo, str[i] - 'a' + 10, xx, y); + else + DrawDigit(BootInfo, 37, xx, y); + } +} + +VOID +NTAPI +KiInitializePcr(IN ULONG ProcessorNumber, + IN PKIPCR Pcr, + IN PKTHREAD IdleThread, + IN PVOID DpcStack) +{ + TRACE; + Pcr->MajorVersion = PCR_MAJOR_VERSION; + TRACE; + Pcr->MinorVersion = PCR_MINOR_VERSION; + TRACE; + Pcr->CurrentIrql = PASSIVE_LEVEL; + TRACE; + Pcr->Prcb = PrcbData; + TRACEXY(Pcr->Prcb, PrcbData); + Pcr->Prcb->MajorVersion = 1; + TRACE; + Pcr->Prcb->MinorVersion = 1; + TRACE; + Pcr->Prcb->Number = 0; /* UP for now */ + TRACE; + Pcr->Prcb->SetMember = 1; + TRACE; + Pcr->Prcb->BuildType = 0; + TRACE; + Pcr->Prcb->DpcStack = DpcStack; + TRACE; + KiProcessorBlock[ProcessorNumber] = Pcr->Prcb; + TRACEXY(0xd00d,0xbeef); +} + +extern ULONG KiGetFeatureBits(); +extern VOID KiSetProcessorType(); +extern VOID KiGetCacheInformation(); + +VOID +NTAPI +KiInitializeKernel(IN PKPROCESS InitProcess, + IN PKTHREAD InitThread, + IN PVOID IdleStack, + IN PKPRCB Prcb, + IN CCHAR Number, + IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock) +{ + ULONG FeatureBits; + LARGE_INTEGER PageDirectory; + PVOID DpcStack; + + /* Detect and set the CPU Type */ + KiSetProcessorType(); + + /* Initialize the Power Management Support for this PRCB */ + PoInitializePrcb(Prcb); + + /* Get the processor features for the CPU */ + FeatureBits = KiGetFeatureBits(); + + /* Save feature bits */ + Prcb->FeatureBits = FeatureBits; + + /* Get cache line information for this CPU */ + KiGetCacheInformation(); + + /* Initialize spinlocks and DPC data */ + KiInitSpinLocks(Prcb, Number); + + /* Check if this is the Boot CPU */ + if (!Number) + { + /* Set Node Data */ + KeNodeBlock[0] = &KiNode0; + Prcb->ParentNode = KeNodeBlock[0]; + KeNodeBlock[0]->ProcessorMask = Prcb->SetMember; + + /* Set boot-level flags */ + KeProcessorArchitecture = 0; + KeProcessorLevel = (USHORT)Prcb->CpuType; + KeFeatureBits = FeatureBits; + + /* Set the current MP Master KPRCB to the Boot PRCB */ + Prcb->MultiThreadSetMaster = Prcb; + + /* Initialize portable parts of the OS */ + KiInitSystem(); + + /* Initialize the Idle Process and the Process Listhead */ + InitializeListHead(&KiProcessListHead); + PageDirectory.QuadPart = 0; + KeInitializeProcess(InitProcess, + 0, + 0xFFFFFFFF, + &PageDirectory, + TRUE); + InitProcess->QuantumReset = MAXCHAR; + } + else + { + /* FIXME */ + DPRINT1("SMP Boot support not yet present\n"); + } + +#if 0 + /* Setup the Idle Thread */ + KeInitializeThread(InitProcess, + InitThread, + NULL, + NULL, + NULL, + NULL, + NULL, + IdleStack); +#endif + InitThread->NextProcessor = Number; + InitThread->Priority = HIGH_PRIORITY; + InitThread->State = Running; + InitThread->Affinity = 1 << Number; + InitThread->WaitIrql = DISPATCH_LEVEL; + InitProcess->ActiveProcessors = 1 << Number; + + /* Set up the thread-related fields in the PRCB */ + //Prcb->CurrentThread = InitThread; + Prcb->NextThread = NULL; + //Prcb->IdleThread = InitThread; + + /* Initialize the Kernel Executive */ + ExpInitializeExecutive(0, (PLOADER_PARAMETER_BLOCK)LoaderBlock); + + /* Only do this on the boot CPU */ + if (!Number) + { + /* Calculate the time reciprocal */ + KiTimeIncrementReciprocal = + KiComputeReciprocal(KeMaximumIncrement, + &KiTimeIncrementShiftCount); + + /* Update DPC Values in case they got updated by the executive */ + Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth; + Prcb->MinimumDpcRate = KiMinimumDpcRate; + Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; + + /* Allocate the DPC Stack */ + DpcStack = MmCreateKernelStack(FALSE); + if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0); + Prcb->DpcStack = DpcStack; + } + + /* Free Initial Memory */ + MiFreeInitMemory(); + + while (1) + { + LARGE_INTEGER Timeout; + Timeout.QuadPart = 0x7fffffffffffffffLL; + KeDelayExecutionThread(KernelMode, FALSE, &Timeout); + } + + /* Bug Check and loop forever if anything failed */ + KEBUGCHECK(0); + for(;;); +} + +/* translate address */ +int PpcVirt2phys( int virt, int inst ); +/* Add a new page table entry for the indicated mapping */ +BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ); +void SetBat( int bat, int inst, int hi, int lo ); +void SetSR( int n, int val ); + +/* Use this for early boot additions to the page table */ +VOID +NTAPI +KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + ULONG Cpu, PhysicalPage, i; + PKIPCR Pcr = (PKIPCR)KPCR_BASE; + PKPRCB Prcb; + + /* Zero bats for now ... We may use these for something later */ + for( i = 0; i < 4; i++ ) { + SetBat( i, 0, 0, 0 ); + SetBat( i, 1, 0, 0 ); + } + + /* Set up segs for normal paged address space. */ + for( i = 0; i < 16; i++ ) { + SetSR(i, i); + } + + /* Save the loader block and get the current CPU */ + //KeLoaderBlock = LoaderBlock; + Cpu = KeNumberProcessors; + if (!Cpu) + { + /* Skippable initialization for secondary processor */ + /* We'll allocate a page from the end of the kernel area for KPCR. This code will probably + * change when we get SMP support. + */ + ULONG LastPage = ROUND_UP(KeLoaderModules[KeLoaderModuleCount-1].ModEnd,1<Prcb; + Pcr->Number = Cpu; + Pcr->SetMember = 1 << Cpu; + Prcb->SetMember = 1 << Cpu; + + TRACE; + /* Initialize the Processor with HAL */ + HalInitializeProcessor(Cpu, LoaderBlock); + + TRACE; + /* Set active processors */ + KeActiveProcessors |= Pcr->SetMember; + KeNumberProcessors++; + + TRACE; + /* Initialize the Debugger for the Boot CPU */ + if (!Cpu) KdInitSystem (0, LoaderBlock); + + TRACE; + /* Check for break-in */ + if (KdPollBreakIn()) + { + DbgBreakPointWithStatus(1); + } + + TRACE; + /* Raise to HIGH_LEVEL */ + KfRaiseIrql(HIGH_LEVEL); + + TRACE; + /* Call main kernel intialization */ + KiInitializeKernel(&KiInitialProcess.Pcb, + &KiInitialThread.Tcb, + P0BootStack, + Prcb, + Cpu, + (PVOID)LoaderBlock); + TRACE; +} + diff --git a/reactos/ntoskrnl/ke/powerpc/mmu.c b/reactos/ntoskrnl/ke/powerpc/mmu.c new file mode 100644 index 00000000000..89f735300b3 --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/mmu.c @@ -0,0 +1,397 @@ +#include + +inline int GetMSR() { + register int res asm ("r3"); + __asm__("mfmsr 3"); + return res; +} + +inline int GetDEC() { + register int res asm ("r3"); + __asm__("mfdec 3"); + return res; +} + +extern int GetPhys(int Addr); +extern void SetPhys(int Addr, int Val); + +__asm__("\t.globl GetPhys\n" + "GetPhys:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "isync\n\t" + "sync\n\t" + "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ + "mtmsr 5\n\t" + "isync\n\t" + "sync\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl SetPhys\n" + "SetPhys:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "sync\n\t" + "eieio\n\t" + "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" + "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl SetPhysByte\n" + "SetPhysByte:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,7\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "sync\n\t" + "eieio\n\t" + "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" + "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +inline int GetSR(int n) { + register int res asm ("r3"); + switch( n ) { + case 0: + __asm__("mfsr 3,0"); + break; + case 1: + __asm__("mfsr 3,1"); + break; + case 2: + __asm__("mfsr 3,2"); + break; + case 3: + __asm__("mfsr 3,3"); + break; + case 4: + __asm__("mfsr 3,4"); + break; + case 5: + __asm__("mfsr 3,5"); + break; + case 6: + __asm__("mfsr 3,6"); + break; + case 7: + __asm__("mfsr 3,7"); + break; + case 8: + __asm__("mfsr 3,8"); + break; + case 9: + __asm__("mfsr 3,9"); + break; + case 10: + __asm__("mfsr 3,10"); + break; + case 11: + __asm__("mfsr 3,11"); + break; + case 12: + __asm__("mfsr 3,12"); + break; + case 13: + __asm__("mfsr 3,13"); + break; + case 14: + __asm__("mfsr 3,14"); + break; + case 15: + __asm__("mfsr 3,15"); + break; + } + return res; +} + +inline void SetSR(int n, int val) { + switch( n ) { + case 0: + __asm__("mtsr 4,0"); + break; + case 1: + __asm__("mtsr 4,1"); + break; + case 2: + __asm__("mtsr 4,2"); + break; + case 3: + __asm__("mtsr 4,3"); + break; + case 4: + __asm__("mtsr 4,4"); + break; + case 5: + __asm__("mtsr 4,5"); + break; + case 6: + __asm__("mtsr 4,6"); + break; + case 7: + __asm__("mtsr 4,7"); + break; + case 8: + __asm__("mtsr 4,8"); + break; + case 9: + __asm__("mtsr 4,9"); + break; + case 10: + __asm__("mtsr 4,10"); + break; + case 11: + __asm__("mtsr 4,11"); + break; + case 12: + __asm__("mtsr 4,12"); + break; + case 13: + __asm__("mtsr 4,13"); + break; + case 14: + __asm__("mtsr 4,14"); + break; + case 15: + __asm__("mtsr 4,15"); + break; + } +} + +inline void GetBat( int bat, int inst, int *batHi, int *batLo ) { + register int bh asm("r3"), bl asm("r4"); + if( inst ) { + switch( bat ) { + case 0: + __asm__("mfibatu 3,0"); + __asm__("mfibatl 4,0"); + break; + case 1: + __asm__("mfibatu 3,1"); + __asm__("mfibatl 4,1"); + break; + case 2: + __asm__("mfibatu 3,2"); + __asm__("mfibatl 4,2"); + break; + case 3: + __asm__("mfibatu 3,3"); + __asm__("mfibatl 4,3"); + break; + } + } else { + switch( bat ) { + case 0: + __asm__("mfdbatu 3,0"); + __asm__("mfdbatl 4,0"); + break; + case 1: + __asm__("mfdbatu 3,1"); + __asm__("mfdbatl 4,1"); + break; + case 2: + __asm__("mfdbatu 3,2"); + __asm__("mfdbatl 4,2"); + break; + case 3: + __asm__("mfdbatu 3,3"); + __asm__("mfdbatl 4,3"); + break; + } + } + *batHi = bh; + *batLo = bl; +} + +inline void SetBat( int bat, int inst, int batHi, int batLo ) { + register int bh asm("r3"), bl asm("r4"); + bh = batHi; + bl = batLo; + if( inst ) { + switch( bat ) { + case 0: + __asm__("mtibatu 0,3"); + __asm__("mtibatl 0,4"); + break; + case 1: + __asm__("mtibatu 1,3"); + __asm__("mtibatl 1,4"); + break; + case 2: + __asm__("mtibatu 2,3"); + __asm__("mtibatl 2,4"); + break; + case 3: + __asm__("mtibatu 3,3"); + __asm__("mtibatl 3,4"); + break; + } + } else { + switch( bat ) { + case 0: + __asm__("mtdbatu 0,3"); + __asm__("mtdbatl 0,4"); + break; + case 1: + __asm__("mtdbatu 1,3"); + __asm__("mtdbatl 1,4"); + break; + case 2: + __asm__("mtdbatu 2,3"); + __asm__("mtdbatl 2,4"); + break; + case 3: + __asm__("mtdbatu 3,3"); + __asm__("mtdbatl 3,4"); + break; + } + } + __asm__("isync\n\tsync"); +} + +inline int GetSDR1() { + register int res asm("r3"); + __asm__("mfsdr1 3"); + return res; +} + +inline void SetSDR1( int sdr ) { +#if 0 + int i,j; +#endif + __asm__("mtsdr1 3"); +#if 0 + __asm__("sync"); + __asm__("isync"); + __asm__("ptesync"); + + for( i = 0; i < 256; i++ ) { + j = i << 12; + __asm__("tlbie %0,0" : : "r" (j)); + } + __asm__("eieio"); + __asm__("tlbsync"); + __asm__("ptesync"); +#endif +} + +inline int BatHit( int bath, int batl, int virt ) { + int mask = 0xfffe0000 & ~((batl & 0x3f) << 17); + return (batl & 0x40) && ((virt & mask) == (bath & mask)); +} + +inline int BatTranslate( int bath, int batl, int virt ) { + return (virt & 0x007fffff) | (batl & 0xfffe0000); +} + +/* translate address */ +int PpcVirt2phys( int virt, int inst ) { + int msr = GetMSR(); + int txmask = inst ? 0x20 : 0x10; + int i, bath, batl, sr, sdr1, physbase, vahi, valo; + int npteg, hash, hashmask, ptehi, ptelo, ptegaddr; + int vsid, pteh, ptevsid, pteapi; + + if( msr & txmask ) { + sr = GetSR( virt >> 28 ); + vsid = sr & 0xfffffff; + vahi = vsid >> 4; + valo = (vsid << 28) | (virt & 0xfffffff); + if( sr & 0x80000000 ) { + return valo; + } + + for( i = 0; i < 4; i++ ) { + GetBat( i, inst, &bath, &batl ); + if( BatHit( bath, batl, virt ) ) { + return BatTranslate( bath, batl, virt ); + } + } + + sdr1 = GetSDR1(); + + physbase = sdr1 & ~0xffff; + hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; + hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); + npteg = hashmask + 1; + + for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) { + ptegaddr = ((hashmask & hash) * 64) + physbase; + + for( i = 0; i < 8; i++ ) { + ptehi = GetPhys( ptegaddr + (i * 8) ); + ptelo = GetPhys( ptegaddr + (i * 8) + 4 ); + + ptevsid = (ptehi >> 7) & 0xffffff; + pteapi = ptehi & 0x3f; + + if( (ptehi & 64) != pteh ) continue; + if( ptevsid != (vsid & 0xffffff) ) continue; + if( pteapi != ((virt >> 22) & 0x3f) ) continue; + + return (ptelo & 0xfffff000) | (virt & 0xfff); + } + } + return -1; + } else { + return virt; + } +} + +/* Add a new page table entry for the indicated mapping */ +BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) { + int i, ptehi, ptelo; + int sdr1 = _sdr1 ? _sdr1 : GetSDR1(); + int sr = GetSR( (virt >> 28) & 0xf ); + int vsid = sr & 0xfffffff; + int physbase = sdr1 & ~0xffff; + int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; + int valo = (vsid << 28) | (virt & 0xfffffff); + int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); + int ptegaddr = ((hashmask & hash) * 64) + physbase; + + for( i = 0; i < 8; i++ ) { + ptehi = GetPhys( ptegaddr + (i * 8) ); + + if( (slot != i) && (ptehi & 0x80000000) ) continue; + + ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f); + ptelo = phys & ~0xfff; + + SetPhys( ptegaddr + (i * 8), ptehi ); + SetPhys( ptegaddr + (i * 8) + 4, ptelo ); + + return TRUE; + } + + return FALSE; +} diff --git a/reactos/ntoskrnl/ke/powerpc/ppc_irq.c b/reactos/ntoskrnl/ke/powerpc/ppc_irq.c new file mode 100644 index 00000000000..41df38281fd --- /dev/null +++ b/reactos/ntoskrnl/ke/powerpc/ppc_irq.c @@ -0,0 +1,739 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/i386/irq.c + * PURPOSE: IRQ handling + * + * PROGRAMMERS: David Welch (welch@mcmail.com) + */ + +/* + * NOTE: In general the PIC interrupt priority facilities are used to + * preserve the NT IRQL semantics, global interrupt disables are only used + * to keep the PIC in a consistent state + * + */ + +/* INCLUDES ****************************************************************/ + +#include + +#define NDEBUG +#include + +extern KDPC KiExpireTimerDpc; +extern ULONG KiMaximumDpcQueueDepth; +extern ULONG KiMinimumDpcRate; +extern ULONG KiAdjustDpcThreshold; +extern ULONG KiIdealDpcRate; +extern LONG KiTickOffset; +extern ULONG KeMaximumIncrement; +extern ULONG KeMinimumIncrement; +extern ULONG KeTimeAdjustment; +extern BOOLEAN KiClockSetupComplete; + +/* GLOBALS *****************************************************************/ + +/* Interrupt handler list */ + +#define NR_TRAPS 16 +#ifdef CONFIG_SMP + +#define INT_NAME2(intnum) KiUnexpectedInterrupt##intnum + +#define BUILD_INTERRUPT_HANDLER(intnum) \ +VOID INT_NAME2(intnum)(VOID); + +#define D(x,y) \ + BUILD_INTERRUPT_HANDLER(x##y) + +#define D16(x) \ + D(x,0) D(x,1) D(x,2) D(x,3) \ + D(x,4) D(x,5) D(x,6) D(x,7) \ + D(x,8) D(x,9) D(x,A) D(x,B) \ + D(x,C) D(x,D) D(x,E) D(x,F) + +D16(3) D16(4) D16(5) D16(6) +D16(7) D16(8) D16(9) D16(A) +D16(B) D16(C) D16(D) D16(E) +D16(F) + +#define L(x,y) \ + (ULONG)& INT_NAME2(x##y) + +#define L16(x) \ + L(x,0), L(x,1), L(x,2), L(x,3), \ + L(x,4), L(x,5), L(x,6), L(x,7), \ + L(x,8), L(x,9), L(x,A), L(x,B), \ + L(x,C), L(x,D), L(x,E), L(x,F) + +static ULONG irq_handler[ROUND_UP(NR_TRAPS, 16)] = { + L16(3), L16(4), L16(5), L16(6), + L16(7), L16(8), L16(9), L16(A), + L16(B), L16(C), L16(D), L16(E) +}; + +#undef L +#undef L16 +#undef D +#undef D16 + +#else /* CONFIG_SMP */ + +void trap_handler_0(void); +void trap_handler_1(void); +void trap_handler_2(void); +void trap_handler_3(void); +void trap_handler_4(void); +void trap_handler_5(void); +void trap_handler_6(void); +void trap_handler_7(void); +void trap_handler_8(void); +void trap_handler_9(void); +void trap_handler_10(void); +void trap_handler_11(void); +void trap_handler_12(void); +void trap_handler_13(void); +void trap_handler_14(void); +void trap_handler_15(void); + +static unsigned int trap_handler[NR_TRAPS] __attribute__((unused)) = +{ + (int)&trap_handler_0, + (int)&trap_handler_1, + (int)&trap_handler_2, + (int)&trap_handler_3, + (int)&trap_handler_4, + (int)&trap_handler_5, + (int)&trap_handler_6, + (int)&trap_handler_7, + (int)&trap_handler_8, + (int)&trap_handler_9, + (int)&trap_handler_10, + (int)&trap_handler_11, + (int)&trap_handler_12, + (int)&trap_handler_13, + (int)&trap_handler_14, + (int)&trap_handler_15, +}; + +#endif /* CONFIG_SMP */ + +/* + * PURPOSE: Object describing each isr + * NOTE: The data in this table is only modified at passsive level but can + * be accessed at any irq level. + */ + +typedef struct +{ + LIST_ENTRY ListHead; + KSPIN_LOCK Lock; + ULONG Count; +} +ISR_TABLE, *PISR_TABLE; + +#ifdef CONFIG_SMP +static ISR_TABLE IsrTable[NR_TRAPS][MAXIMUM_PROCESSORS]; +#else +static ISR_TABLE IsrTable[NR_TRAPS][1]; +#endif + +#define TAG_ISR_LOCK TAG('I', 'S', 'R', 'L') + +/* FUNCTIONS ****************************************************************/ + +VOID +INIT_FUNCTION +NTAPI +KeInitInterrupts (VOID) +{ + int i, j; + + /* + * Setup the IDT entries to point to the interrupt handlers + */ + for (i=0;iCurrentThread)) return; + + /* Get the current thread and process */ + CurrentThread = Prcb->CurrentThread; + CurrentProcess = CurrentThread->ApcState.Process; + + /* Check if we came from user mode */ + if (TrapFrame->PreviousMode != KernelMode) + { + /* Update user times */ + CurrentThread->UserTime++; + InterlockedIncrement((PLONG)&CurrentProcess->UserTime); + Prcb->UserTime++; + } + else + { + /* Check IRQ */ + if (Irql > DISPATCH_LEVEL) + { + /* This was an interrupt */ + Prcb->InterruptTime++; + } + else if ((Irql < DISPATCH_LEVEL) || !(Prcb->DpcRoutineActive)) + { + /* This was normal kernel time */ + CurrentThread->KernelTime++; + InterlockedIncrement((PLONG)&CurrentProcess->KernelTime); + } + else if (Irql == DISPATCH_LEVEL) + { + /* This was DPC time */ + Prcb->DpcTime++; + } + + /* Update CPU kernel time in all cases */ + Prcb->KernelTime++; + } + + /* Set the last DPC Count and request rate */ + Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount; + Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) + + Prcb->DpcRequestRate) / 2; + + /* Check if we should request a DPC */ + if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive)) + { + /* Request one */ + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + + /* Update the depth if needed */ + if ((Prcb->DpcRequestRate < KiIdealDpcRate) && + (Prcb->MaximumDpcQueueDepth > 1)) + { + /* Decrease the maximum depth by one */ + Prcb->MaximumDpcQueueDepth--; + } + } + else + { + /* Decrease the adjustment threshold */ + if (!(--Prcb->AdjustDpcThreshold)) + { + /* We've hit 0, reset it */ + Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; + + /* Check if we've hit queue maximum */ + if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth) + { + /* Increase maximum by one */ + Prcb->MaximumDpcQueueDepth++; + } + } + } + + /* + * If we're at end of quantum request software interrupt. The rest + * is handled in KiDispatchInterrupt. + * + * NOTE: If one stays at DISPATCH_LEVEL for a long time the DPC routine + * which checks for quantum end will not be executed and decrementing + * the quantum here can result in overflow. This is not a problem since + * we don't care about the quantum value anymore after the QuantumEnd + * flag is set. + */ + if ((CurrentThread->Quantum -= 3) <= 0) + { + Prcb->QuantumEnd = TRUE; + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + } +} + + +/* + * NOTE: On Windows this function takes exactly zero parameters and EBP is + * guaranteed to point to KTRAP_FRAME. Also [esp+0] contains an IRQL. + * The function is used only by HAL, so there's no point in keeping + * that prototype. + * + * @implemented + */ +VOID +STDCALL +KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, + IN KIRQL Irql, + IN ULONG Increment) +{ + LONG OldOffset; + LARGE_INTEGER Time; + ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL); + if (!KiClockSetupComplete) return; + + /* Update interrupt time */ + Time.LowPart = SharedUserData->InterruptTime.LowPart; + Time.HighPart = SharedUserData->InterruptTime.High1Time; + Time.QuadPart += Increment; + SharedUserData->InterruptTime.High2Time = Time.u.HighPart; + SharedUserData->InterruptTime.LowPart = Time.u.LowPart; + SharedUserData->InterruptTime.High1Time = Time.u.HighPart; + + /* Increase the tick offset */ + KiTickOffset -= Increment; + OldOffset = KiTickOffset; + + /* Check if this isn't a tick yet */ + if (KiTickOffset > 0) + { + /* Expire timers */ + KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0); + } + else + { + /* Setup time structure for system time */ + Time.LowPart = SharedUserData->SystemTime.LowPart; + Time.HighPart = SharedUserData->SystemTime.High1Time; + Time.QuadPart += KeTimeAdjustment; + SharedUserData->SystemTime.High2Time = Time.HighPart; + SharedUserData->SystemTime.LowPart = Time.LowPart; + SharedUserData->SystemTime.High1Time = Time.HighPart; + + /* Setup time structure for tick time */ + Time.LowPart = KeTickCount.LowPart; + Time.HighPart = KeTickCount.High1Time; + Time.QuadPart += 1; + KeTickCount.High2Time = Time.HighPart; + KeTickCount.LowPart = Time.LowPart; + KeTickCount.High1Time = Time.HighPart; + SharedUserData->TickCount.High2Time = Time.HighPart; + SharedUserData->TickCount.LowPart = Time.LowPart; + SharedUserData->TickCount.High1Time = Time.HighPart; + + /* Update tick count in shared user data as well */ + SharedUserData->TickCountLowDeprecated++; + + /* Queue a DPC that will expire timers */ + KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0); + } + + /* Update process and thread times */ + if (OldOffset <= 0) + { + /* This was a tick, calculate the next one */ + KiTickOffset += KeMaximumIncrement; + KeUpdateRunTime(TrapFrame, Irql); + } +} + +VOID STDCALL +KiInterruptDispatch2 (ULONG vector, KIRQL old_level) +/* + * FUNCTION: Calls all the interrupt handlers for a given irq. + * ARGUMENTS: + * vector - The number of the vector to call handlers for. + * old_level - The irql of the processor when the irq took place. + * NOTES: Must be called at DIRQL. + */ +{ + PKINTERRUPT isr; + PLIST_ENTRY current; + KIRQL oldlvl; + PISR_TABLE CurrentIsr; + + DPRINT("I(0x%.08x, 0x%.08x)\n", vector, old_level); + + /* + * Iterate the list until one of the isr tells us its device interrupted + */ + CurrentIsr = &IsrTable[vector][(ULONG)KeGetCurrentProcessorNumber()]; + + KiAcquireSpinLock(&CurrentIsr->Lock); + + CurrentIsr->Count++; + current = CurrentIsr->ListHead.Flink; + + while (current != &CurrentIsr->ListHead) + { + isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry); + oldlvl = KeAcquireInterruptSpinLock(isr); + if (isr->ServiceRoutine(isr, isr->ServiceContext)) + { + KeReleaseInterruptSpinLock(isr, oldlvl); + break; + } + KeReleaseInterruptSpinLock(isr, oldlvl); + current = current->Flink; + } + KiReleaseSpinLock(&CurrentIsr->Lock); +} + +VOID +KiInterruptDispatch3 (ULONG vector, PKIRQ_TRAPFRAME Trapframe) +/* + * FUNCTION: Calls the irq specific handler for an irq + * ARGUMENTS: + * irq = IRQ that has interrupted + */ +{ + KIRQL old_level; + KTRAP_FRAME KernelTrapFrame; + PKTHREAD CurrentThread; + PKTRAP_FRAME OldTrapFrame=NULL; + + /* + * At this point we have interrupts disabled, nothing has been done to + * the PIC. + */ + + KeGetCurrentPrcb()->InterruptCount++; + + /* + * Notify the rest of the kernel of the raised irq level. For the + * default HAL this will send an EOI to the PIC and alter the IRQL. + */ + if (!HalBeginSystemInterrupt (vector, + vector, + &old_level)) + { + return; + } + + + /* + * Enable interrupts + * NOTE: Only higher priority interrupts will get through + */ + _enable(); + +#ifndef CONFIG_SMP + if (vector == 0) + { + KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame); + KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000); + } + else +#endif + { + /* + * Actually call the ISR. + */ + KiInterruptDispatch2(vector, old_level); + } + + /* + * End the system interrupt. + */ + _disable(); + + if (old_level==PASSIVE_LEVEL) + { + HalEndSystemInterrupt (APC_LEVEL, 0); + + CurrentThread = KeGetCurrentThread(); + if (CurrentThread!=NULL && CurrentThread->ApcState.UserApcPending) + { + DPRINT("PID: %d, TID: %d CS %04x/%04x\n", + ((PETHREAD)CurrentThread)->ThreadsProcess->UniqueProcessId, + ((PETHREAD)CurrentThread)->Cid.UniqueThread, + Trapframe->Cs, + CurrentThread->TrapFrame ? CurrentThread->TrapFrame->Cs : 0); + if (CurrentThread->TrapFrame == NULL) + { + OldTrapFrame = CurrentThread->TrapFrame; + KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame); + CurrentThread->TrapFrame = &KernelTrapFrame; + } + + _enable(); + KiDeliverApc(UserMode, NULL, NULL); + _disable(); + + ASSERT(KeGetCurrentThread() == CurrentThread); + if (CurrentThread->TrapFrame == &KernelTrapFrame) + { + KeTrapFrameToIRQTrapFrame(&KernelTrapFrame, Trapframe); + CurrentThread->TrapFrame = OldTrapFrame; + } + } + KeLowerIrql(PASSIVE_LEVEL); + } + else + { + HalEndSystemInterrupt (old_level, 0); + } + +} + +static VOID +KeDumpIrqList(VOID) +{ + PKINTERRUPT current; + PLIST_ENTRY current_entry; + LONG i, j; + KIRQL oldlvl; + BOOLEAN printed; + + for (i=0;iFlink; + current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry); + } + KiReleaseSpinLock(&IsrTable[i][j].Lock); + } + KeLowerIrql(oldlvl); + } +} + +/* + * @implemented + */ +BOOLEAN +STDCALL +KeConnectInterrupt(PKINTERRUPT InterruptObject) +{ + KIRQL oldlvl,synch_oldlvl; + PKINTERRUPT ListHead; + ULONG Vector; + PISR_TABLE CurrentIsr; + BOOLEAN Result; + + DPRINT("KeConnectInterrupt()\n"); + + Vector = InterruptObject->Vector; + + if (Vector < 0 || Vector >= NR_TRAPS) + return FALSE; + + ASSERT (InterruptObject->Number < KeNumberProcessors); + + KeSetSystemAffinityThread(1 << InterruptObject->Number); + + CurrentIsr = &IsrTable[Vector][(ULONG)InterruptObject->Number]; + + KeRaiseIrql(Vector,&oldlvl); + KiAcquireSpinLock(&CurrentIsr->Lock); + + /* + * Check if the vector is already in use that we can share it + */ + if (!IsListEmpty(&CurrentIsr->ListHead)) + { + ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry); + if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE) + { + KiReleaseSpinLock(&CurrentIsr->Lock); + KeLowerIrql(oldlvl); + KeRevertToUserAffinityThread(); + return FALSE; + } + } + + synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject); + + DPRINT("%x %x\n",CurrentIsr->ListHead.Flink, CurrentIsr->ListHead.Blink); + + Result = HalEnableSystemInterrupt(Vector, InterruptObject->Irql, InterruptObject->Mode); + if (Result) + { + InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry); + DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->InterruptListEntry.Blink); + } + + InterruptObject->Connected = TRUE; + KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl); + + /* + * Release the table spinlock + */ + KiReleaseSpinLock(&CurrentIsr->Lock); + KeLowerIrql(oldlvl); + + KeDumpIrqList(); + + KeRevertToUserAffinityThread(); + + return Result; +} + +/* + * @implemented + * + * FUNCTION: Releases a drivers isr + * ARGUMENTS: + * InterruptObject = isr to release + */ +BOOLEAN +STDCALL +KeDisconnectInterrupt(PKINTERRUPT InterruptObject) +{ + KIRQL oldlvl,synch_oldlvl; + PISR_TABLE CurrentIsr; + BOOLEAN State; + + DPRINT1("KeDisconnectInterrupt\n"); + ASSERT (InterruptObject->Number < KeNumberProcessors); + + /* Set the affinity */ + KeSetSystemAffinityThread(1 << InterruptObject->Number); + + /* Get the ISR Tabe */ + CurrentIsr = &IsrTable[InterruptObject->Vector] + [(ULONG)InterruptObject->Number]; + + /* Raise IRQL to required level and lock table */ + KeRaiseIrql(InterruptObject->Vector,&oldlvl); + KiAcquireSpinLock(&CurrentIsr->Lock); + + /* Check if it's actually connected */ + if ((State = InterruptObject->Connected)) + { + /* Lock the Interrupt */ + synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject); + + /* Remove this one, and check if all are gone */ + RemoveEntryList(&InterruptObject->InterruptListEntry); + if (IsListEmpty(&CurrentIsr->ListHead)) + { + /* Completely Disable the Interrupt */ + HalDisableSystemInterrupt(InterruptObject->Vector, InterruptObject->Irql); + } + + /* Disconnect it */ + InterruptObject->Connected = FALSE; + + /* Release the interrupt lock */ + KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl); + } + /* Release the table spinlock */ + KiReleaseSpinLock(&CurrentIsr->Lock); + KeLowerIrql(oldlvl); + + /* Go back to default affinity */ + KeRevertToUserAffinityThread(); + + /* Return Old Interrupt State */ + return State; +} + +/* + * @implemented + */ +VOID +STDCALL +KeInitializeInterrupt(PKINTERRUPT Interrupt, + PKSERVICE_ROUTINE ServiceRoutine, + PVOID ServiceContext, + PKSPIN_LOCK SpinLock, + ULONG Vector, + KIRQL Irql, + KIRQL SynchronizeIrql, + KINTERRUPT_MODE InterruptMode, + BOOLEAN ShareVector, + CHAR ProcessorNumber, + BOOLEAN FloatingSave) +{ + /* Set the Interrupt Header */ + Interrupt->Type = InterruptObject; + Interrupt->Size = sizeof(KINTERRUPT); + + /* Check if we got a spinlock */ + if (SpinLock) + { + Interrupt->ActualLock = SpinLock; + } + else + { + /* This means we'll be usin the built-in one */ + KeInitializeSpinLock(&Interrupt->SpinLock); + Interrupt->ActualLock = &Interrupt->SpinLock; + } + + /* Set the other settings */ + Interrupt->ServiceRoutine = ServiceRoutine; + Interrupt->ServiceContext = ServiceContext; + Interrupt->Vector = Vector; + Interrupt->Irql = Irql; + Interrupt->SynchronizeIrql = SynchronizeIrql; + Interrupt->Mode = InterruptMode; + Interrupt->ShareVector = ShareVector; + Interrupt->Number = ProcessorNumber; + Interrupt->FloatingSave = FloatingSave; + + /* Disconnect it at first */ + Interrupt->Connected = FALSE; +} + +VOID KePrintInterruptStatistic(VOID) +{ + LONG i, j; + + for (j = 0; j < KeNumberProcessors; j++) + { + DPRINT1("CPU%d:\n", j); + for (i = 0; i < NR_TRAPS; i++) + { + if (IsrTable[i][j].Count) + { + DPRINT1(" Irq %x(%d): %d\n", i, i, IsrTable[i][j].Count); + } + } + } +} + +/* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index fe3abe497b5..4f0cba59073 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -49,6 +49,9 @@ main_asm.S + mmu.c + cpu.c + exp.c kiinit.c ppc_irq.c From 3bae2c0ecd74fd0c64e6f375de8a793fce02ec75 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 5 Jan 2007 05:42:00 +0000 Subject: [PATCH 63/81] This is the modified version of alink used to produce pe-coff powerpc executables. I received permission from Anthony Williams to distribute a modified version for use in ReactOS. Thanks to him, we're able to use better-supported elf tools for most of the things we do. svn path=/branches/powerpc/; revision=25300 --- reactos/tools/ppc-build/alink/Alinksrc.txt | 23 + reactos/tools/ppc-build/alink/Makefile | 12 + reactos/tools/ppc-build/alink/alink.cpp | 1843 +++++++++++++ reactos/tools/ppc-build/alink/alink.h | 956 +++++++ reactos/tools/ppc-build/alink/alink.mak | 11 + reactos/tools/ppc-build/alink/alink2.mak | 11 + reactos/tools/ppc-build/alink/coff.cpp | 723 +++++ reactos/tools/ppc-build/alink/cofflib.cpp | 310 +++ reactos/tools/ppc-build/alink/combine.cpp | 519 ++++ reactos/tools/ppc-build/alink/elf.cpp | 693 +++++ .../tools/ppc-build/alink/license-note.txt | 8 + reactos/tools/ppc-build/alink/objload.cpp | 1441 ++++++++++ reactos/tools/ppc-build/alink/output.cpp | 2435 +++++++++++++++++ reactos/tools/ppc-build/alink/readme.txt | 10 + reactos/tools/ppc-build/alink/tests/test.c | 1 + reactos/tools/ppc-build/alink/tests/test.obj | Bin 0 -> 456 bytes reactos/tools/ppc-build/alink/tests/test1.c | 2 + reactos/tools/ppc-build/alink/tests/test2.c | 1 + .../tools/ppc-build/alink/tests/testms.exe | Bin 0 -> 1548 bytes reactos/tools/ppc-build/alink/util.cpp | 186 ++ 20 files changed, 9185 insertions(+) create mode 100644 reactos/tools/ppc-build/alink/Alinksrc.txt create mode 100644 reactos/tools/ppc-build/alink/Makefile create mode 100644 reactos/tools/ppc-build/alink/alink.cpp create mode 100644 reactos/tools/ppc-build/alink/alink.h create mode 100644 reactos/tools/ppc-build/alink/alink.mak create mode 100644 reactos/tools/ppc-build/alink/alink2.mak create mode 100644 reactos/tools/ppc-build/alink/coff.cpp create mode 100644 reactos/tools/ppc-build/alink/cofflib.cpp create mode 100755 reactos/tools/ppc-build/alink/combine.cpp create mode 100755 reactos/tools/ppc-build/alink/elf.cpp create mode 100644 reactos/tools/ppc-build/alink/license-note.txt create mode 100644 reactos/tools/ppc-build/alink/objload.cpp create mode 100644 reactos/tools/ppc-build/alink/output.cpp create mode 100644 reactos/tools/ppc-build/alink/readme.txt create mode 100644 reactos/tools/ppc-build/alink/tests/test.c create mode 100644 reactos/tools/ppc-build/alink/tests/test.obj create mode 100644 reactos/tools/ppc-build/alink/tests/test1.c create mode 100644 reactos/tools/ppc-build/alink/tests/test2.c create mode 100755 reactos/tools/ppc-build/alink/tests/testms.exe create mode 100644 reactos/tools/ppc-build/alink/util.cpp diff --git a/reactos/tools/ppc-build/alink/Alinksrc.txt b/reactos/tools/ppc-build/alink/Alinksrc.txt new file mode 100644 index 00000000000..6fa3d16dd94 --- /dev/null +++ b/reactos/tools/ppc-build/alink/Alinksrc.txt @@ -0,0 +1,23 @@ +ALINK Source Code, V1.6, Copyright 1998-9 Anthony A.J. Williams. +All Rights Reserved. + +This source code is free for all to use, compile and distribute for any +purpose, provided it remains unmodified, and I am credited. You may not +charge for this source code, or any executables compiled from it, but you +may charge a small distribution fee to cover costs, and you may charge +for any warranty or support you may wish to give your customers. + +As this source is free, it comes with no warranty whatsoever - use it +entirely at your own risk. + +makefile contains the makefile for use with GCC (RSXNT) + +alink.mak contains the makefile for use with GCC (RSXNT), linking with the +ALINK libaries. Set C_INCLUDE_PATH to point to the ALINK library headers. + +alink2.mak contains the makefile for use with MSVC, linking with the ALINK +libraries. Set INCLUDE to point to the ALINK library headers. + +Any comments or bug reports, please email me at + +anthony_w@geocities.com diff --git a/reactos/tools/ppc-build/alink/Makefile b/reactos/tools/ppc-build/alink/Makefile new file mode 100644 index 00000000000..69b9223e6a6 --- /dev/null +++ b/reactos/tools/ppc-build/alink/Makefile @@ -0,0 +1,12 @@ +%.o: %.cpp + g++ -g -c -o $@ $< + +all: alink.exe + +clean: + rm -rf alink.exe *.o + +alink.o combine.o util.o output.o objload.o coff.o cofflib.o elf.o: alink.h + +alink.exe: alink.o combine.o util.o output.o objload.o coff.o cofflib.o elf.o + g++ -g -o $@ $^ diff --git a/reactos/tools/ppc-build/alink/alink.cpp b/reactos/tools/ppc-build/alink/alink.cpp new file mode 100644 index 00000000000..7fcddb33616 --- /dev/null +++ b/reactos/tools/ppc-build/alink/alink.cpp @@ -0,0 +1,1843 @@ +#include "alink.h" + +#define strupr(x) + +char case_sensitive=1; +char padsegments=0; +char mapfile=0; +std::string mapname; +unsigned short maxalloc=0xffff; +int output_type=OUTPUT_EXE; +std::string outname; + +FILE *afile=0; +UINT filepos=0; +long reclength=0; +unsigned char rectype=0; +char li_le=0; +UINT prevofs=0; +long prevseg=0; +long gotstart=0; +RELOC startaddr; +UINT imageBase=0; +UINT fileAlign=1; +UINT objectAlign=1; +UINT stackSize; +UINT stackCommitSize; +UINT heapSize; +UINT heapCommitSize; +unsigned char osMajor,osMinor; +unsigned char subsysMajor,subsysMinor; +unsigned int subSystem; +int buildDll=FALSE; +std::string stubName; + +long errcount=0; + +std::vector buf; +PDATABLOCK lidata; + +std::vector namelist; +std::vector seglist; +std::vector outlist; +std::vector grplist; +SORTLIST publics; +std::vector externs; +std::vector comdefs; +std::vector relocs; +std::vector impdefs; +std::vector expdefs; +std::vector libfiles; +std::vector resource; +SORTLIST comdats; +std::vector modname; +std::vector filename; +UINT namemin=0, +pubmin=0, + segmin=0, + grpmin=0, + extmin=0, + commin=0, + fixmin=0, + impmin=0,impsreq=0, + expmin=0; +UINT libPathCount=0; +std::vector libPath; +std::string entryPoint; +int cpuIdent = 0; + +void processArgs(int argc,char **argv) +{ + long i,j; + int helpRequested=FALSE; + UINT setbase,setfalign,setoalign; + UINT setstack,setstackcommit,setheap,setheapcommit; + int setsubsysmajor,setsubsysminor,setosmajor,setosminor; + unsigned char setsubsys; + int gotbase=FALSE,gotfalign=FALSE,gotoalign=FALSE,gotsubsys=FALSE; + int gotstack=FALSE,gotstackcommit=FALSE,gotheap=FALSE,gotheapcommit=FALSE; + int gotsubsysver=FALSE,gotosver=FALSE; + char *p,*q; + int c; + std::vector newargs; + FILE *argFile; + + for(i=1;i(256*1048576)) + || (getBitCount(setoalign)>1)) + { + printf("Bad object alignment\n"); + exit(1); + } + gotoalign=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + } + else if(!strcmp(&newargs[i][1],"osver")) + { + if(i<(newargs.size()-1)) + { + i++; + if(sscanf(&newargs[i][0],"%d.%d%n",&setosmajor,&setosminor,&j)!=2) + { + printf("Invalid version number %s\n",newargs[i].c_str()); + exit(1); + } + if((j!=newargs[i].size()) || (setosmajor<0) || (setosminor<0) + || (setosmajor>65535) || (setosminor>65535)) + { + printf("Invalid version number %s\n",newargs[i].c_str()); + exit(1); + } + gotosver=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + break; + case 'L': + if(newargs[i].size()==2) + { + if(i<(newargs.size()-1)) + { + i++; + j=newargs[i].size(); + if(newargs[i][j-1]!=PATH_CHAR) + { + /* append a path separator if not present */ + std::string lp = newargs[i]; + lp += PATH_CHAR; + libPath.push_back(lp); + } + else + { + libPath.push_back(newargs[i]); + } + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + break; + case 'h': + case 'H': + case '?': + if(newargs[i].size()==2) + { + helpRequested=TRUE; + } + else if(!strcmp(&newargs[i][1],"heapsize")) + { + if(i<(newargs.size()-1)) + { + i++; + setheap=strtoul(newargs[i].c_str(),&p,0); + if(p[0]) /* if not at end of arg */ + { + printf("Bad heap size\n"); + exit(1); + } + gotheap=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else if(!strcmp(&newargs[i][1],"heapcommitsize")) + { + if(i<(newargs.size()-1)) + { + i++; + setheapcommit=strtoul(newargs[i].c_str(),&p,0); + if(p[0]) /* if not at end of arg */ + { + printf("Bad heap commit size\n"); + exit(1); + } + gotheapcommit=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + break; + case 'b': + if(!strcmp(&newargs[i][1],"base")) + { + if(i<(newargs.size()-1)) + { + i++; + setbase=strtoul(newargs[i].c_str(),&p,0); + if(p[0]) /* if not at end of arg */ + { + printf("Bad image base\n"); + exit(1); + } + if(setbase&0xffff) + { + printf("Bad image base\n"); + exit(1); + } + gotbase=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + case 's': + if(!strcmp(&newargs[i][1],"subsys")) + { + if(i<(newargs.size()-1)) + { + i++; + if(!strcmp(newargs[i].c_str(),"gui") + || !strcmp(newargs[i].c_str(),"windows") + || !strcmp(newargs[i].c_str(),"win")) + { + setsubsys=PE_SUBSYS_WINDOWS; + gotsubsys=TRUE; + } + else if(!strcmp(newargs[i].c_str(),"char") + || !strcmp(newargs[i].c_str(),"console") + || !strcmp(newargs[i].c_str(),"con")) + { + setsubsys=PE_SUBSYS_CONSOLE; + gotsubsys=TRUE; + } + else if(!strcmp(newargs[i].c_str(),"native")) + { + setsubsys=PE_SUBSYS_NATIVE; + gotsubsys=TRUE; + } + else if(!strcmp(newargs[i].c_str(),"posix")) + { + setsubsys=PE_SUBSYS_POSIX; + gotsubsys=TRUE; + } + else + { + printf("Invalid subsystem id %s\n",newargs[i].c_str()); + exit(1); + } + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else if(!strcmp(&newargs[i][1],"subsysver")) + { + if(i<(newargs.size()-1)) + { + i++; + if(sscanf(newargs[i].c_str(),"%d.%d%n",&setsubsysmajor,&setsubsysminor,&j)!=2) + { + printf("Invalid version number %s\n",newargs[i].c_str()); + exit(1); + } + if((j!=newargs[i].size()) || (setsubsysmajor<0) || (setsubsysminor<0) + || (setsubsysmajor>65535) || (setsubsysminor>65535)) + { + printf("Invalid version number %s\n",newargs[i].c_str()); + exit(1); + } + gotsubsysver=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else if(!strcmp(&newargs[i][1],"stacksize")) + { + if(i<(newargs.size()-1)) + { + i++; + setstack=strtoul(newargs[i].c_str(),&p,0); + if(p[0]) /* if not at end of arg */ + { + printf("Bad stack size\n"); + exit(1); + } + gotstack=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else if(!strcmp(&newargs[i][1],"stackcommitsize")) + { + if(i<(newargs.size()-1)) + { + i++; + setstackcommit=strtoul(newargs[i].c_str(),&p,0); + if(p[0]) /* if not at end of arg */ + { + printf("Bad stack commit size\n"); + exit(1); + } + gotstackcommit=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else if(!strcmp(&newargs[i][1],"stub")) + { + if(i<(newargs.size()-1)) + { + i++; + stubName=newargs[i]; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + case 'f': + if(!strcmp(&newargs[i][1],"filealign")) + { + if(i<(newargs.size()-1)) + { + i++; + setfalign=strtoul(newargs[i].c_str(),&p,0); + if(p[0]) /* if not at end of arg */ + { + printf("Bad file alignment\n"); + exit(1); + } + if((setfalign<512)|| (setfalign>65536) + || (getBitCount(setfalign)>1)) + { + printf("Bad file alignment\n"); + exit(1); + } + gotfalign=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + case 'd': + if(!strcmp(&newargs[i][1],"dll")) + { + buildDll=TRUE; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + case 'e': + if(!strcmp(&newargs[i][1],"entry")) + { + if(i<(newargs.size()-1)) + { + i++; + entryPoint=newargs[i]; + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + } + else + { + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + break; + + default: + printf("Invalid switch %s\n",newargs[i].c_str()); + exit(1); + } + } + else + { + std::string newfilename = newargs[i]; + if(newfilename.find('.') == std::string::npos) + newfilename += DEFAULT_EXTENSION; + filename.push_back(newfilename); + } + } + if(helpRequested || !filename.size()) + { + printf("Usage: ALINK [file [file [...]]] [options]\n"); + printf("\n"); + printf(" Each file may be an object file, a library, or a Win32 resource\n"); + printf(" file. If no extension is specified, .obj is assumed. Modules are\n"); + printf(" only loaded from library files if they are required to match an\n"); + printf(" external reference.\n"); + printf(" Options and files may be listed in any order, all mixed together.\n"); + printf("\n"); + printf("The following options are permitted:\n"); + printf("\n"); + printf(" @name Load additional options from response file name\n"); + printf(" -c Enable Case sensitivity\n"); + printf(" -c+ Enable Case sensitivity\n"); + printf(" -c- Disable Case sensitivity\n"); + printf(" -p Enable segment padding\n"); + printf(" -p+ Enable segment padding\n"); + printf(" -p- Disable segment padding\n"); + printf(" -m Enable map file\n"); + printf(" -m+ Enable map file\n"); + printf(" -m- Disable map file\n"); + printf("----Press Enter to continue---"); + while(((c=getchar())!='\n') && (c!=EOF)); + printf("\n"); + printf(" -h Display this help list\n"); + printf(" -H \"\n"); + printf(" -? \"\n"); + printf(" -L ddd Add directory ddd to search list\n"); + printf(" -o name Choose output file name\n"); + printf(" -oXXX Choose output format XXX\n"); + printf(" Available options are:\n"); + printf(" COM - MSDOS COM file\n"); + printf(" EXE - MSDOS EXE file\n"); + printf(" PE - Win32 PE Executable\n"); + printf(" -entry name Use public symbol name as the entry point\n"); + printf("\nOptions for PE files:\n"); + printf(" -base addr Set base address of image\n"); + printf(" -filealign addr Set section alignment in file\n"); + printf(" -objectalign addr Set section alignment in memory\n"); + printf(" -subsys xxx Set subsystem used\n"); + printf(" Available options are:\n"); + printf(" console Select character mode\n"); + printf(" con \"\n"); + printf(" char \"\n"); + printf(" windows Select windowing mode\n"); + printf(" win \"\n"); + printf(" gui \"\n"); + printf(" native Select native mode\n"); + printf(" posix Select POSIX mode\n"); + printf(" -subsysver x.y Select subsystem version x.y\n"); + printf(" -osver x.y Select OS version x.y\n"); + printf(" -stub xxx Use xxx as the MSDOS stub\n"); + printf(" -dll Build DLL instead of EXE\n"); + printf(" -stacksize xxx Set stack size to xxx\n"); + printf(" -stackcommitsize xxx Set stack commit size to xxx\n"); + printf(" -heapsize xxx Set heap size to xxx\n"); + printf(" -heapcommitsize xxx Set heap commit size to xxx\n"); + exit(0); + } + if((output_type!=OUTPUT_PE) && + (gotoalign || gotfalign || gotbase || gotsubsys || gotstack || + gotstackcommit || gotheap || gotheapcommit || buildDll || stubName.size() || + gotsubsysver || gotosver)) + { + printf("Option not supported for non-PE output formats\n"); + exit(1); + } + if(gotstack) + { + stackSize=setstack; + } + if(gotstackcommit) + { + stackCommitSize=setstackcommit; + } + if(stackCommitSize>stackSize) + { + printf("Stack commit size is greater than stack size, committing whole stack\n"); + stackCommitSize=stackSize; + } + if(gotheap) + { + heapSize=setheap; + } + if(gotheapcommit) + { + heapCommitSize=setheapcommit; + } + if(heapCommitSize>heapSize) + { + printf("Heap commit size is greater than heap size, committing whole heap\n"); + heapCommitSize=heapSize; + } + if(gotoalign) + { + objectAlign=setoalign; + } + if(gotfalign) + { + fileAlign=setfalign; + } + if(gotbase) + { + imageBase=setbase; + } + if(gotsubsys) + { + subSystem=setsubsys; + } + if(gotsubsysver) + { + subsysMajor=setsubsysmajor; + subsysMinor=setsubsysminor; + } + if(gotosver) + { + osMajor=setosmajor; + osMinor=setosminor; + } +} + +void matchExterns() +{ + long i,j,old_nummods,k; + int n; + std::string name; + SORTLIST::iterator listnode, l; + PPUBLIC pubdef; + + do + { + for(i=0;isecond.size();k++) + { + /* exports can only match global publics */ + if(((PPUBLIC)listnode->second[k])->modnum==0) + { + expdefs[i].pubdef=(PPUBLIC)listnode->second[k]; + break; + } + } + } + } + for(i=0;isecond.size();k++) + { + /* local publics can only match externs in same module */ + /* and global publics can only match global externs */ + if(((PPUBLIC)listnode->second[k])->modnum==externs[i].modnum) + { + externs[i].pubdef=(PPUBLIC)listnode->second[k]; + externs[i].flags=EXT_MATCHEDPUBLIC; + break; + } + } + } + if(externs[i].flags==EXT_NOMATCH) + { + for(j=0;jsecond.size()); + break; + } + } + } + } + for(i=0;(isecond.size()); + break; + } + } + } + } + for(l=publics.begin(); + (l!=publics.end())&&(modname.size()==old_nummods); + ++l) + { + for(k=0;ksecond.size();k++) + { + pubdef=(PPUBLIC)l->second[k]; + if(pubdef->aliasName == "") continue; + if((listnode=publics.find(pubdef->aliasName)) != publics.end()) + { + for(j=0;jsecond.size();j++) + { + if((((PPUBLIC)listnode->second[j])->modnum==pubdef->modnum) + && ((PPUBLIC)listnode->second[j])->aliasName == "") + { + /* if we've found a match for the alias, then kill the alias */ + (*pubdef)=(*((PPUBLIC)listnode->second[j])); + break; + } + } + } + if(pubdef->aliasName == "") continue; + for(k=0;kaliasName; + if(!(libfiles[k].flags&LIBF_CASESENSITIVE)) + { + strupr(name); + } + + if((listnode=libfiles[k].symbols.find(name)) != libfiles[k].symbols.end()) + { + loadlibmod(k,listnode->second.size()); + break; + } + } + + } + } + + } while (old_nummods!=modname.size()); +} + +void matchComDefs() +{ + int i,j,k; + int comseg; + int comfarseg; + SORTLIST::iterator listnode; + PPUBLIC pubdef; + + if(!comdefs.size()) return; + + for(i=0;imodnum!=comdefs[j]->modnum) continue; + if(comdefs[i]->name == comdefs[j]->name) + { + if(comdefs[i]->isFar!=comdefs[j]->isFar) + { + printf("Mismatched near/far type for COMDEF %s\n",comdefs[i]->name.c_str()); + exit(1); + } + if(comdefs[i]->length>comdefs[j]->length) + comdefs[j]->length=comdefs[i]->length; + free(comdefs[i]); + comdefs[i]=0; + break; + } + } + } + + for(i=0;iname)) != publics.end()) + { + for(j=0;jsecond.size();j++) + { + /* local publics can only match externs in same module */ + /* and global publics can only match global externs */ + if((((PPUBLIC)listnode->second[j])->modnum==comdefs[i]->modnum) + && ((PPUBLIC)listnode->second[j])->aliasName == "") + { + free(comdefs[i]); + comdefs[i]=0; + break; + } + } + } + } + + PSEG seg = new SEG(); + seg->name = "COMDEFS"; + comseg=seglist.size(); + seglist.push_back(seg); + + for(i=0;iname == "") continue; + if(grplist[i]->name != "DGROUP") + { + if(grplist[i]->numsegs==0) continue; /* don't add to an emtpy group */ + /* because empty groups are special */ + /* else add to group */ + grplist[i]->segindex[grplist[i]->numsegs]=seglist[comseg]; + grplist[i]->numsegs++; + break; + } + } + + seg = new SEG(); + seg->name = "FARCOMDEFS"; + comfarseg=seglist.size(); + seglist.push_back(seg); + + for(i=0;iisFar) + { + if(comdefs[i]->length>65536) + { + seg = new SEG(); + seg->name = "FARCOMDEFS"; + seg->length=comdefs[i]->length; + seg->datmask.resize((comdefs[i]->length+7)/8); + for(j=0;j<(comdefs[i]->length+7)/8;j++) + seglist[seglist.size()-1]->datmask[j]=0; + pubdef->seg=seglist[seglist.size()-1]; + seglist.push_back(seg); + pubdef->ofs=0; + } + else if((comdefs[i]->length+seglist[comfarseg]->length)>65536) + { + seglist[comfarseg]->datmask.resize((seglist[comfarseg]->length+7)/8); + for(j=0;j<(seglist[comfarseg]->length+7)/8;j++) + seglist[comfarseg]->datmask[j]=0; + + seg = new SEG(); + seg->name = "FARCOMDEFS"; + seg->length=comdefs[i]->length; + comfarseg=seglist.size(); + seglist.push_back(seg); + pubdef->seg=seglist[comfarseg]; + pubdef->ofs=0; + } + else + { + pubdef->seg=seglist[comfarseg]; + pubdef->ofs=seglist[comfarseg]->length; + seglist[comfarseg]->length+=comdefs[i]->length; + } + } + else + { + pubdef->seg=seglist[comseg]; + pubdef->ofs=seglist[comseg]->length; + seglist[comseg]->length+=comdefs[i]->length; + } + pubdef->modnum=comdefs[i]->modnum; + pubdef->grpnum=-1; + pubdef->typenum=0; + if((listnode=publics.find(comdefs[i]->name)) != publics.end()) + { + for(j=0;jsecond.size();++j) + { + if(((PPUBLIC)listnode->second[j])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[j])->aliasName == "") + { + printf("Duplicate public symbol %s\n",comdefs[i]->name.c_str()); + exit(1); + } + (*((PPUBLIC)listnode->second[j]))=(*pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator it = publics.find(comdefs[i]->name); + if(it == publics.end()) + { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(comdefs[i]->name, vv)); + } else { + it->second.push_back((void *)pubdef); + } + } + } + seglist[comfarseg]->datmask.reserve((seglist[comfarseg]->length+7)/8); + for(j=0;j<(seglist[comfarseg]->length+7)/8;j++) + seglist[comfarseg]->datmask[j]=0; + + + seglist[comseg]->datmask.reserve((seglist[comseg]->length+7)/8); + for(j=0;j<(seglist[comseg]->length+7)/8;j++) + seglist[comseg]->datmask[j]=0; + + + for(i=0;isecond.size();j++) + { + /* global publics only can match exports */ + if(((PPUBLIC)listnode->second[j])->modnum==0) + { + expdefs[i].pubdef=(PPUBLIC)listnode->second[j]; + break; + } + } + } + } + for(i=0;isecond.size();j++) + { + /* global publics only can match exports */ + if(((PPUBLIC)(listnode->second[j]))->modnum==externs[i].modnum) + { + externs[i].pubdef=(PPUBLIC)(listnode->second[j]); + externs[i].flags=EXT_MATCHEDPUBLIC; + break; + } + } + } + } +} + +void sortSegments() +{ + long i,j; + PSEG k, baseSeg; + UINT base=0,align; + + for(i=0;iattr&SEG_ALIGN)!=SEG_ABS) + { + seglist[i]->absframe=0; + } + } + } + + for(i=0;iseg=NULL; + for(j=0;jnumsegs;j++) + { + k=grplist[i]->segindex[j]; + if(!k) + { + printf("Error - group %s contains non-existent segment\n",grplist[i]->name.c_str()); + exit(1); + } + /* don't add removed sections */ + if(k->winFlags & WINF_REMOVE) + { + continue; + } + /* add non-absolute segment */ + if((k->attr&SEG_ALIGN)!=SEG_ABS) + { + switch(k->attr&SEG_ALIGN) + { + case SEG_WORD: + align=2; + break; + case SEG_DWORD: + align=4; + break; + case SEG_8BYTE: + align=0x8; + break; + case SEG_PARA: + align=0x10; + break; + case SEG_32BYTE: + align=0x20; + break; + case SEG_64BYTE: + align=0x40; + break; + case SEG_PAGE: + align=0x100; + break; + case SEG_MEMPAGE: + align=0x1000; + break; + case SEG_BYTE: + default: + align=1; + break; + } + if(alignsetbase(base); + if(k->length>0) + { + base+=k->length; + if(k->absframe!=0) + { + printf("Error - Segment %s part of more than one group\n",k->name.c_str()); + exit(1); + } + k->absframe=1; + k->absofs=i+1; + if(!grplist[i]->seg) + { + grplist[i]->seg=k; + } + if(outlist.size()==0) + { + baseSeg=k; + } + else + { + outlist[outlist.size()-1]->virtualSize=k->getbase()- + outlist[outlist.size()-1]->getbase(); + } + outlist.push_back(k); + } + } + } + } + } + for(i=0;iwinFlags & WINF_REMOVE) + { + continue; + } + /* add non-absolute segment, not already dealt with */ + if(((seglist[i]->attr&SEG_ALIGN)!=SEG_ABS) && + !seglist[i]->absframe) + { + switch(seglist[i]->attr&SEG_ALIGN) + { + case SEG_WORD: + case SEG_BYTE: + case SEG_DWORD: + case SEG_PARA: + align=0x10; + break; + case SEG_PAGE: + align=0x100; + break; + case SEG_MEMPAGE: + align=0x1000; + break; + default: + align=1; + break; + } + if(alignsetbase(base); + if(seglist[i]->length>0) + { + base+=seglist[i]->length; + seglist[i]->absframe=1; + seglist[i]->absofs=0; + if(outlist.size()==0) + { + baseSeg=seglist[i]; + } + else + { + outlist[outlist.size()-1]->virtualSize=seglist[i]->getbase()- + outlist[outlist.size()-1]->getbase(); + } + outlist.push_back(seglist[i]); + } + } + else if((seglist[i]->attr&SEG_ALIGN)==SEG_ABS) + { + seglist[i]->setbase((seglist[i]->absframe<<4)+seglist[i]->absofs); + } + } + } + /* build size of last segment in output list */ + if(outlist.size()) + { + outlist[outlist.size()-1]->virtualSize= + (outlist[outlist.size()-1]->length+objectAlign-1)& + (0xffffffff-(objectAlign-1)); + } + for(i=0;iseg)) grplist[i]->seg=baseSeg; + } +} + +void printRelocs(FILE *afile) +{ + int i; + + if(relocs.size()) + { + INT_TO_NAME disptypes[] = { + { REL_SEGDISP, "REL_SEGDISP" }, + { REL_GRPDISP, "REL_GRPDISP" }, + { REL_EXTDISP, "REL_EXTDISP" }, + { REL_EXPFRAME, "REL_EXPFRAME" }, + { REL_SEGONLY, "REL_SEGONLY" }, + { REL_GRPONLY, "REL_GRPONLY" }, + { REL_EXTONLY, "REL_EXTONLY" }, + { 0 } + }; + + INT_TO_NAME frametypes[] = { + { REL_SEGFRAME, "REL_SEGFRAME" }, + { REL_GRPFRAME, "REL_GRPFRAME" }, + { REL_EXTFRAME, "REL_EXTFRAME" }, + { REL_LILEFRAME,"REL_LILEFRAME"}, + { REL_TARGETFRAME,"REL_TARGETFRAME"}, + { 0 } + }; + + INT_TO_NAME reloctype[] = { + { FIX_LBYTE, "FIX_LBYTE" }, + { FIX_OFS16, "FIX_OFS16" }, + { FIX_BASE, "FIX_BASE" }, + { FIX_PTR1616, "FIX_PTR1616" }, + { FIX_HBYTE, "FIX_HBYTE" }, + { FIX_OFS16_2, "FIX_OFS16_2" }, + { FIX_OFS32, "FIX_OFS32" }, + { FIX_PTR1632, "FIX_PTR1632" }, + { FIX_RVA32, "FIX_RVA32" }, + { FIX_REL32, "FIX_REL32" }, + { FIX_PPC_ADDR24, "FIX_PPC_ADDR24" }, + { FIX_PPC_REL24, "FIX_PPC_REL24" }, + { FIX_PPC_RVA16LO, "FIX_PPC_RVA16LO" }, + { FIX_PPC_RVA16HA, "FIX_PPC_RVA16HA" }, + { FIX_PPC_SECTOFF, "FIX_PPC_SECTOFF" }, + { 0 } + }; + + fprintf(afile,"\n %li relocs:\n",relocs.size()); + for(i=0;i %-10s(%d) type %-16s(%d) ofs %08x disp %08x" + " | frame (%-10s) target (%-10s)" + " | addr %08x off %08x info %08x\n", + findName(frametypes, relocs[i]->ftype), + relocs[i]->ftype, + findName(disptypes, relocs[i]->ttype), + relocs[i]->ttype, + findName(reloctype, relocs[i]->rtype), + relocs[i]->rtype, + relocs[i]->ofs, + relocs[i]->disp, + (relocs[i]->seg ? + relocs[i]->seg->name.c_str() : + externs[relocs[i]->frame].name.c_str()), + (relocs[i]->targseg ? + relocs[i]->targseg->name.c_str() : + externs[relocs[i]->target].name.c_str()), + relocs[i]->orig.r_address, + relocs[i]->orig.r_offset, + relocs[i]->orig.r_info); + } + } +} + +void loadFiles() +{ + long i,j,k; + std::string name; + + for(i=0;iname.c_str()); + switch(seglist[i]->attr&SEG_COMBINE) + { + case SEG_PRIVATE: + fprintf(afile,"PRIVATE "); + break; + case SEG_PUBLIC: + fprintf(afile,"PUBLIC "); + break; + case SEG_PUBLIC2: + fprintf(afile,"PUBLIC(2) "); + break; + case SEG_STACK: + fprintf(afile,"STACK "); + break; + case SEG_COMMON: + fprintf(afile,"COMMON "); + break; + case SEG_PUBLIC3: + fprintf(afile,"PUBLIC(3) "); + break; + default: + fprintf(afile,"unknown "); + break; + } + if(seglist[i]->attr&SEG_USE32) + { + fprintf(afile,"USE32 "); + } + else + { + fprintf(afile,"USE16 "); + } + switch(seglist[i]->attr&SEG_ALIGN) + { + case SEG_ABS: + fprintf(afile,"AT 0%04lXh ",seglist[i]->absframe); + break; + case SEG_BYTE: + fprintf(afile,"BYTE "); + break; + case SEG_WORD: + fprintf(afile,"WORD "); + break; + case SEG_PARA: + fprintf(afile,"PARA "); + break; + case SEG_PAGE: + fprintf(afile,"PAGE "); + break; + case SEG_DWORD: + fprintf(afile,"DWORD "); + break; + case SEG_MEMPAGE: + fprintf(afile,"MEMPAGE "); + break; + default: + fprintf(afile,"unknown "); + } + if(seglist[i]->classindex>=0) + fprintf(afile,"'%s'\n",namelist[seglist[i]->classindex].c_str()); + else + fprintf(afile,"\n"); + fprintf(afile," at %08lX, length %08lX\n", + (output_type == OUTPUT_PE) ? + seglist[i]->getbase() + objectAlign + imageBase : + seglist[i]->getbase(), + seglist[i]->length); + } + } + for(i=0;iname.c_str()); + for(j=0;jnumsegs;j++) + { + fprintf(afile," %s\n",grplist[i]->segindex[j]->name.c_str()); + } + } + + if(publics.size()) + { + fprintf(afile,"\npublics:\n"); + } + for(l=publics.begin();l!=publics.end();++l) + { + for(j=0;jsecond.size();++j) + { + q=(PPUBLIC)l->second[j]; + if(q->modnum) continue; + fprintf(afile,"%s at %s:%08lX\n", + l->first.c_str(), + (q->seg) ? q->seg->name.c_str() : "Absolute", + q->ofs); + } + } + + printRelocs(afile); + + if(expdefs.size()) + { + fprintf(afile,"\n %li exports:\n",expdefs.size()); + for(i=0;i=0)&&(outname[i]!='.')&&(outname[i]!=PATH_CHAR)&&(outname[i]!=':')) + { + i--; + } + if(outname[i]=='.') + { + outname[i]=0; + } + } + i=outname.size(); + while((i>=0)&&(outname[i]!='.')&&(outname[i]!=PATH_CHAR)&&(outname[i]!=':')) + { + i--; + } + if(outname[i]!='.') + { + switch(output_type) + { + case OUTPUT_EXE: + case OUTPUT_PE: + if(!buildDll) + { + outname += ".exe"; + } + else + { + outname += ".dll"; + } + break; + case OUTPUT_COM: + outname += ".com"; + break; + default: + break; + } + } + + if(mapfile) + { + if(!mapname.size()) + { + mapname = outname; + while((i>=0)&&(mapname[i]!='.')&&(mapname[i]!=PATH_CHAR)&&(mapname[i]!=':')) + { + i--; + } + if(mapname[i]!='.') + { + i=mapname.size(); + } + mapname += ".map"; + } + } + else + { + if(mapname.size()) + { + mapname=""; + } + } + + loadFiles(); + + if(!modname.size()) + { + printf("No required modules specified\n"); + exit(1); + } + + if(resource.size() && (output_type!=OUTPUT_PE)) + { + printf("Cannot link resources into a non-PE application\n"); + exit(1); + } + + if(entryPoint.size()) + { + if(!case_sensitive) + { + strupr(entryPoint); + } + + if(gotstart) + { + printf("Warning, overriding entry point from Command Line\n"); + } + /* define an external reference for entry point */ + externs.push_back(EXTREC(entryPoint)); + + /* point start address to this external */ + startaddr.ftype=REL_EXTFRAME; /* REL_EXTDISP ? */ + startaddr.frame=externs.size()-1; + startaddr.ttype=REL_EXTONLY; + startaddr.target=externs.size()-1; + + gotstart=TRUE; + } + + matchExterns(); + printf("matched Externs\n"); + + matchComDefs(); + printf("matched ComDefs\n"); + + for(i=0;ialiasName.c_str() != "") + { + printf("Unresolved export %s=%s, with alias %s\n",expdefs[i].exp_name.c_str(),expdefs[i].int_name.c_str(),(char *)expdefs[i].pubdef->aliasName.c_str()); + errcount++; + } + + } + + for(i=0;ialiasName != "") + { + printf("Unresolved external %s with alias %s\n",externs[i].name.c_str(),externs[i].pubdef->aliasName.c_str()); + errcount++; + } + } + } + + if(errcount!=0) + { + exit(1); + } + + combineBlocks(); + sortSegments(); + + if(mapfile) generateMap(); + switch(output_type) + { + case OUTPUT_COM: + OutputCOMfile(outname); + break; + case OUTPUT_EXE: + OutputEXEfile(outname); + break; + case OUTPUT_PE: + OutputWin32file(outname); + break; + default: + printf("Invalid output type\n"); + exit(1); + break; + } + return 0; +} diff --git a/reactos/tools/ppc-build/alink/alink.h b/reactos/tools/ppc-build/alink/alink.h new file mode 100644 index 00000000000..86f032ab8da --- /dev/null +++ b/reactos/tools/ppc-build/alink/alink.h @@ -0,0 +1,956 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned long ULONG; + +#define typeid x_typeid +#define class x_class +#define stricmp strcasecmp + +#define TRUE (1==1) +#define FALSE (1==0) + +#define SWITCHCHAR '-' +#define PATH_CHAR '\\' +#define DEFAULT_EXTENSION ".obj" + +#define ERR_EXTRA_DATA 1 +#define ERR_NO_HEADER 2 +#define ERR_NO_RECDATA 3 +#define ERR_NO_MEM 4 +#define ERR_INV_DATA 5 +#define ERR_INV_SEG 6 +#define ERR_BAD_FIXUP 7 +#define ERR_BAD_SEGDEF 8 +#define ERR_ABS_SEG 9 +#define ERR_DUP_PUBLIC 10 +#define ERR_NO_MODEND 11 +#define ERR_EXTRA_HEADER 12 +#define ERR_UNKNOWN_RECTYPE 13 +#define ERR_SEG_TOO_LARGE 14 +#define ERR_MULTIPLE_STARTS 15 +#define ERR_BAD_GRPDEF 16 +#define ERR_OVERWRITE 17 +#define ERR_INVALID_COMENT 18 +#define ERR_ILLEGAL_IMPORTS 19 + +#define PREV_LE 1 +#define PREV_LI 2 +#define PREV_LI32 3 + +#define THEADR 0x80 +#define LHEADR 0x82 +#define COMENT 0x88 +#define MODEND 0x8a +#define MODEND32 0x8b +#define EXTDEF 0x8c +#define TYPDEF 0x8e +#define PUBDEF 0x90 +#define PUBDEF32 0x91 +#define LINNUM 0x94 +#define LINNUM32 0x95 +#define LNAMES 0x96 +#define SEGDEF 0x98 +#define SEGDEF32 0x99 +#define GRPDEF 0x9a +#define FIXUPP 0x9c +#define FIXUPP32 0x9d +#define LEDATA 0xa0 +#define LEDATA32 0xa1 +#define LIDATA 0xa2 +#define LIDATA32 0xa3 +#define COMDEF 0xb0 +#define BAKPAT 0xb2 +#define BAKPAT32 0xb3 +#define LEXTDEF 0xb4 +#define LEXTDEF32 0xb5 +#define LPUBDEF 0xb6 +#define LPUBDEF32 0xb7 +#define LCOMDEF 0xb8 +#define CEXTDEF 0xbc +#define COMDAT 0xc2 +#define COMDAT32 0xc3 +#define LINSYM 0xc4 +#define LINSYM32 0xc5 +#define ALIAS 0xc6 +#define NBKPAT 0xc8 +#define NBKPAT32 0xc9 +#define LLNAMES 0xca +#define LIBHDR 0xf0 +#define LIBEND 0xf1 + +#define COMENT_TRANSLATOR 0x00 +#define COMENT_INTEL_COPYRIGHT 0x01 +#define COMENT_LIB_SPEC 0x81 +#define COMENT_MSDOS_VER 0x9c +#define COMENT_MEMMODEL 0x9d +#define COMENT_DOSSEG 0x9e +#define COMENT_DEFLIB 0x9f +#define COMENT_OMFEXT 0xa0 +#define COMENT_NEWOMF 0xa1 +#define COMENT_LINKPASS 0xa2 +#define COMENT_LIBMOD 0xa3 +#define COMENT_EXESTR 0xa4 +#define COMENT_INCERR 0xa6 +#define COMENT_NOPAD 0xa7 +#define COMENT_WKEXT 0xa8 +#define COMENT_LZEXT 0xa9 +#define COMENT_PHARLAP 0xaa +#define COMENT_IBM386 0xb0 +#define COMENT_RECORDER 0xb1 +#define COMENT_COMMENT 0xda +#define COMENT_COMPILER 0xdb +#define COMENT_DATE 0xdc +#define COMENT_TIME 0xdd +#define COMENT_USER 0xdf +#define COMENT_DEPFILE 0xe9 +#define COMENT_COMMANDLINE 0xff +#define COMENT_PUBTYPE 0xe1 +#define COMENT_COMPARAM 0xea +#define COMENT_TYPDEF 0xe3 +#define COMENT_STRUCTMEM 0xe2 +#define COMENT_OPENSCOPE 0xe5 +#define COMENT_LOCAL 0xe6 +#define COMENT_ENDSCOPE 0xe7 +#define COMENT_SOURCEFILE 0xe8 + +#define EXT_IMPDEF 0x01 +#define EXT_EXPDEF 0x02 + +#define SEG_ALIGN 0x3e0 +#define SEG_COMBINE 0x1c +#define SEG_BIG 0x02 +#define SEG_USE32 0x01 + +#define SEG_ABS 0x00 +#define SEG_BYTE 0x20 +#define SEG_WORD 0x40 +#define SEG_PARA 0x60 +#define SEG_PAGE 0x80 +#define SEG_DWORD 0xa0 +#define SEG_MEMPAGE 0xc0 +#define SEG_BADALIGN 0xe0 +#define SEG_8BYTE 0x100 +#define SEG_32BYTE 0x200 +#define SEG_64BYTE 0x300 + +#define SEG_PRIVATE 0x00 +#define SEG_PUBLIC 0x08 +#define SEG_PUBLIC2 0x10 +#define SEG_STACK 0x14 +#define SEG_COMMON 0x18 +#define SEG_PUBLIC3 0x1c + +typedef enum segdisp_t { +//#define REL_SEGDISP 0x80 + REL_SEGDISP = 0x80, +//#define REL_GRPDISP 0x81 + REL_GRPDISP = 0x81, +//#define REL_EXTDISP 0x82 + REL_EXTDISP = 0x82, +//#define REL_EXPFRAME 0x83 + REL_EXPFRAME = 0x83, +//#define REL_SEGONLY 0x84 + REL_SEGONLY = 0x84, +//#define REL_GRPONLY 0x85 + REL_GRPONLY = 0x85, +//#define REL_EXTONLY 0x86 + REL_EXTONLY = 0x86 +} segdisp_t; + +typedef enum segframe_t { +//#define REL_SEGFRAME 0 + REL_SEGFRAME, +//#define REL_GRPFRAME 1 + REL_GRPFRAME, +//#define REL_EXTFRAME 2 + REL_EXTFRAME, +//#define REL_EXPFFRAME 3 + REL_EXPFFRAME, +//#define REL_LILEFRAME 4 + REL_LILEFRAME, +//#define REL_TARGETFRAME 5 + REL_TARGETFRAME +}; + +#define FIX_SELFREL 0x10 +#define FIX_MASK (0x0f+FIX_SELFREL) + +#define FIX_THRED 0x08 +#define THRED_MASK 0x07 + +#define FIX_LBYTE 0 +#define FIX_OFS16 1 +#define FIX_BASE 2 +#define FIX_PTR1616 3 +#define FIX_HBYTE 4 +#define FIX_OFS16_2 5 +#define FIX_OFS32 9 +#define FIX_PTR1632 11 +#define FIX_OFS32_2 13 + +#define FIX_PPC_ADDR24 259 +#define FIX_PPC_REL24 260 +#define FIX_PPC_RVA16LO 261 +#define FIX_PPC_RVA16HA 262 +#define FIX_PPC_SECTOFF 263 + +/* RVA32 fixups are not supported by OMF, so has an out-of-range number */ +#define FIX_RVA32 256 +#define FIX_REL32 264 +#define FIX_ADDR32 265 + +#define FIX_SELF_LBYTE (FIX_LBYTE+FIX_SELFREL) +#define FIX_SELF_OFS16 (FIX_OFS16+FIX_SELFREL) +#define FIX_SELF_OFS16_2 (FIX_OFS16_2+FIX_SELFREL) +#define FIX_SELF_OFS32 (FIX_OFS32+FIX_SELFREL) +#define FIX_SELF_OFS32_2 (FIX_OFS32_2+FIX_SELFREL) + +#define LIBF_CASESENSITIVE 1 + +#define EXT_NOMATCH 0 +#define EXT_MATCHEDPUBLIC 1 +#define EXT_MATCHEDIMPORT 2 + +#define PE_SIGNATURE 0x00 +#define PE_MACHINEID 0x04 +#define PE_NUMOBJECTS 0x06 +#define PE_DATESTAMP 0x08 +#define PE_SYMBOLPTR 0x0c +#define PE_NUMSYMBOLS 0x10 +#define PE_HDRSIZE 0x14 +#define PE_FLAGS 0x16 +#define PE_MAGIC 0x18 +#define PE_LMAJOR 0x1a +#define PE_LMINOR 0x1b +#define PE_CODESIZE 0x1c +#define PE_INITDATASIZE 0x20 +#define PE_UNINITDATASIZE 0x24 +#define PE_ENTRYPOINT 0x28 +#define PE_CODEBASE 0x2c +#define PE_DATABASE 0x30 +#define PE_IMAGEBASE 0x34 +#define PE_OBJECTALIGN 0x38 +#define PE_FILEALIGN 0x3c +#define PE_OSMAJOR 0x40 +#define PE_OSMINOR 0x42 +#define PE_USERMAJOR 0x44 +#define PE_USERMINOR 0x46 +#define PE_SUBSYSMAJOR 0x48 +#define PE_SUBSYSMINOR 0x4a +#define PE_IMAGESIZE 0x50 +#define PE_HEADERSIZE 0x54 +#define PE_CHECKSUM 0x58 +#define PE_SUBSYSTEM 0x5c +#define PE_DLLFLAGS 0x5e +#define PE_STACKSIZE 0x60 +#define PE_STACKCOMMSIZE 0x64 +#define PE_HEAPSIZE 0x68 +#define PE_HEAPCOMMSIZE 0x6c +#define PE_LOADERFLAGS 0x70 +#define PE_NUMRVAS 0x74 +#define PE_EXPORTRVA 0x78 +#define PE_EXPORTSIZE 0x7c +#define PE_IMPORTRVA 0x80 +#define PE_IMPORTSIZE 0x84 +#define PE_RESOURCERVA 0x88 +#define PE_RESOURCESIZE 0x8c +#define PE_EXCEPTIONRVA 0x90 +#define PE_EXCEPTIONSIZE 0x94 +#define PE_SECURITYRVA 0x98 +#define PE_SECURITYSIZE 0x9c +#define PE_FIXUPRVA 0xa0 +#define PE_FIXUPSIZE 0xa4 +#define PE_DEBUGRVA 0xa8 +#define PE_DEBUGSIZE 0xac +#define PE_DESCRVA 0xb0 +#define PE_DESCSIZE 0xb4 +#define PE_MSPECRVA 0xb8 +#define PE_MSPECSIZE 0xbc +#define PE_TLSRVA 0xc0 +#define PE_TLSSIZE 0xc4 +#define PE_LOADCONFIGRVA 0xc8 +#define PE_LOADCONFIGSIZE 0xcc +#define PE_BOUNDIMPRVA 0xd0 +#define PE_BOUNDIMPSIZE 0xd4 +#define PE_IATRVA 0xd8 +#define PE_IATSIZE 0xdc + +#define PE_OBJECT_NAME 0x00 +#define PE_OBJECT_VIRTSIZE 0x08 +#define PE_OBJECT_VIRTADDR 0x0c +#define PE_OBJECT_RAWSIZE 0x10 +#define PE_OBJECT_RAWPTR 0x14 +#define PE_OBJECT_RELPTR 0x18 +#define PE_OBJECT_LINEPTR 0x1c +#define PE_OBJECT_NUMREL 0x20 +#define PE_OBJECT_NUMLINE 0x22 +#define PE_OBJECT_FLAGS 0x24 + +#define PE_BASE_HEADER_SIZE 0x18 +#define PE_OPTIONAL_HEADER_SIZE 0xe0 +#define PE_OBJECTENTRY_SIZE 0x28 +#define PE_HEADBUF_SIZE (PE_BASE_HEADER_SIZE+PE_OPTIONAL_HEADER_SIZE) +#define PE_IMPORTDIRENTRY_SIZE 0x14 +#define PE_NUM_VAS 0x10 +#define PE_EXPORTHEADER_SIZE 0x28 +#define PE_RESENTRY_SIZE 0x08 +#define PE_RESDIR_SIZE 0x10 +#define PE_RESDATAENTRY_SIZE 0x10 +#define PE_SYMBOL_SIZE 0x12 +#define PE_RELOC_SIZE 0x0a + +#define PE_ORDINAL_FLAG 0x80000000 +#define PE_INTEL386 0x014c +#define PE_POWERPC 0x01f0 +#define PE_MAGICNUM 0x010b +#define PE_FILE_EXECUTABLE 0x0002 +#define PE_FILE_32BIT 0x0100 +#define PE_FILE_LIBRARY 0x2000 + +#define PE_REL_LOW16 0x2000 +#define PE_REL_OFS32 0x3000 + +#define PE_SUBSYS_NATIVE 1 +#define PE_SUBSYS_WINDOWS 2 +#define PE_SUBSYS_CONSOLE 3 +#define PE_SUBSYS_POSIX 7 + +//seglist[0]->nameindex=0 o=-1 l=38 a=140 f=00100a00 +//seglist[1]->nameindex=1 o=-1 l=8 a=178 f=60400020 +//seglist[2]->nameindex=2 o=-1 l=20 a=186 f=40300040 + +#define WINF_UNDEFINED 0x00000000 +#define WINF_CODE 0x00000020 +#define WINF_INITDATA 0x00000040 +#define WINF_UNINITDATA 0x00000080 +#define WINF_DISCARDABLE 0x02000000 +#define WINF_NOPAGE 0x08000000 +#define WINF_SHARED 0x10000000 +#define WINF_EXECUTE 0x20000000 +#define WINF_READABLE 0x40000000 +#define WINF_WRITEABLE 0x80000000 +#define WINF_ALIGN_NOPAD 0x00000008 +#define WINF_ALIGN_BYTE 0x00100000 +#define WINF_ALIGN_WORD 0x00200000 +#define WINF_ALIGN_DWORD 0x00300000 +#define WINF_ALIGN_8 0x00400000 +#define WINF_ALIGN_PARA 0x00500000 +#define WINF_ALIGN_32 0x00600000 +#define WINF_ALIGN_64 0x00700000 +#define WINF_ALIGN (WINF_ALIGN_64) +#define WINF_COMMENT 0x00000200 +#define WINF_REMOVE 0x00000800 +#define WINF_COMDAT 0x00001000 +#define WINF_NEG_FLAGS (WINF_DISCARDABLE | WINF_NOPAGE) +#define WINF_IMAGE_FLAGS 0xfa0008e0 + +#define COFF_SYM_EXTERNAL 2 +#define COFF_SYM_STATIC 3 +#define COFF_SYM_LABEL 6 +#define COFF_SYM_FUNCTION 101 +#define COFF_SYM_FILE 103 +#define COFF_SYM_SECTION 104 + +#define COFF_FIX_DIR32 6 +#define COFF_FIX_RVA32 7 +#define COFF_FIX_REL32 0x14 + +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR24 2 +#define R_PPC_ADDR16 3 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_REL24 10 +#define R_PPC_UADDR32 24 +#define R_PPC_REL32 26 +#define R_PPC_SECTOFF 33 + +#define IMAGE_REL_PPC_ABSOLUTE 0x00 +#define IMAGE_REL_PPC_ADDR64 0x01 +#define IMAGE_REL_PPC_ADDR32 0x02 +#define IMAGE_REL_PPC_ADDR24 0x03 +#define IMAGE_REL_PPC_ADDR16 0x04 +#define IMAGE_REL_PPC_ADDR14 0x05 +#define IMAGE_REL_PPC_REL24 0x06 +#define IMAGE_REL_PPC_REL14 0x07 +#define IMAGE_REL_PPC_ADDR32NB 0x0a +#define IMAGE_REL_PPC_SECREL 0x0b +#define IMAGE_REL_PPC_SECTION 0x0c +#define IMAGE_REL_PPC_SECREL16 0x0f +#define IMAGE_REL_PPC_REFHI 0x10 +#define IMAGE_REL_PPC_REFLO 0x11 +#define IMAGE_REL_PPC_PAIR 0x12 +#define IMAGE_REL_PPC_SECRELLO 0x13 +#define IMAGE_REL_PPC_SECRELHI 0x14 +#define IMAGE_REL_PPC_GPREL 0x15 + +#define OUTPUT_COM 1 +#define OUTPUT_EXE 2 +#define OUTPUT_PE 3 + +#define WIN32_DEFAULT_BASE 0x00400000 +#define WIN32_DEFAULT_FILEALIGN 0x00000200 +#define WIN32_DEFAULT_OBJECTALIGN 0x00001000 +#define WIN32_DEFAULT_STACKSIZE 0x00100000 +#define WIN32_DEFAULT_STACKCOMMITSIZE 0x00001000 +#define WIN32_DEFAULT_HEAPSIZE 0x00100000 +#define WIN32_DEFAULT_HEAPCOMMITSIZE 0x00001000 +#define WIN32_DEFAULT_SUBSYS PE_SUBSYS_WINDOWS +#define WIN32_DEFAULT_SUBSYSMAJOR 4 +#define WIN32_DEFAULT_SUBSYSMINOR 0 +#define WIN32_DEFAULT_OSMAJOR 1 +#define WIN32_DEFAULT_OSMINOR 0 + +#define EXP_ORD 0x80 + +typedef char *PCHAR,**PPCHAR; +typedef unsigned char *PUCHAR; +typedef unsigned long UINT; + +extern UINT imageBase; +extern UINT fileAlign; +extern UINT objectAlign; +extern UINT stackSize; +extern UINT stackCommitSize; +extern UINT heapSize; +extern UINT heapCommitSize; + +template +int get32(T &vect, int offset) +{ + return vect[offset] | + (vect[offset+1] << 8) | + (vect[offset+2] << 16) | + (vect[offset+3] << 24); +} + +template +void put32(T &vect, int offset, int val) +{ + vect[offset] = val; + vect[offset+1] = val >> 8; + vect[offset+2] = val >> 16; + vect[offset+3] = val >> 24; +} + +template +int get16(T &vect, int offset) +{ + return vect[offset] | (vect[offset+1] << 8); +} + +template +void put16(T &vect, int offset, int val) +{ + vect[offset] = val; vect[offset+1] = val >> 8; +} + +template +void ClearNbit(T &mask,long i) +{ + mask[i/8]&=0xff-(1<<(i%8)); +} + +template +void SetNbit(T &mask,long i) +{ + mask[i/8]|=(1<<(i%8)); +} + +template +char GetNbit(T &mask,long i) +{ + return (mask[i/8]>>(i%8))&1; +} + +template +long GetIndex(T &buf,long *index) +{ + long i; + if(buf[*index]&0x80) + { + i=((buf[*index]&0x7f)*256)+buf[(*index)+1]; + (*index)+=2; + return i; + } + else + { + return buf[(*index)++]; + } +} + +static int roundup(int x, int align) +{ + x += align-1; + return x & ~(align-1); +} + +typedef struct __int_to_name { + int id; + const char *name; +} INT_TO_NAME, *PINT_TO_NAME; + +static const char *findName(const INT_TO_NAME *names, int id) +{ + for( int i = 0; names[i].name; i++ ) { + if(names[i].id == id) return names[i].name; + } + return ""; +} + +typedef struct __seg { +private: + UINT base; +public: + std::string name; + long classindex; + long overlayindex; + long orderindex; + UINT length; + UINT virtualSize; + UINT absframe; + UINT absofs; + UINT winFlags; + UINT fileBase; + unsigned short attr; + std::vector data; + std::vector datmask; + + __seg() { + classindex = overlayindex = orderindex = -1; + length = virtualSize = absframe = absofs = base = 0; + winFlags = WINF_READABLE | WINF_WRITEABLE | WINF_NEG_FLAGS; + attr = SEG_PRIVATE | SEG_PARA; + } + + UINT getbase() { return base; } + void setbase(UINT base) { + this->base = base; + } +} SEG, *PSEG, **PPSEG; + +typedef struct __datablock { + long count; + long blocks; + long dataofs; + std::vector data; + __datablock() { count = blocks = dataofs = 0; } +} DATABLOCK, *PDATABLOCK, **PPDATABLOCK; + +typedef struct __pubdef { + PSEG seg; + long grpnum; + long typenum; + UINT ofs; + UINT modnum; + std::string name; + std::string aliasName; + __pubdef() { + seg = 0; grpnum = typenum = ofs = modnum = 0; + } +} PUBLIC, *PPUBLIC,**PPPUBLIC; + +typedef struct __extdef { + std::string name; + long typenum; + PPUBLIC pubdef; + long impnum; + long flags; + UINT modnum; + __extdef(std::string name = "") : name(name), typenum(-1), pubdef(0), impnum(0), flags(EXT_NOMATCH), modnum(0) { } +} EXTREC, *PEXTREC,**PPEXTREC; + +typedef struct __imprec { + std::string int_name, mod_name, imp_name; + unsigned short ordinal; + char flags; + PSEG seg; + UINT abs, ofs; + __imprec() { + abs = ordinal = flags = 0; seg = 0; ofs = 0; + } +} IMPREC, *PIMPREC, **PPIMPREC; + +typedef struct __exprec { + std::string int_name, exp_name; + UINT ordinal; + char flags; + PPUBLIC pubdef; + UINT modnum; + __exprec() { + ordinal = flags = modnum = 0; + pubdef = 0; + } +} EXPREC, *PEXPREC, **PPEXPREC; + +typedef struct __comdef { + std::string name; + UINT length; + int isFar; + UINT modnum; + __comdef() { length = isFar = modnum; } +} COMREC, *PCOMREC, **PPCOMREC; + +typedef struct __elf32sym +{ + ULONG st_name; + ULONG st_value; + ULONG st_size; + UCHAR st_info; + UCHAR st_other; + USHORT st_shndx; +} ELF32SYM, *PELF32SYM; + +typedef struct __elf32rela +{ + ULONG r_offset; + ULONG r_info; + ULONG r_address; +} ELF32RELA, *PELF32RELA; + +typedef struct __elf32relx +{ + ULONG r_offset; + ULONG r_info; + ULONG r_address; + ULONG r_seg; /* Implied by section order */ +} ELF32RELX, *PELF32RELX; + +typedef struct __reloc { + UINT ofs; + segframe_t ftype; + segdisp_t ttype; + unsigned short rtype; + long target; + UINT disp; + UINT outputPos; + PSEG seg, targseg; + UINT frame; + ELF32RELX orig; + __reloc() { + frame = 0; seg = 0; targseg = 0; + ftype = REL_SEGFRAME; + ttype = REL_SEGDISP; + rtype = target = disp = outputPos = 0; + } +} RELOC, *PRELOC,**PPRELOC; + +typedef struct __grp { + std::string name; + long numsegs; + PSEG segindex[256]; + PSEG seg; + __grp() { numsegs = 0; seg = 0; memset(segindex, 0, sizeof(segindex)); } +} GRP, *PGRP, **PPGRP; + +typedef std::map > SORTLIST; +typedef struct __libfile { + std::string filename; + unsigned short blocksize; + unsigned short numdicpages; + UINT dicstart; + char flags; + char libtype; + int modsloaded; + std::vector modlist; + std::vector longnames; + SORTLIST symbols; +} LIBFILE, *PLIBFILE, **PPLIBFILE; + +typedef struct __libentry { + UINT libfile; + UINT modpage; +} LIBENTRY, *PLIBENTRY, **PPLIBENTRY; + +typedef struct __resource { + std::vector xtypename; + std::vector name; + std::vector data; + UINT length; + unsigned short typeid; + unsigned short id; + unsigned short languageid; +} RESOURCE, *PRESOURCE; + +typedef struct __coffsym { + std::string name; + UINT value; + short section; + unsigned short type; + unsigned char coff_class; + long extnum; + UINT numAuxRecs; + std::vector auxRecs; + int isComDat; + int originalSym; + PSEG segptr; + + __coffsym() { + value = numAuxRecs = extnum = isComDat = originalSym = 0; + section = 0; type = 0; + coff_class = 0; segptr = 0; + } +} COFFSYM, *PCOFFSYM; + +typedef struct __comdatrec +{ + UINT segnum; + UINT combineType; + UINT linkwith; +} COMDATREC, *PCOMDAT; + +#define EI_NIDENT 16 + +typedef struct __elf32hdr +{ + UCHAR e_ident[EI_NIDENT]; + USHORT e_type, e_machine; + ULONG e_version; + ULONG e_entry; + ULONG e_phoff; + ULONG e_shoff; + ULONG e_flags; + USHORT e_ehsize, e_phentsize; + USHORT e_phnum, e_shentsize; + USHORT e_shnum, e_shtrndx; +} ELF32HDR, *PELF32HDR; + +typedef struct __elf32shdr +{ + ULONG sh_name; + ULONG sh_type; + ULONG sh_flags; + ULONG sh_addr; + ULONG sh_offset; + ULONG sh_size; + ULONG sh_link; + ULONG sh_info; + ULONG sh_addralign; + ULONG sh_entsize; +} ELF32SHDR, *PELF32SHDR; + +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOOS 0xfe00 +#define ET_HIOS 0xfeff +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +/* #define EM_RESERVED 6 */ +#define EM_860 7 +#define EM_MIPS 8 +/* #define EM_RESERVED 9 */ +#define EM_MIPS_RS3_LE 10 +/* #define EM_RESERVED 11-14 */ +#define EM_PARISC 15 +/* #define EM_RESERVED 16 */ +#define EM_VPP500 17 +#define EM_SPARC32PLUS 18 +#define EM_960 19 +#define EM_PPC 20 +/* #define EM_RESERVED 21-35 */ +#define EM_V800 36 +#define EM_FR20 37 +#define EM_RH32 38 +#define EM_RCE 39 +#define EM_ARM 40 +#define EM_ALPHA 41 +#define EM_SH 42 +#define EM_SPARCV9 43 +#define EM_TRICORE 44 +#define EM_ARC 45 +#define EM_H8_300 46 +#define EM_H8_300H 47 +#define EM_H8S 48 +#define EM_H8_500 49 +#define EM_IA_64 50 +#define EM_MIPPS_X 51 +#define EM_COLDFIRE 52 +#define EM_68HC12 53 + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_UNKNOWN12 12 +#define SHT_UNKNOWN13 13 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +#define SHT_NUM 19 + +#define SHF_WRITE 1 +#define SHF_ALLOC 2 +#define SHF_EXECINSTR 4 + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOOS 10 +#define STB_HIOS 11 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +#define STT_FILE 4 +#define STT_COMMON 5 +#define SHN_COMMON 0xfff2 + +#define ELF32SYMSIZE 16 + +#define ELF32_ST_BIND(info) ((info) >> 4) +#define ELF32_ST_TYPE(info) ((info) & 0xf) +#define ELF32_ST_INFO(bind,type) (((bind)<<4) | ((type)&0xf)) + +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) +#define ELF32_R_INFO(sym, type) (((sym)<<8)+(unsigned char)(type)) + +#define T_NULL 0 +#define T_VOID 1 +#define T_CHAR 2 +#define T_SHORT 3 +#define T_INT 4 +#define T_LONG 5 +#define T_FLOAT 6 +#define T_DOUBLE 7 +#define T_STRUCT 8 +#define T_UNION 9 +#define T_ENUM 10 +#define T_MOE 11 +#define T_UCHAR 12 +#define T_USHORT 13 +#define T_UINT 14 +#define T_ULONG 15 +#define T_LNGDBL 16 +#define DT_NON 0 +#define DT_PTR 1 +#define DT_FCN 2 +#define DT_ARY 3 + +#define COFFTYPE(dt,t) (((dt)<<4)|t) + +int sortCompare(const void *x1,const void *x2); +void processArgs(int argc,char *argv[]); +void combine_groups(long i,long j); +void combine_common(long i,long j); +void combine_segments(PSEG i,PSEG j); +void combineBlocks(); +void OutputWin32file(const std::string &outname); +void OutputEXEfile(const std::string &outname); +void OutputCOMfile(const std::string &outname); +void GetFixupTarget(PRELOC r,PSEG *tseg,UINT *tofs,int isFlat); +void loadlibmod(UINT libnum,UINT modpage); +void loadlib(FILE *libfile,std::string libname); +void loadelf(FILE *libfile); +void loadCoffLib(FILE *libfile,std::string libname); +void loadcofflibmod(PLIBFILE p,FILE *libfile); +long loadmod(FILE *objfile); +void loadres(FILE *resfile); +void loadcoff(FILE *objfile); +void loadCoffImport(FILE *objfile); +void LoadFIXUP(PRELOC r,PUCHAR buf,long *p); +void RelocLIDATA(PDATABLOCK p,long *ofs,PRELOC r); +void EmitLiData(PDATABLOCK p,long segnum,long *ofs); +PDATABLOCK BuildLiData(long *bufofs); +void DestroyLIDATA(PDATABLOCK p); +void ReportError(long errnum); +int wstricmp(const char *s1,const char*s2); +int wstrlen(const char *s); +unsigned short wtoupper(unsigned short a); +int getBitCount(UINT a); +int _wstricmp(unsigned char *a, unsigned char *b); +int _wstrlen(unsigned char *a); +#define strdup _strdup + +extern char case_sensitive; +extern char padsegments; +extern char mapfile; +extern std::string mapname; +extern unsigned short maxalloc; +extern int output_type; +extern std::string outname; + +extern FILE *afile; +extern UINT filepos; +extern long reclength; +extern unsigned char rectype; +extern char li_le; +extern UINT prevofs; +extern long prevseg; +extern long gotstart; +extern RELOC startaddr; +extern unsigned char osMajor,osMinor; +extern unsigned char subsysMajor,subsysMinor; +extern unsigned int subSystem; + +extern long errcount; + +extern std::vector buf; +extern PDATABLOCK lidata; + +//extern std::vector namelist; +extern std::vector seglist; +extern std::vector outlist; +extern std::vector grplist; +extern SORTLIST publics; +extern std::vector externs; +extern std::vector comdefs; +extern std::vector relocs; +extern std::vector impdefs; +extern std::vector expdefs; +extern std::vector libfiles; +extern std::vector resource; +extern std::vector modname; +extern std::vector filename; +extern SORTLIST comdats; +extern UINT namemin, + pubmin, + segmin, + grpmin, + extmin, + commin, + fixmin, + impmin,impsreq, + expmin; + +extern int buildDll; +extern std::string stubName, entryPoint; +extern int cpuIdent; diff --git a/reactos/tools/ppc-build/alink/alink.mak b/reactos/tools/ppc-build/alink/alink.mak new file mode 100644 index 00000000000..929758cee6c --- /dev/null +++ b/reactos/tools/ppc-build/alink/alink.mak @@ -0,0 +1,11 @@ +CC = gcc -Zomf -c -s -O5 + +%.obj: %.c + $(CC) -o $@ $< + +all: blink.exe + +alink.obj coff.obj cofflib.obj combine.obj output.obj objload.obj util.obj: alink.h + +blink.exe: alink.obj coff.obj cofflib.obj combine.obj output.obj objload.obj util.obj + alink -subsys con @lib/def.rsp -o $@ $^ diff --git a/reactos/tools/ppc-build/alink/alink2.mak b/reactos/tools/ppc-build/alink/alink2.mak new file mode 100644 index 00000000000..ae6b8023bb9 --- /dev/null +++ b/reactos/tools/ppc-build/alink/alink2.mak @@ -0,0 +1,11 @@ +CC = cl /Zl /c /Ox + +%.obj: %.c + $(CC) /Fo$@ $< + +all: blink.exe + +alink.obj coff.obj cofflib.obj combine.obj output.obj objload.obj util.obj: alink.h + +blink.exe: alink.obj coff.obj cofflib.obj combine.obj output.obj objload.obj util.obj + alink -subsys con @lib/def.rsp -o $@ $^ diff --git a/reactos/tools/ppc-build/alink/coff.cpp b/reactos/tools/ppc-build/alink/coff.cpp new file mode 100644 index 00000000000..a2d5be19c76 --- /dev/null +++ b/reactos/tools/ppc-build/alink/coff.cpp @@ -0,0 +1,723 @@ +#include "alink.h" + +#define strupr(x) + +void loadcoff(FILE *objfile) +{ + unsigned char headbuf[20]; + unsigned char buf[100]; + PUCHAR bigbuf; + std::vector stringList; + UINT thiscpu; + UINT numSect; + UINT headerSize; + UINT symbolPtr; + UINT numSymbols; + UINT stringPtr; + UINT stringSize; + UINT stringOfs; + UINT i,j,k,l; + UINT fileStart; + UINT minseg; + UINT numrel; + UINT relofs; + UINT relshift; + UINT sectname; + long sectorder; + std::vector sym; + UINT combineType; + PPUBLIC pubdef; + PCOMDAT comdat; + PCHAR comdatsym; + std::vector nlist; + SORTLIST::iterator listnode; + + minseg=seglist.size(); + fileStart=ftell(objfile); + + if(fread(headbuf,1,20,objfile)!=20) + { + printf("Unable to read from file\n"); + exit(1); + } + thiscpu=headbuf[0]+256*headbuf[1]; + if(!thiscpu) + { + /* if we've got an import module, start at the beginning */ + fseek(objfile,fileStart,SEEK_SET); + /* and load it */ + loadCoffImport(objfile); + return; + } + + if(thiscpu==0x14c) + cpuIdent = PE_INTEL386; + if(thiscpu==0x1f0) + cpuIdent = PE_POWERPC; + + if(!cpuIdent) + { + printf("Unsupported CPU type for module (type %x)\n", thiscpu); + exit(1); + } + + numSect=get16(headbuf, PE_NUMOBJECTS-PE_MACHINEID); + symbolPtr=get32(headbuf, PE_SYMBOLPTR-PE_MACHINEID); + numSymbols=get32(headbuf, PE_NUMSYMBOLS-PE_MACHINEID); + + if(headbuf[PE_HDRSIZE-PE_MACHINEID]|headbuf[PE_HDRSIZE-PE_MACHINEID+1]) + { + printf("warning, optional header discarded\n"); + headerSize=headbuf[PE_HDRSIZE-PE_MACHINEID]+256*headbuf[PE_HDRSIZE-PE_MACHINEID+1]; + } + else + headerSize=0; + headerSize+=PE_BASE_HEADER_SIZE-PE_MACHINEID; + + stringPtr=symbolPtr+numSymbols*PE_SYMBOL_SIZE; + if(stringPtr) + { + fseek(objfile,fileStart+stringPtr,SEEK_SET); + if(fread(buf,1,4,objfile)!=4) + { + printf("Invalid COFF object file, unable to read string table size\n"); + exit(1); + } + stringSize=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24); + if(!stringSize) stringSize=4; + if(stringSize<4) + { + printf("Invalid COFF object file, bad string table size %i\n",stringSize); + exit(1); + } + stringPtr+=4; + stringSize-=4; + } + else + { + stringSize=0; + } + if(stringSize) + { + stringList.resize(stringSize); + if(fread(&stringList[0],1,stringSize,objfile)!=stringSize) + { + printf("Invalid COFF object file, unable to read string table\n"); + exit(1); + } + if(stringList[stringSize-1]) + { + printf("Invalid COFF object file, last string unterminated\n"); + exit(1); + } + } + else + { + stringList.resize(0); + } + + if(symbolPtr && numSymbols) + { + fseek(objfile,fileStart+symbolPtr,SEEK_SET); + sym.resize(numSymbols); + for(i=0;i=stringSize) + { + printf("Invalid COFF object file bad symbol location\n"); + exit(1); + } + sym[i].name=(char *)&stringList[0]+stringOfs; + } + if(!case_sensitive) + { + strupr(sym[i].name); + } + + sym[i].value=get32(buf, 8); + sym[i].section=get16(buf, 12); + sym[i].type=get16(buf, 14); + sym[i].coff_class=buf[16]; + sym[i].extnum=-1; + sym[i].numAuxRecs=buf[17]; + sym[i].isComDat=FALSE; + + switch(sym[i].coff_class) + { + case COFF_SYM_SECTION: { /* section symbol */ + if(sym[i].section<-1) + { + break; + } + /* section symbols declare an extern always, so can use in relocs */ + /* they may also include a PUBDEF */ + EXTREC ext; + ext.name=sym[i].name; + ext.pubdef=NULL; + ext.modnum=0; + ext.flags=EXT_NOMATCH; + sym[i].extnum=externs.size(); + externs.push_back(ext); + if(sym[i].section!=0) /* if the section is defined here, make public */ + { + pubdef=new PUBLIC(); + pubdef->grpnum=-1; + pubdef->typenum=0; + pubdef->modnum=0; + pubdef->aliasName=""; + pubdef->ofs=sym[i].value; + + if(sym[i].section==-1) + { + pubdef->seg=0; + } + else + { + pubdef->seg=seglist[minseg+sym[i].section-1]; + } + if((listnode=publics.find(sym[i].name)) != publics.end()) + { + for(j=0;jsecond.size();++j) + { + if(((PPUBLIC)listnode->second[j])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[j])->aliasName == "") + { + printf("Duplicate public symbol %s\n",sym[i].name.c_str()); + exit(1); + } + (*((PPUBLIC)listnode->second[j]))=(*pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator it = publics.find(sym[i].name); + if(it == publics.end()) { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(sym[i].name,vv)); + } else { + it->second.push_back((void *)pubdef); + } + } + } + } + case COFF_SYM_STATIC: /* allowed, but ignored for now as we only want to process if required */ + case COFF_SYM_LABEL: + case COFF_SYM_FILE: + case COFF_SYM_FUNCTION: + case COFF_SYM_EXTERNAL: + break; + default: + printf("unsupported symbol class %02X for symbol %s\n",sym[i].coff_class,sym[i].name.c_str()); + exit(1); + } + if(sym[i].numAuxRecs) + { + sym[i].auxRecs.resize(sym[i].numAuxRecs*PE_SYMBOL_SIZE); + } + else + { + sym[i].auxRecs.resize(0); + } + + /* read in the auxillary records for this symbol */ + for(j=0;j=stringSize) + { + printf("Invalid COFF object file\n"); + exit(1); + } + nlist.push_back((char *)&stringList[0]+sectname); + sectname=nlist.size()-1; + } + else + { + nlist.push_back((char *)buf); + sectname=nlist.size()-1; + } + size_t dollar = nlist[sectname].find('$'); + if(dollar != std::string::npos) + { + /* if we have a grouped segment, sort by original name */ + sectorder=sectname; + /* and get real name, without $ sort section */ + sectname=nlist.size(); + std::string no_dollar = nlist[sectname].substr(dollar); + nlist.push_back(no_dollar); + } + else + { + sectorder=-1; + } + + numrel=get16(buf, PE_OBJECT_NUMREL); + relofs=get32(buf, PE_OBJECT_RELPTR); + + PSEG seg = new SEG(); + seg->name=nlist[sectname]; + seg->orderindex=sectorder; + seg->classindex=-1; + seg->overlayindex=-1; + seg->length=get32(buf, PE_OBJECT_RAWSIZE); + + seg->attr=SEG_PUBLIC|SEG_USE32; + seg->winFlags=get32(buf, PE_OBJECT_FLAGS); + seg->setbase(get32(buf, PE_OBJECT_RAWPTR)); + + if(seg->winFlags & WINF_ALIGN_NOPAD) + { + seg->winFlags &= (0xffffffff-WINF_ALIGN); + seg->winFlags |= WINF_ALIGN_BYTE; + } + + switch(seg->winFlags & WINF_ALIGN) + { + case WINF_ALIGN_BYTE: + seg->attr |= SEG_BYTE; + break; + case WINF_ALIGN_WORD: + seg->attr |= SEG_WORD; + break; + case WINF_ALIGN_DWORD: + seg->attr |= SEG_DWORD; + break; + case WINF_ALIGN_8: + seg->attr |= SEG_8BYTE; + break; + case WINF_ALIGN_PARA: + seg->attr |= SEG_PARA; + break; + case WINF_ALIGN_32: + seg->attr |= SEG_32BYTE; + break; + case WINF_ALIGN_64: + seg->attr |= SEG_64BYTE; + break; + case 0: + seg->attr |= SEG_PARA; /* default */ + break; + default: + printf("Invalid COFF object file, bad section alignment %08X\n",seg->winFlags); + exit(1); + } + + /* invert all negative-logic flags */ + seg->winFlags ^= WINF_NEG_FLAGS; + /* remove .debug sections */ + if(nlist[sectname] == ".debug") + { + seg->winFlags |= WINF_REMOVE; + seg->length=0; + numrel=0; + } + + if(seg->winFlags & WINF_COMDAT) + { + printf("COMDAT section %s\n",nlist[sectname].c_str()); + comdat=new COMDATREC(); + combineType=0; + comdat->linkwith=0; + for(j=0;jlinkwith=sym[j].auxRecs[12]+(sym[j].auxRecs[13]<<8)+minseg-1; + printf("Combine type %i ",sym[j].auxRecs[14]); + printf("Link alongside section %i",comdat->linkwith); + + break; + } + } + if(j==numSymbols) + { + printf("Invalid COMDAT section\n"); + exit(1); + } + for(j++;jsegnum=seglist.size(); + comdat->combineType=combineType; + + printf("COMDATs not yet supported\n"); + exit(1); + + printf("Combine types for duplicate COMDAT symbol %s do not match\n",comdatsym); + exit(1); + } + + if(seg->length) + { + seg->data.resize(seg->length); + + seg->datmask.resize((seg->length+7)/8); + + if(seg->getbase()) + { + fseek(objfile,fileStart+seg->getbase(),SEEK_SET); + if(fread(&seg->data[0],1,seg->length,objfile) + !=seg->length) + { + printf("Invalid COFF object file\n"); + exit(1); + } + for(j=0;j<(seg->length+7)/8;j++) + seg->datmask[j]=0xff; + } + else + { + for(j=0;j<(seg->length+7)/8;j++) + seg->datmask[j]=0; + } + + } + else + { + seg->data.resize(0); + seg->datmask.resize(0); + } + + if(numrel) fseek(objfile,fileStart+relofs,SEEK_SET); + for(j=0;jofs=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24); + reloc->ofs-=relshift; + /* get segment */ + reloc->seg=seglist[i+minseg]; + reloc->disp=0; + /* get relocation target external index */ + reloc->target=get32(buf, 4); + if(reloc->target>=numSymbols) + { + printf("Invalid COFF object file, undefined symbol\n"); + exit(1); + } + k=reloc->target; + reloc->ttype=REL_EXTONLY; /* assume external reloc */ + if(sym[k].extnum<0) + { + switch(sym[k].coff_class) + { + case COFF_SYM_EXTERNAL: { + /* global symbols declare an extern when used in relocs */ + EXTREC ext; + ext.name=(char *)sym[k].name.c_str(); + ext.pubdef=NULL; + ext.modnum=0; + ext.flags=EXT_NOMATCH; + sym[k].extnum=externs.size(); + externs.push_back(ext); + /* they may also include a COMDEF or a PUBDEF */ + /* this is dealt with after all sections loaded, to cater for COMDAT symbols */ + } break; + case COFF_SYM_STATIC: /* static symbol */ + case COFF_SYM_LABEL: /* code label symbol */ + if(sym[k].section<-1) + { + printf("cannot relocate against a debug info symbol\n"); + exit(1); + break; + } + if(sym[k].section==0) + { + if(sym[k].value) + { + EXTREC ext; + ext.name=(char *)sym[k].name.c_str(); + ext.pubdef=NULL; + ext.modnum=modname.size()-1; + ext.flags=EXT_NOMATCH; + sym[k].extnum=externs.size(); + externs.push_back(ext); + + PCOMREC com = new COMREC(); + com->length=sym[k].value; + com->isFar=FALSE; + com->name=(char *)sym[k].name.c_str(); + com->modnum=modname.size()-1; + comdefs.push_back(com); + } + else + { + printf("Undefined symbol %s\n",sym[k].name.c_str()); + exit(1); + } + } + else + { + /* update relocation information to reflect symbol */ + reloc->ttype=REL_SEGDISP; + reloc->disp=sym[k].value; + if(sym[k].section==-1) + { + /* absolute symbols have section=-1 */ + reloc->target=-1; + } + else + { + /* else get real number of section */ + reloc->target=sym[k].section+minseg-1; + } + } + break; + default: + printf("undefined symbol class 0x%02X for symbol %s\n",sym[k].coff_class,sym[k].name.c_str()); + exit(1); + } + } + if(reloc->ttype==REL_EXTONLY) + { + /* set relocation target to external if sym is external */ + reloc->target=sym[k].extnum; + } + + /* frame is current segment (only relevant for non-FLAT output) */ + reloc->ftype=REL_SEGFRAME; + reloc->frame=i+minseg; + /* set relocation type */ + switch(get16(buf,8)) + { + case COFF_FIX_DIR32: + reloc->rtype=FIX_OFS32; + break; + + case COFF_FIX_RVA32: + reloc->rtype=FIX_RVA32; + break; +/* + case 0x0a: - + break; + case 0x0b: + break; +*/ + case COFF_FIX_REL32: + reloc->rtype=FIX_SELF_OFS32; + break; + default: + printf("unsupported COFF relocation type %04X\n",buf[8]+(buf[9]<<8)); + exit(1); + } + relocs.push_back(reloc); + } + + seglist.push_back(seg); + } + /* build PUBDEFs or COMDEFs for external symbols defined here that aren't COMDAT symbols. */ + for(i=0;ilength=sym[i].value; + com->isFar=FALSE; + com->name=sym[i].name; + com->modnum=0; + comdefs.push_back(com); + } + } + else + { + pubdef=new PUBLIC(); + pubdef->grpnum=-1; + pubdef->typenum=0; + pubdef->modnum=0; + pubdef->aliasName=""; + pubdef->ofs=sym[i].value; + + if(sym[i].section==-1) + { + pubdef->seg=0; + } + else + { + pubdef->seg=seglist[minseg+sym[i].section-1]; + } + if((listnode=publics.find(sym[i].name)) != publics.end()) + { + for(j=0;jsecond.size();++j) + { + if(((PPUBLIC)listnode->second[j])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[j])->aliasName == "") + { + printf("Duplicate public symbol %s\n",sym[i].name.c_str()); + exit(1); + } + (*((PPUBLIC)listnode->second[j]))=(*pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator it = publics.find(sym[i].name); + if( it == publics.end() ) { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(sym[i].name, vv)); + } else { + it->second.push_back((void *)pubdef); + } + } + } + } +} + +void loadCoffImport(FILE *objfile) +{ + UINT fileStart; + UINT thiscpu; + + fileStart=ftell(objfile); + + if(fread(&buf[0],1,20,objfile)!=20) + { + printf("Unable to read from file\n"); + exit(1); + } + + if(get32(buf,0) != 0xffff0000) + { + printf("Invalid Import entry\n"); + exit(1); + } + /* get CPU type */ + thiscpu=get16(buf,6); + printf("Import CPU=%04X\n",thiscpu); + + if(thiscpu!=0x14c && thiscpu!=0x1f0) + { + printf("Unsupported CPU type for module (type %x)\n", thiscpu); + exit(1); + } + +} diff --git a/reactos/tools/ppc-build/alink/cofflib.cpp b/reactos/tools/ppc-build/alink/cofflib.cpp new file mode 100644 index 00000000000..4f5b1757bb7 --- /dev/null +++ b/reactos/tools/ppc-build/alink/cofflib.cpp @@ -0,0 +1,310 @@ +#include "alink.h" + +#define strupr(x) + +void loadCoffLib(FILE *libfile,std::string libname) +{ + UINT i,j; + UINT numsyms; + UINT modpage; + UINT memberSize; + UINT startPoint; + PUCHAR endptr; + PLIBFILE p; + std::string name; + std::vector modbuf; + SORTLIST symlist; + int x; + + libfiles.push_back(LIBFILE()); + p=&libfiles[libfiles.size()-1]; + p->filename=libname; + startPoint=ftell(libfile); + + if(fread(&buf[0],1,8,libfile)!=8) + { + printf("Error reading from file\n"); + exit(1); + } + buf[8]=0; + /* complain if file header is wrong */ + if(strcmp((char *)&buf[0],"!\n")) + { + printf("Invalid library file format - bad file header\n"); + printf("\"%s\"\n",&buf[0]); + + exit(1); + } + /* read archive member header */ + if(fread(&buf[0],1,60,libfile)!=60) + { + printf("Error reading from file\n"); + exit(1); + } + if((buf[58]!=0x60) || (buf[59]!='\n')) + { + printf("Invalid library file format - bad member signature\n"); + exit(1); + } + buf[16]=0; + /* check name of first linker member */ + if(strcmp((char *)&buf[0],"/ ")) /* 15 spaces */ + { + printf("Invalid library file format - bad member name\n"); + exit(1); + } + buf[58]=0; + + /* strip trailing spaces from size */ + endptr=&buf[57]; + while((endptr>(&buf[48])) && isspace(*endptr)) + { + *endptr=0; + endptr--; + } + + /* get size */ + errno=0; + memberSize=strtoul((char *)&buf[48],(PPCHAR)&endptr,10); + if(errno || (*endptr)) + { + printf("Invalid library file format - bad member size\n"); + exit(1); + } + if((memberSize<4) && memberSize) + { + printf("Invalid library file format - bad member size\n"); + exit(1); + } + if(!memberSize) + { + numsyms=0; + } + else + { + if(fread(&buf[0],1,4,libfile)!=4) + { + printf("Error reading from file\n"); + exit(1); + } + numsyms=buf[3]+(buf[2]<<8)+(buf[1]<<16)+(buf[0]<<24); + } + printf("%u symbols\n",numsyms); + + if(numsyms) + { + if(fread(&modbuf[0],1,4*numsyms,libfile)!=4*numsyms) + { + printf("Error reading from file\n"); + exit(1); + } + } + + for(i=0;i vv; + vv.resize(modpage); + symlist.insert(std::make_pair(name, vv)); + } + + if(numsyms) + { + p->symbols=symlist; + } + + /* move to an even byte boundary in the file */ + if(ftell(libfile)&1) + { + fseek(libfile,1,SEEK_CUR); + } + + if(ftell(libfile)!=(startPoint+68+memberSize)) + { + printf("Invalid first linker member\n"); + printf("Pos=%08X, should be %08X\n",ftell(libfile),startPoint+68+memberSize); + + exit(1); + } + + printf("Loaded first linker member\n"); + + startPoint=ftell(libfile); + + /* read archive member header */ + if(fread(&buf[0],1,60,libfile)!=60) + { + printf("Error reading from file\n"); + exit(1); + } + if((buf[58]!=0x60) || (buf[59]!='\n')) + { + printf("Invalid library file format - bad member signature\n"); + exit(1); + } + buf[16]=0; + /* check name of second linker member */ + if(!strcmp((char *)&buf[0],"/ ")) /* 15 spaces */ + { + /* OK, so we've found it, now skip over */ + buf[58]=0; + + /* strip trailing spaces from size */ + endptr=&buf[57]; + while((endptr>(&buf[48])) && isspace(*endptr)) + { + *endptr=0; + endptr--; + } + + /* get size */ + errno=0; + memberSize=strtoul((char *)&buf[48],(PPCHAR)&endptr,10); + if(errno || (*endptr)) + { + printf("Invalid library file format - bad member size\n"); + exit(1); + } + if((memberSize<8) && memberSize) + { + printf("Invalid library file format - bad member size\n"); + exit(1); + } + + /* move over second linker member */ + fseek(libfile,startPoint+60+memberSize,SEEK_SET); + + /* move to an even byte boundary in the file */ + if(ftell(libfile)&1) + { + fseek(libfile,1,SEEK_CUR); + } + } + else + { + fseek(libfile,startPoint,SEEK_SET); + } + + + startPoint=ftell(libfile); + p->longnames.resize(0); + + /* read archive member header */ + if(fread(&buf[0],1,60,libfile)!=60) + { + printf("Error reading from file\n"); + exit(1); + } + if((buf[58]!=0x60) || (buf[59]!='\n')) + { + printf("Invalid library file format - bad 3rd member signature\n"); + exit(1); + } + buf[16]=0; + /* check name of long names linker member */ + if(!strcmp((char *)&buf[0],"// ")) /* 14 spaces */ + { + buf[58]=0; + + /* strip trailing spaces from size */ + endptr=&buf[57]; + while((endptr>(&buf[48])) && isspace(*endptr)) + { + *endptr=0; + endptr--; + } + + /* get size */ + errno=0; + memberSize=strtoul((char *)&buf[48],(PPCHAR)&endptr,10); + if(errno || (*endptr)) + { + printf("Invalid library file format - bad member size\n"); + exit(1); + } + if(memberSize) + { + p->longnames.resize(memberSize); + if(fread(&p->longnames[0],1,memberSize,libfile)!=memberSize) + { + printf("Error reading from file\n"); + exit(1); + } + } + } + else + { + /* if no long names member, move back to member header */ + fseek(libfile,startPoint,SEEK_SET); + } + + + p->modsloaded=0; + p->modlist.resize(numsyms); + p->libtype='C'; + p->blocksize=1; + p->flags=LIBF_CASESENSITIVE; +} + +void loadcofflibmod(PLIBFILE p,FILE *libfile) +{ + char *name; + UINT ofs; + + if(fread(&buf[0],1,60,libfile)!=60) + { + printf("Error reading from file\n"); + exit(1); + } + if((buf[58]!=0x60) || (buf[59]!='\n')) + { + printf("Invalid library member header\n"); + exit(1); + } + buf[16]=0; + if(buf[0]=='/') + { + ofs=15; + while(isspace(buf[ofs])) + { + buf[ofs]=0; + ofs--; + } + + ofs=strtoul((char *)&buf[1],&name,10); + if(!buf[1] || *name) + { + printf("Invalid string number \n"); + exit(1); + } + name=(char *)&p->longnames[0]+ofs; + } + else + { + name=(char *)&buf[0]; + } + + printf("Loading module %s\n",name); + loadcoff(libfile); +} diff --git a/reactos/tools/ppc-build/alink/combine.cpp b/reactos/tools/ppc-build/alink/combine.cpp new file mode 100755 index 00000000000..cd82543751b --- /dev/null +++ b/reactos/tools/ppc-build/alink/combine.cpp @@ -0,0 +1,519 @@ +#include "alink.h" + +void fixpubsegs(PSEG src,PSEG dest,UINT shift) +{ + UINT i,j; + PPUBLIC q; + SORTLIST::iterator it; + + for(it=publics.begin();it!=publics.end();++it) + { + for(j=0;jsecond.size();++it) + { + q=(PPUBLIC)it->second[j]; + if(q->seg==src) + { + q->seg=dest; + q->ofs+=shift; + } + } + } +} + +void fixpubgrps(int src,int dest) +{ + UINT i,j; + PPUBLIC q; + SORTLIST::iterator it; + + for(it=publics.begin();it!=publics.end();++it) + { + for(j=0;jsecond.size();++j) + { + q=(PPUBLIC)it->second[j]; + if(q->grpnum==src) + { + q->grpnum=dest; + } + } + } +} + +void combine_segments(PSEG destseg,PSEG srcseg) +{ + UINT k,n; + std::vector p,q; + long a1,a2; + + assert(destseg != srcseg); + + k=destseg->length; + switch(srcseg->attr&SEG_ALIGN) + { + case SEG_WORD: + a2=2; + k=(k+1)&0xfffffffe; + break; + case SEG_PARA: + a2=16; + k=(k+0xf)&0xfffffff0; + break; + case SEG_PAGE: + a2=0x100; + k=(k+0xff)&0xffffff00; + break; + case SEG_DWORD: + a2=4; + k=(k+3)&0xfffffffc; + break; + case SEG_MEMPAGE: + a2=0x1000; + k=(k+0xfff)&0xfffff000; + break; + case SEG_8BYTE: + a2=8; + k=(k+7)&0xfffffff8; + break; + case SEG_32BYTE: + a2=32; + k=(k+31)&0xffffffe0; + break; + case SEG_64BYTE: + a2=64; + k=(k+63)&0xffffffc0; + break; + default: + a2=1; + break; + } + switch(destseg->attr&SEG_ALIGN) + { + case SEG_WORD: + a1=2; + break; + case SEG_DWORD: + a1=4; + break; + case SEG_8BYTE: + a1=8; + break; + case SEG_PARA: + a1=16; + break; + case SEG_32BYTE: + a1=32; + break; + case SEG_64BYTE: + a1=64; + break; + case SEG_PAGE: + a1=0x100; + break; + case SEG_MEMPAGE: + a1=0x1000; + break; + default: + a1=1; + break; + } + + srcseg->setbase(k); + p.resize(k+srcseg->length); + q.resize((k+srcseg->length+7)/8); + for(k=0;klength;k++) + { + if(GetNbit(destseg->datmask,k)) + { + SetNbit(q,k); + p[k]=destseg->data[k]; + } + else + { + ClearNbit(q,k); + } + } + for(;kgetbase();k++) + { + ClearNbit(q,k); + } + for(;k<(srcseg->getbase()+srcseg->length);k++) + { + if(GetNbit(srcseg->datmask,k-srcseg->getbase())) + { + p[k]=srcseg->data[k-srcseg->getbase()]; + SetNbit(q,k); + } + else + { + ClearNbit(q,k); + } + } + destseg->length=k; + if(a2>a1) destseg->attr=srcseg->attr; + destseg->winFlags |= srcseg->winFlags; + destseg->data=p; + destseg->datmask=q; + + fixpubsegs(srcseg,destseg,srcseg->getbase()); + + for(k=0;kseg==srcseg) + { + relocs[k]->seg=destseg; + relocs[k]->ofs+=srcseg->getbase(); + } + if(relocs[k]->ttype==REL_SEGDISP) + { + if(relocs[k]->targseg==srcseg) + { + relocs[k]->targseg=destseg; + relocs[k]->disp=srcseg->getbase(); + } + } + else if(relocs[k]->ttype==REL_SEGONLY) + { + if(relocs[k]->targseg==srcseg) + { + relocs[k]->targseg=destseg; + relocs[k]->ttype=REL_SEGDISP; + relocs[k]->disp=srcseg->getbase(); + } + } + if((relocs[k]->ftype==REL_SEGFRAME) || + (relocs[k]->ftype==REL_LILEFRAME)) + { + if(relocs[k]->seg==srcseg) + { + relocs[k]->seg=destseg; + } + } + } + + if(gotstart) + { + if(startaddr.ttype==REL_SEGDISP) + { + if(startaddr.targseg==srcseg) + { + startaddr.targseg=destseg; + startaddr.disp+=srcseg->getbase(); + } + } + else if(startaddr.ttype==REL_SEGONLY) + { + if(startaddr.targseg==srcseg) + { + startaddr.targseg=destseg; + startaddr.disp=srcseg->getbase(); + startaddr.ttype=REL_SEGDISP; + } + } + if((startaddr.ftype==REL_SEGFRAME) || + (startaddr.ftype==REL_LILEFRAME)) + { + if(startaddr.seg==srcseg) + { + startaddr.seg=destseg; + } + } + } + + for(k=0;knumsegs;n++) + { + if(grplist[k]->segindex[n]==srcseg) + { + grplist[k]->segindex[n]=destseg; + } + } + } + } + + srcseg=0; +} + +void combine_common(long i,long j) +{ + UINT k,n; + std::vector p,q; + + if(seglist[j]->length>seglist[i]->length) + { + k=seglist[i]->length; + seglist[i]->length=seglist[j]->length; + seglist[j]->length=k; + p=seglist[i]->data; + q=seglist[i]->datmask; + seglist[i]->data=seglist[j]->data; + seglist[i]->datmask=seglist[j]->datmask; + } + else + { + p=seglist[j]->data; + q=seglist[j]->datmask; + } + for(k=0;klength;k++) + { + if(GetNbit(q,k)) + { + if(GetNbit(seglist[i]->datmask,k)) + { + if(seglist[i]->data[k]!=p[k]) + { + ReportError(ERR_OVERWRITE); + } + } + else + { + SetNbit(seglist[i]->datmask,k); + seglist[i]->data[k]=p[k]; + } + } + } + + fixpubsegs(seglist[j],seglist[i],0); + + for(k=0;kseg==seglist[j]) + { + relocs[k]->seg=seglist[i]; + } + if(relocs[k]->ttype==REL_SEGDISP) + { + if(relocs[k]->target==j) + { + relocs[k]->target=i; + } + } + else if(relocs[k]->ttype==REL_SEGONLY) + { + if(relocs[k]->target==j) + { + relocs[k]->target=i; + } + } + if((relocs[k]->ftype==REL_SEGFRAME) || + (relocs[k]->ftype==REL_LILEFRAME)) + { + if(relocs[k]->frame==j) + { + relocs[k]->frame=i; + } + } + } + + if(gotstart) + { + if(startaddr.ttype==REL_SEGDISP) + { + if(startaddr.target==j) + { + startaddr.target=i; + } + } + else if(startaddr.ttype==REL_SEGONLY) + { + if(startaddr.target==j) + { + startaddr.target=i; + } + } + if((startaddr.ftype==REL_SEGFRAME) || + (startaddr.ftype==REL_LILEFRAME)) + { + if(startaddr.frame==j) + { + startaddr.frame=i; + } + } + } + + for(k=0;knumsegs;n++) + { + if(grplist[k]->segindex[n]==seglist[j]) + { + grplist[k]->segindex[n]=seglist[i]; + } + } + } + } + + free(seglist[j]); + seglist[j]=0; +} + +void combine_groups(long i,long j) +{ + long n,m; + char match; + + for(n=0;nnumsegs;n++) + { + match=0; + for(m=0;mnumsegs;m++) + { + if(grplist[j]->segindex[n]==grplist[i]->segindex[m]) + { + match=1; + } + } + if(!match) + { + grplist[i]->numsegs++; + grplist[i]->segindex[grplist[i]->numsegs]=grplist[j]->segindex[n]; + } + } + free(grplist[j]); + grplist[j]=0; + + fixpubgrps(j,i); + + for(n=0;nftype==REL_GRPFRAME) + { + if(relocs[n]->frame==j) + { + relocs[n]->frame=i; + } + } + if((relocs[n]->ttype==REL_GRPONLY) || (relocs[n]->ttype==REL_GRPDISP)) + { + if(relocs[n]->target==j) + { + relocs[n]->target=i; + } + } + } + + if(gotstart) + { + if((startaddr.ttype==REL_GRPDISP) || (startaddr.ttype==REL_GRPONLY)) + { + if(startaddr.target==j) + { + startaddr.target=i; + } + } + if(startaddr.ftype==REL_GRPFRAME) + { + if(startaddr.frame==j) + { + startaddr.frame=i; + } + } + } +} + +void combineBlocks() +{ + long i,j,k; + std::string name; + long attr; + UINT count; + std::vector slist; + UINT curseg; + + for(i=0;iattr&SEG_ALIGN)!=SEG_ABS)) + { + if(seglist[i]->winFlags & WINF_COMDAT) continue; /* don't combine COMDAT segments */ + name=seglist[i]->name; + attr=seglist[i]->attr&(SEG_COMBINE|SEG_USE32); + + switch(attr&SEG_COMBINE) + { + case SEG_STACK: + for(j=i+1;jwinFlags & WINF_COMDAT) continue; + if((seglist[j]->attr&SEG_ALIGN)==SEG_ABS) continue; + if((seglist[j]->attr&SEG_COMBINE)!=SEG_STACK) continue; + combine_segments(seglist[i],seglist[j]); + } + break; + case SEG_PUBLIC: + case SEG_PUBLIC2: + case SEG_PUBLIC3: + slist.resize(1); + slist[0] = i; + /* get list of segments to combine */ + for(j=i+1,count=1;jwinFlags & WINF_COMDAT) continue; + if((seglist[j]->attr&SEG_ALIGN)==SEG_ABS) continue; + if(attr!=(seglist[j]->attr&(SEG_COMBINE|SEG_USE32))) continue; + if(name != seglist[j]->name) continue; + slist.push_back(j); + } + /* sort them by sortorder */ + for(j=0;jorderindex<0 || + seglist[slist[j]]->orderindex<0) continue; + + if(seglist[slist[j]]->name > + seglist[slist[k]]->name) { + int x = slist[k]; + slist[k] = slist[j]; + slist[j] = x; + } + } + } + /* then combine in that order */ + for(j=1;jattr&SEG_ALIGN)!=SEG_ABS)) && + ((seglist[i]->attr&(SEG_ALIGN|SEG_COMBINE|SEG_USE32))==(seglist[j]->attr&(SEG_ALIGN|SEG_COMBINE|SEG_USE32))) + && + (name == seglist[j]->name) + && !(seglist[j]->winFlags & WINF_COMDAT) + ) + { + combine_common(i,j); + } + } + break; + default: + break; + } + } + } + + for(i=0;iname == grplist[j]->name) + { + combine_groups(i,j); + } + } + } + } +} + + diff --git a/reactos/tools/ppc-build/alink/elf.cpp b/reactos/tools/ppc-build/alink/elf.cpp new file mode 100755 index 00000000000..cf50d2a14a6 --- /dev/null +++ b/reactos/tools/ppc-build/alink/elf.cpp @@ -0,0 +1,693 @@ +#include "alink.h" +#include + +#define strupr(x) + +unsigned short get16(unsigned char **src) +{ + unsigned short out = ((*src)[0] & 0xff) | (((*src)[1] & 0xff) << 8); + *src += 2; + return out; +} + +unsigned long get32(unsigned char **src) +{ + unsigned long out = + ((*src)[0] & 0xff) | + (((*src)[1] & 0xff) << 8) | + (((*src)[2] & 0xff) << 16) | + (((*src)[3] & 0xff) << 24); + *src += 4; + return out; +} + +int wantSeg(PSEG seg) +{ + return + !((seg->name.find(".debug") != std::string::npos) || + (seg->name.find(".rela") != std::string::npos) || + (seg->name.find("symtab") != std::string::npos) || + (seg->name.find("strtab") != std::string::npos)); +} + +int readElf32Hdr(FILE *objfile, PELF32HDR elf32hdr) +{ + unsigned char headbuf[52]; + PUCHAR hptr = headbuf; + + if(fread(headbuf,1,52,objfile)!=52) + { + return 0; + } + + memcpy(elf32hdr->e_ident, headbuf, EI_NIDENT); + hptr += EI_NIDENT; + elf32hdr->e_type = get16(&hptr); + elf32hdr->e_machine = get16(&hptr); + elf32hdr->e_version = get32(&hptr); + elf32hdr->e_entry = get32(&hptr); + elf32hdr->e_phoff = get32(&hptr); + elf32hdr->e_shoff = get32(&hptr); + elf32hdr->e_flags = get32(&hptr); + elf32hdr->e_ehsize = get16(&hptr); + elf32hdr->e_phentsize=get16(&hptr); + elf32hdr->e_phnum = get16(&hptr); + elf32hdr->e_shentsize=get16(&hptr); + elf32hdr->e_shnum = get16(&hptr); + elf32hdr->e_shtrndx = get16(&hptr); + + return 1; +} + +int readElf32SHdr(FILE *objfile, PELF32SHDR elf32shdr) +{ + unsigned char buf[40]; + PUCHAR bptr = buf; + + if(fread(buf,1,40,objfile)!=40) + { + return 0; + } + + elf32shdr->sh_name = get32(&bptr); + elf32shdr->sh_type = get32(&bptr); + elf32shdr->sh_flags = get32(&bptr); + elf32shdr->sh_addr = get32(&bptr); + elf32shdr->sh_offset = get32(&bptr); + elf32shdr->sh_size = get32(&bptr); + elf32shdr->sh_link = get32(&bptr); + elf32shdr->sh_info = get32(&bptr); + elf32shdr->sh_addralign =get32(&bptr); + elf32shdr->sh_entsize = get32(&bptr); + + return 1; +} + +int readElf32Sym(FILE *objfile, PELF32SYM elf32sym) +{ + unsigned char buf[16]; + unsigned char *bptr = buf; + + if(fread(buf,1,16,objfile)!=16) + { + return 0; + } + + elf32sym->st_name = get32(&bptr); + elf32sym->st_value = get32(&bptr); + elf32sym->st_size = get32(&bptr); + elf32sym->st_info = *bptr; bptr++; + elf32sym->st_other = *bptr; bptr++; + elf32sym->st_shndx = get16(&bptr); + + return 1; +} + +int readElf32Rel(FILE *objfile, PELF32RELX elf32rel) +{ + unsigned char buf[8]; + unsigned char *bptr = buf; + + if(fread(buf,1,8,objfile)!=8) + { + return 0; + } + + elf32rel->r_offset = get32(&bptr); + elf32rel->r_info = get32(&bptr); + elf32rel->r_address= 0; + + return 1; +} + +int readElf32Rela(FILE *objfile, PELF32RELX elf32rel) +{ + unsigned char buf[12]; + unsigned char *bptr = buf; + + if(fread(buf,1,12,objfile)!=12) + { + return 0; + } + + elf32rel->r_offset = get32(&bptr); + elf32rel->r_info = get32(&bptr); + elf32rel->r_address= get32(&bptr); + + return 1; +} + +void swapscn( PELF32SHDR seca, PELF32SHDR secb ) { + ELF32SHDR scn; + memcpy(&scn, seca, sizeof(scn)); + memcpy(seca, secb, sizeof(scn)); + memcpy(secb, &scn, sizeof(scn)); +} + +void loadelf(FILE *objfile) +{ + unsigned char buf[100]; + PUCHAR bigbuf; + std::vector stringList; + UINT thiscpu; + UINT symbolPtr = 0; + UINT numSymbols; + UINT stringPtr = 0; + UINT stringSize; + UINT stringOfs; + UINT curBase = 0; + UINT i,j,k,l; + UINT fileStart; + UINT relcount = 0; + UINT bss, bsscur = 0; + std::vector sym; + PPUBLIC pubdef; + PCOMDAT comdat; + PCHAR comdatsym; + SORTLIST::iterator listnode; + ELF32HDR elf32hdr; + std::vector elf32shdr; + int elf32sn = 0; + ELF32SYM elf32sym; + std::vector stringListOffsets; + int stringOffset = 0, secNum; + std::vector rel; + + fileStart=ftell(objfile); + + if(!readElf32Hdr(objfile, &elf32hdr)) + { + printf("Unable to read from file\n"); + exit(1); + } + + if( elf32hdr.e_machine == EM_386 ) + cpuIdent = PE_INTEL386; + else if( elf32hdr.e_machine == EM_PPC ) + cpuIdent = PE_POWERPC; + + if( !cpuIdent ) { + printf("Unsupported CPU type for module (type %x)\n", elf32hdr.e_machine); + exit(1); + } + + elf32shdr.resize((elf32hdr.e_shnum * 2) + 1); + memset(&elf32shdr[0], 0, (sizeof(elf32shdr[0]) * elf32hdr.e_shnum * 2) + 1); + stringListOffsets.resize(elf32hdr.e_shnum); + + /* Find a symbol section */ + for( i = 0; i < elf32hdr.e_shnum; i++ ) + { + int seekto = fileStart + elf32hdr.e_shoff + elf32hdr.e_shentsize * i; + if(fseek(objfile, seekto, 0)==-1) + { + printf("Short elf file (wanted to seek to %d)\n", seekto); + exit(1); + } + + if(!readElf32SHdr(objfile, &(elf32shdr[i]))) + { + printf("Could not read elf section header %d\n", i); + exit(1); + } + } + + /* Find string tables */ + for( i = 0; i < elf32hdr.e_shnum; i++ ) + { + if( elf32shdr[i].sh_type != SHT_STRTAB ) continue; + + stringPtr = elf32shdr[i].sh_offset; + stringSize = elf32shdr[i].sh_size + 1; + + if(fseek(objfile,fileStart+stringPtr,SEEK_SET)==-1) + { + printf("Short elf file, unable to seek to (%d)\n", stringPtr); + exit(1); + } + + if(stringSize) + { + stringList.resize(stringSize + stringOffset); + if(fread(&stringList[0]+stringOffset,1,stringSize - 1,objfile)!=stringSize - 1) + { + printf("Invalid elf object file, unable to read string table\n"); + exit(1); + } + stringList[stringSize-1] = 0; + + stringListOffsets[i] = stringOffset; + stringOffset += stringSize; + } + } + + /* Find segment order */ + for( i = 0; i < elf32hdr.e_shnum; i++ ) + { + const char *segname = (char *) + &stringList[0] + stringListOffsets[elf32hdr.e_shtrndx] + + elf32shdr[i].sh_name; + + if(elf32shdr[i].sh_type == SHT_REL || + elf32shdr[i].sh_type == SHT_RELA || + elf32shdr[i].sh_type == SHT_SYMTAB || + elf32shdr[i].sh_type == SHT_STRTAB) + continue; + + if(!strcmp(segname,".bss")) + { + bss = i; + bsscur = elf32shdr[i].sh_size; + } + } + + for( i = 0; i < elf32hdr.e_shnum; i++ ) + { + if(elf32shdr[i].sh_type == SHT_REL || + elf32shdr[i].sh_type == SHT_RELA || + elf32shdr[i].sh_type == SHT_SYMTAB || + elf32shdr[i].sh_type == SHT_STRTAB) + continue; + } + + memcpy(&elf32shdr[elf32hdr.e_shnum], &elf32shdr[0], sizeof(elf32shdr[0])); + + memcpy(&elf32shdr[0], &elf32shdr[elf32sn], sizeof(elf32shdr[0]) * elf32sn); + + elf32sn = elf32hdr.e_shnum; + + for( i = 0; i < elf32sn; i++ ) + { + if(stringPtr && !symbolPtr && elf32shdr[i].sh_type == SHT_SYMTAB) + { + int actualNum = 0; + + symbolPtr = elf32shdr[i].sh_offset; + numSymbols = elf32shdr[i].sh_size / ELF32SYMSIZE; + + if(fseek(objfile,fileStart+symbolPtr,SEEK_SET)==-1) + { + printf("Short elf file, unable to seek to (%d)\n", symbolPtr); + exit(1); + } + + sym.resize(numSymbols); + + for( j = 0; j < numSymbols; j++ ) + { + if(!readElf32Sym(objfile, &elf32sym)) + { + printf("Could not read elf symbol %d\n", i); + exit(1); + } + + sym[j].name = (char *) + (&stringList[stringListOffsets[elf32shdr[i].sh_link]] + + elf32sym.st_name); + +#if 0 + fprintf(stderr, + "S[%05x] value %08x size %08x info %08x " + "other %08x shndx %08x %s\n", + j, + elf32sym.st_value, elf32sym.st_size, elf32sym.st_info, + elf32sym.st_other, elf32sym.st_shndx, sym[j].name.c_str()); +#endif + + if(!case_sensitive) + { + strupr(sym[j].name); + } + + if(elf32sym.st_shndx == SHN_COMMON) + { + UINT thisbss = roundup(bsscur, elf32sym.st_value); + /* Round up bss objects */ + bsscur = thisbss + elf32sym.st_size; + sym[j].section = bss; + sym[j].value = thisbss; + sym[j].coff_class = COFF_SYM_EXTERNAL; + //fprintf( stderr, "BSS: @%08x(%04x) %s\n", sym[j].value, elf32sym.st_size, sym[j].name.c_str() ); + } + else + { + if(sym[j].name == entryPoint) + sym[j].coff_class = COFF_SYM_EXTERNAL; + else + sym[j].coff_class = COFF_SYM_STATIC; + sym[j].section = elf32sym.st_shndx; + sym[j].value = elf32sym.st_value; + } + + sym[j].extnum = -1; + sym[j].type = COFFTYPE(DT_FCN,T_NULL); + } + } + else if(elf32shdr[i].sh_type == SHT_REL || + elf32shdr[i].sh_type == SHT_RELA) + { + int rela = elf32shdr[i].sh_type == SHT_RELA; + int size = rela ? sizeof(ELF32RELA) : 8; + int oldrel = relcount; + + relcount+=elf32shdr[i].sh_size/size; + + rel.resize(relcount); + fseek(objfile,fileStart+elf32shdr[i].sh_offset,SEEK_SET); + + for( j = oldrel; j < relcount; j++ ) + { + if( rela ) + readElf32Rela(objfile, &rel[j]); + else + readElf32Rel(objfile, &rel[j]); + + rel[j].r_seg = elf32shdr[i].sh_info; + } + } + } + + for(i=0;iname= + (char *)&stringList[0] + stringListOffsets[elf32hdr.e_shtrndx] + + elf32shdr[i].sh_name; + seg->orderindex=0; + seg->classindex=-1; + seg->overlayindex=-1; + if(seg->name == ".bss") + { + seg->length = bsscur; + } + else + { + seg->length=elf32shdr[i].sh_size; + } + + seg->attr=SEG_PUBLIC|SEG_USE32|SEG_DWORD; + seg->winFlags=WINF_ALIGN_DWORD | WINF_READABLE; + seg->fileBase = elf32shdr[i].sh_offset; + seg->setbase(curBase); + if( wantSeg(seg) ) { + curBase += roundup(curBase + seg->length, objectAlign); + } else { + seg->winFlags |= WINF_REMOVE; + } + + if( elf32shdr[i].sh_flags & SHF_WRITE ) + seg->winFlags |= WINF_WRITEABLE; + + if( elf32shdr[i].sh_flags == 0 ) + seg->winFlags |= WINF_COMMENT; + + switch( elf32shdr[i].sh_type ) + { + case SHT_PROGBITS: + if( elf32shdr[i].sh_flags & SHF_EXECINSTR ) + seg->winFlags |= WINF_CODE | WINF_EXECUTE; + else + seg->winFlags |= WINF_INITDATA; + break; + + case SHT_NOBITS: + if( elf32shdr[i].sh_flags & SHF_WRITE ) + seg->winFlags |= WINF_UNINITDATA; + break; + + default: + break; + } + + if(seg->winFlags & WINF_ALIGN_NOPAD) + { + seg->winFlags &= ~WINF_ALIGN; + seg->winFlags |= WINF_ALIGN_BYTE; + } + + /* invert all negative-logic flags */ + seg->winFlags ^= WINF_NEG_FLAGS; + seg->datmask.resize(roundup(seg->length,8)/8); + seg->data.resize(roundup(seg->length,8)); + if(seg->name == ".bss") + { + memset(&seg->datmask[0], 0, seg->datmask.size()); + memset(&seg->data[0], 0, seg->data.size()); + } + else + { + memset(&seg->datmask[0], 0xff, seg->datmask.size()); + fseek(objfile, seg->fileBase, 0); + fread(&seg->data[0], 1, seg->length, objfile); + } + seglist.push_back(seg); + } + + for( i = 0; i < numSymbols; i++ ) { + sym[i].segptr = seglist[sym[i].section]; + + switch(sym[i].coff_class) + { + case COFF_SYM_SECTION: { /* section symbol */ + /* section symbols declare an extern always, so can use in relocs */ + /* they may also include a PUBDEF */ + EXTREC ext; + ext.name=(char *)sym[i].name.c_str(); + ext.pubdef=NULL; + ext.modnum=0; + ext.flags=EXT_NOMATCH; + sym[i].extnum=externs.size(); + externs.push_back(ext); + if(sym[i].section) /* if the section is defined here, make public */ + { + pubdef=new PUBLIC(); + pubdef->grpnum=-1; + pubdef->typenum=0; + pubdef->modnum=0; + pubdef->aliasName=""; + pubdef->name = sym[i].name; + pubdef->ofs=sym[i].value; + //fprintf(stderr, "sym[%05d] public %s\n", i, sym[i].name.c_str()); + + if(sym[i].section==-1) + { + pubdef->seg=NULL; + } + else + { + pubdef->seg=seglist[sym[i].section]; + } + if((listnode=publics.find(sym[i].name)) != publics.end()) + { + for(j=0;jsecond.size();++j) + { + if(((PPUBLIC)listnode->second[j])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[j])->aliasName=="") + { + printf("Duplicate public symbol %s\n",sym[i].name.c_str()); + exit(1); + } + (*((PPUBLIC)listnode->second[j]))=(*pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator it = publics.find(sym[i].name); + if( it == publics.end() ) { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(sym[i].name, vv)); + } else { + it->second.push_back((void *)pubdef); + } + } + } + } break; + + case COFF_SYM_EXTERNAL: + case COFF_SYM_STATIC: /* allowed, but ignored for now as we only want to process if required */ + case COFF_SYM_LABEL: + case COFF_SYM_FILE: + case COFF_SYM_FUNCTION: + break; + + default: + printf("unsupported symbol class %02X for symbol %s\n",sym[i].coff_class,sym[i].name.c_str()); + exit(1); + } + } + + for(i=0;iwinFlags & WINF_REMOVE) ) continue; + + PRELOC reloc = new RELOC(); + /* get address to relocate */ + reloc->ofs=rel[j].r_offset; + reloc->orig = rel[j]; + reloc->ftype = REL_SEGFRAME; + + /* get segment */ + reloc->seg = seglist[rel[j].r_seg]; + + if( cpuIdent == PE_INTEL386 ) + reloc->disp=4; + else + reloc->disp=rel[j].r_address; + + /* get relocation target external index */ + reloc->target=rel[j].r_info >> 8; + + if(reloc->target>=numSymbols) + { + printf("Invalid ELF object file, undefined symbol\n"); + exit(1); + } + k=reloc->target; + reloc->ttype=REL_EXTDISP; /* assume external reloc */ + + if(sym[k].extnum<0) + { + switch(sym[k].coff_class) + { + case COFF_SYM_EXTERNAL: { + /* global symbols declare an extern when used in relocs */ + EXTREC ext; + ext.name=sym[k].name; + ext.pubdef=NULL; + ext.modnum=0; + ext.flags=EXT_NOMATCH; + sym[k].extnum=externs.size(); + externs.push_back(ext); + /* they may also include a COMDEF or a PUBDEF */ + /* this is dealt with after all sections loaded, to cater + for COMDAT symbols */ + } break; + case COFF_SYM_STATIC: /* static symbol */ + case COFF_SYM_LABEL: /* code label symbol */ + /* update relocation information to reflect symbol */ + reloc->ttype=REL_SEGDISP; + reloc->disp=rel[j].r_address + sym[k].value; + reloc->targseg = seglist[sym[k].section]; + break; + default: + printf("undefined symbol class 0x%02X for symbol %s\n",sym[k].coff_class,sym[k].name.c_str()); + exit(1); + } + } + if(reloc->ttype==REL_EXTONLY || + reloc->ttype==REL_EXTDISP) + { + /* set relocation target to external if sym is external */ + reloc->target=sym[k].extnum; + } + + /* set relocation type */ + switch (rel[j].r_info & 0xff) + { + case R_PPC_ADDR32: + reloc->rtype = FIX_ADDR32; + break; + + case R_PPC_UADDR32: + reloc->rtype = FIX_RVA32; + break; + + case R_PPC_REL32: + reloc->rtype = FIX_REL32; + break; + + case R_PPC_ADDR24: + reloc->rtype = FIX_PPC_ADDR24; + break; + + case R_PPC_REL24: + reloc->rtype = FIX_PPC_REL24; + break; + + case R_PPC_ADDR16_LO: + reloc->rtype = FIX_PPC_RVA16LO; + break; + + case R_PPC_ADDR16_HA: + reloc->rtype = FIX_PPC_RVA16HA; + break; + + default: + printf("unsupported ELF relocation type %04X\n",rel[j].r_info & 0xff); + exit(1); + } + + relocs.push_back(reloc); + } + } + /* build PUBDEFs or COMDEFs for external symbols defined here that aren't COMDAT symbols. */ + for(i=0;igrpnum=-1; + pubdef->typenum=0; + pubdef->modnum=0; + pubdef->name = sym[i].name; + pubdef->aliasName=""; + pubdef->ofs=sym[i].value; + + if(sym[i].section==-1) + { + pubdef->seg=0; + } + else + { + pubdef->seg=seglist[sym[i].section]; + } + if((listnode=publics.find(sym[i].name)) != publics.end()) + { + for(j=0;jsecond.size();++j) + { + if(((PPUBLIC)listnode->second[j])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[j])->aliasName=="") + { + printf("Duplicate public symbol %s\n",sym[i].name.c_str()); + exit(1); + } + (*((PPUBLIC)listnode->second[j]))=(*pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator it = publics.find(sym[i].name); + if( it == publics.end() ) { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(sym[i].name,vv)); + } else { + it->second.push_back((void *)pubdef); + } + } + } + + for(i = 0; i < seglist.size(); i++) { + if(seglist[i]->winFlags & WINF_REMOVE) { + seglist.erase(seglist.begin()+i); + i--; + } + } +} diff --git a/reactos/tools/ppc-build/alink/license-note.txt b/reactos/tools/ppc-build/alink/license-note.txt new file mode 100644 index 00000000000..2bd342e7110 --- /dev/null +++ b/reactos/tools/ppc-build/alink/license-note.txt @@ -0,0 +1,8 @@ +I received permission from Anthony Williams to use alink as the basis for +the elf to coff conversion stage in reactos-powerpc. Thanks to Anthony +for writing alink in a way that made it possible to produce binaries for +reactos-powerpc, and for giving me permission to modify it despite the +license. + +This version of alink has been modified heavily, mostly for the benefit +of producing pe-coff powerpc executables. \ No newline at end of file diff --git a/reactos/tools/ppc-build/alink/objload.cpp b/reactos/tools/ppc-build/alink/objload.cpp new file mode 100644 index 00000000000..cc0cade733b --- /dev/null +++ b/reactos/tools/ppc-build/alink/objload.cpp @@ -0,0 +1,1441 @@ +#include "alink.h" + +#define strupr(x) + +char t_thred[4]; +char f_thred[4]; +int t_thredindex[4]; +int f_thredindex[4]; + +void DestroyLIDATA(PDATABLOCK p) +{ + long i; + if(p->blocks) + { + for(i=0;iblocks;i++) + { + DestroyLIDATA(((PPDATABLOCK)(&p->data[0]))[i]); + } + } + delete p; +} + +PDATABLOCK BuildLiData(long *bufofs) +{ + PDATABLOCK p; + long i,j; + + p=new DATABLOCK(); + i=*bufofs; + p->dataofs=i-lidata->dataofs; + p->count=buf[i]+256*buf[i+1]; + i+=2; + if(rectype==LIDATA32) + { + p->count+=(buf[i]+256*buf[i+1])<<16; + i+=2; + } + p->blocks=buf[i]+256*buf[i+1]; + i+=2; + if(p->blocks) + { + p->data.resize(p->blocks*sizeof(PDATABLOCK)); + for(j=0;jblocks;j++) + { + ((PPDATABLOCK)&p->data[0])[j]=BuildLiData(&i); + } + } + else + { + p->data.resize(buf[i]+1); + p->data[0]=buf[i]; + i++; + for(j=0;jdata[0];j++,i++) + { + p->data[j+1]=buf[i]; + } + } + *bufofs=i; + return p; +} + +void EmitLiData(PDATABLOCK p,long segnum,long *ofs) +{ + long i,j; + + for(i=0;icount;i++) + { + if(p->blocks) + { + for(j=0;jblocks;j++) + { + EmitLiData(((PPDATABLOCK)&p->data[0])[j],segnum,ofs); + } + } + else + { + for(j=0;jdata[0];j++,(*ofs)++) + { + if((*ofs)>=seglist[segnum]->length) + { + ReportError(ERR_INV_DATA); + } + if(GetNbit(seglist[segnum]->datmask,*ofs)) + { + if(seglist[segnum]->data[*ofs]!=p->data[j+1]) + { + ReportError(ERR_OVERWRITE); + } + } + seglist[segnum]->data[*ofs]=p->data[j+1]; + SetNbit(seglist[segnum]->datmask,*ofs); + } + } + } +} + +void RelocLIDATA(PDATABLOCK p,long *ofs,PRELOC r) +{ + long i,j; + + for(i=0;icount;i++) + { + if(p->blocks) + { + for(j=0;jblocks;j++) + { + RelocLIDATA(((PPDATABLOCK)&p->data[0])[j],ofs,r); + } + } + else + { + j=r->ofs-p->dataofs; + if(j>=0) + { + if((j<5) || ((li_le==PREV_LI32) && (j<7))) + { + ReportError(ERR_BAD_FIXUP); + } + PRELOC rel = new RELOC(*r); + rel->ofs = *ofs + j; + relocs.push_back(rel); + *ofs+=p->data[0]; + } + } + } +} + +segframe_t intToFrame(int f) +{ + return (segframe_t)f; +} + +segdisp_t intToDisp(int d) +{ + return (segdisp_t)(d + 0x80); +} + +void LoadFIXUP(PRELOC r,PUCHAR buf,long *p) +{ + long j; + int thrednum; + + j=*p; + + // arty -- come back to this + r->ftype=intToFrame(buf[j]>>4); + r->ttype=intToDisp(buf[j]&0xf); + r->disp=0; + j++; + if(r->ftype&FIX_THRED) + { + thrednum=r->ftype&THRED_MASK; + if(thrednum>3) + { + ReportError(ERR_BAD_FIXUP); + } + r->ftype=intToFrame((f_thred[thrednum]>>2)&7); + switch(r->ftype) + { + case REL_SEGFRAME: + case REL_GRPFRAME: + case REL_EXTFRAME: + r->frame=f_thredindex[thrednum]; + if(!r->frame) + { + ReportError(ERR_BAD_FIXUP); + } + break; + case REL_LILEFRAME: + case REL_TARGETFRAME: + break; + default: + ReportError(ERR_BAD_FIXUP); + } + switch(r->ftype) + { + case REL_SEGFRAME: + r->frame+=segmin-1; + break; + case REL_GRPFRAME: + r->frame+=grpmin-1; + break; + case REL_EXTFRAME: + r->frame+=extmin-1; + break; + case REL_LILEFRAME: + r->frame=prevseg; + break; + default: + break; + } + } + else + { + switch(r->ftype) + { + case REL_SEGFRAME: + case REL_GRPFRAME: + case REL_EXTFRAME: + r->frame=GetIndex(buf,&j); + if(!r->frame) + { + ReportError(ERR_BAD_FIXUP); + } + break; + case REL_LILEFRAME: + case REL_TARGETFRAME: + break; + default: + ReportError(ERR_BAD_FIXUP); + } + switch(r->ftype) + { + case REL_SEGFRAME: + r->frame+=segmin-1; + break; + case REL_GRPFRAME: + r->frame+=grpmin-1; + break; + case REL_EXTFRAME: + r->frame+=extmin-1; + break; + case REL_LILEFRAME: + r->frame=prevseg; + break; + default: + break; + } + } + if(r->ttype&FIX_THRED) + { + thrednum=r->ttype&3; + if((r->ttype&4)==0) /* P bit not set? */ + { + r->ttype=intToDisp((t_thred[thrednum]>>2)&3); /* DISP present */ + } + else + { + r->ttype=intToDisp(((t_thred[thrednum]>>2)&3) | 4); /* no disp */ + } + r->target=t_thredindex[thrednum]; + switch(r->ttype) + { + case REL_SEGDISP: + case REL_GRPDISP: + case REL_EXTDISP: + case REL_SEGONLY: + case REL_GRPONLY: + case REL_EXTONLY: + if(!r->target) + { + ReportError(ERR_BAD_FIXUP); + } + break; + case REL_EXPFRAME: + break; + default: + ReportError(ERR_BAD_FIXUP); + } + switch(r->ttype) + { + case REL_SEGDISP: + r->target+=segmin-1; + break; + case REL_GRPDISP: + r->target+=grpmin-1; + break; + case REL_EXTDISP: + r->target+=extmin-1; + break; + case REL_EXPFRAME: + break; + case REL_SEGONLY: + r->target+=segmin-1; + break; + case REL_GRPONLY: + r->target+=grpmin-1; + break; + case REL_EXTONLY: + r->target+=extmin-1; + break; + } + } + else + { + r->target=GetIndex(buf,&j); + switch(r->ttype) + { + case REL_SEGDISP: + case REL_GRPDISP: + case REL_EXTDISP: + case REL_SEGONLY: + case REL_GRPONLY: + case REL_EXTONLY: + if(!r->target) + { + ReportError(ERR_BAD_FIXUP); + } + break; + case REL_EXPFRAME: + break; + default: + ReportError(ERR_BAD_FIXUP); + } + switch(r->ttype) + { + case REL_SEGDISP: + r->target+=segmin-1; + break; + case REL_GRPDISP: + r->target+=grpmin-1; + break; + case REL_EXTDISP: + r->target+=extmin-1; + break; + case REL_EXPFRAME: + break; + case REL_SEGONLY: + r->target+=segmin-1; + break; + case REL_GRPONLY: + r->target+=grpmin-1; + break; + case REL_EXTONLY: + r->target+=extmin-1; + break; + } + } + switch(r->ttype) + { + case REL_SEGDISP: + case REL_GRPDISP: + case REL_EXTDISP: + case REL_EXPFRAME: + r->disp=get16(buf,j); + j+=2; + if(rectype==FIXUPP32) + { + r->disp+=get16(buf,j)<<16; + j+=2; + } + break; + default: + break; + } + if((r->ftype==REL_TARGETFRAME)&&((r->ttype&FIX_THRED)==0)) + { + switch(r->ttype) + { + case REL_SEGDISP: + r->ftype = REL_SEGFRAME; + break; + case REL_GRPDISP: + r->ftype = REL_GRPFRAME; + break; + case REL_EXTDISP: + r->ftype = REL_EXTFRAME; + break; + case REL_EXPFRAME: + r->ftype = REL_EXPFFRAME; + break; + case REL_SEGONLY: + r->ftype = REL_SEGFRAME; + break; + case REL_GRPONLY: + r->ftype = REL_GRPFRAME; + break; + case REL_EXTONLY: + r->ftype = REL_EXTFRAME; + break; + } + r->frame=r->target; + } + + *p=j; +} + +long loadmod(FILE *objfile) +{ + long modpos; + long done; + long i,j,k; + long segnum,grpnum; + PRELOC r; + PPUBLIC pubdef; + std::string name,aliasName; + SORTLIST::iterator listnode; + std::vector nlist; + + modpos=0; + done=0; + li_le=0; + lidata=0; + + while(!done) + { + if(fread(&buf[0],1,3,objfile)!=3) + { + ReportError(ERR_NO_MODEND); + } + rectype=buf[0]; + reclength=buf[1]+256*buf[2]; + if(fread(&buf[0],1,reclength,afile)!=reclength) + { + ReportError(ERR_NO_RECDATA); + } + reclength--; /* remove checksum */ + if((!modpos)&&(rectype!=THEADR)&&(rectype!=LHEADR)) + { + ReportError(ERR_NO_HEADER); + } + switch(rectype) + { + case THEADR: + case LHEADR: + if(modpos) + { + ReportError(ERR_EXTRA_HEADER); + } + modname.push_back(std::string((char *)&buf[1],buf[0])); + strupr(modname[nummods]); + /* printf("Loading module %s\n",modname[nummods]);*/ + if((buf[0]+1)!=reclength) + { + ReportError(ERR_EXTRA_DATA); + } + segmin=seglist.size(); + extmin=externs.size(); + fixmin=relocs.size(); + grpmin=grplist.size(); + impmin=impdefs.size(); + expmin=expdefs.size(); + commin=comdefs.size(); + break; + case COMENT: + li_le=0; + if(lidata) + { + DestroyLIDATA(lidata); + lidata=0; + } + if(reclength>=2) + { + switch(buf[1]) + { + case COMENT_LIB_SPEC: + case COMENT_DEFLIB: { + std::string newfilename((char *)&buf[2],reclength-2); + if(newfilename.find('.') == std::string::npos) + newfilename += ".lib"; + filename.push_back(newfilename); + } break; + case COMENT_OMFEXT: + if(reclength<4) + { + ReportError(ERR_INVALID_COMENT); + } + switch(buf[2]) + { + case EXT_IMPDEF: { + j=4; + if(reclength<(j+4)) + { + ReportError(ERR_INVALID_COMENT); + } + IMPREC imp; + imp.flags=buf[3]; + imp.int_name=std::string((char *)&buf[j+1]); + if(!case_sensitive) + { + strupr(impdefs[impdefs.size()].int_name); + } + j += buf.size() + 1; + imp.mod_name=std::string((char *)&buf[j+1]); + j += buf.size() + 1; + if(!case_sensitive) + { + strupr(impdefs[impdefs.size()].mod_name); + } + if(imp.flags) + { + imp.ordinal=buf[j]+256*buf[j+1]; + j+=2; + } + else + { + if(buf[j]) + { + imp.imp_name=std::string((char *)&buf[j]); + j += imp.imp_name.size() + 1; + } + else + { + imp.imp_name=imp.int_name; + } + } + impdefs.push_back(imp); + } break; + case EXT_EXPDEF: { + EXPREC exp; + j=4; + exp.flags=buf[3]; + exp.pubdef=NULL; + exp.exp_name = std::string((char *)&buf[j]+1,buf[j]); + j+=buf[j]+1; + if(buf[j]) + { + exp.int_name=std::string((char *)buf[j]+1,buf[j]); + if(!case_sensitive) + { + strupr(exp.int_name); + } + } + else + { + exp.int_name=exp.exp_name; + } + j+=buf[j]+1; + if(exp.flags&EXP_ORD) + { + exp.ordinal=buf[j]+256*buf[j+1]; + } + else + { + exp.ordinal=0; + } + expdefs.push_back(exp); + } break; + default: + ReportError(ERR_INVALID_COMENT); + } + break; + case COMENT_DOSSEG: + break; + case COMENT_TRANSLATOR: + case COMENT_INTEL_COPYRIGHT: + case COMENT_MSDOS_VER: + case COMENT_MEMMODEL: + case COMENT_NEWOMF: + case COMENT_LINKPASS: + case COMENT_LIBMOD: + case COMENT_EXESTR: + case COMENT_INCERR: + case COMENT_NOPAD: + case COMENT_WKEXT: + case COMENT_LZEXT: + case COMENT_PHARLAP: + case COMENT_IBM386: + case COMENT_RECORDER: + case COMENT_COMMENT: + case COMENT_COMPILER: + case COMENT_DATE: + case COMENT_TIME: + case COMENT_USER: + case COMENT_DEPFILE: + case COMENT_COMMANDLINE: + case COMENT_PUBTYPE: + case COMENT_COMPARAM: + case COMENT_TYPDEF: + case COMENT_STRUCTMEM: + case COMENT_OPENSCOPE: + case COMENT_LOCAL: + case COMENT_ENDSCOPE: + case COMENT_SOURCEFILE: + break; + default: + printf("COMENT Record (unknown type %02X)\n",buf[1]); + break; + } + } + break; + case LLNAMES: + case LNAMES: + j=0; + while(jattr=buf[0]; + j=1; + if((seg->attr & SEG_ALIGN)==SEG_ABS) + { + seg->absframe=get16(buf,j); + seg->absofs=buf[j+2]; + j+=3; + } + seg->length=buf[j]+256*buf[j+1]; + j+=2; + if(rectype==SEGDEF32) + { + seg->length+=get16(buf,j)<<16; + j+=2; + } + if(seg->attr&SEG_BIG) + { + if(rectype==SEGDEF) + { + seg->length+=65536; + } + else + { + if((seg->attr&SEG_ALIGN)!=SEG_ABS) + { + ReportError(ERR_SEG_TOO_LARGE); + } + } + } + seg->name=nlist[GetIndex(buf,&j)-1]; + seg->classindex=GetIndex(buf,&j)-1; + seg->overlayindex=GetIndex(buf,&j)-1; + seg->orderindex=-1; + if((seg->attr&SEG_ALIGN)!=SEG_ABS) + { + seg->data.resize(seg->length); + seg->datmask.resize((seg->length+7)/8); + for(i=0;i<(seg->length+7)/8;i++) + { + seg->datmask[i]=0; + } + } + else + { + seg->data.resize(0); + seg->datmask.resize(0); + seg->attr&=(0xffff-SEG_COMBINE); + seg->attr|=SEG_PRIVATE; + } + switch(seg->attr&SEG_COMBINE) + { + case SEG_PRIVATE: + case SEG_PUBLIC: + case SEG_PUBLIC2: + case SEG_COMMON: + case SEG_PUBLIC3: + break; + case SEG_STACK: + /* stack segs are always byte aligned */ + seg->attr&=(0xffff-SEG_ALIGN); + seg->attr|=SEG_BYTE; + break; + default: + ReportError(ERR_BAD_SEGDEF); + break; + } + if((seg->attr&SEG_ALIGN)==SEG_BADALIGN) + { + ReportError(ERR_BAD_SEGDEF); + } + if((seg->classindex>=0) && + (nlist[seg->classindex] == "CODE" || + nlist[seg->classindex] == "TEXT")) + { + /* code segment */ + seg->winFlags=WINF_CODE | WINF_INITDATA | WINF_EXECUTE | WINF_READABLE | WINF_NEG_FLAGS; + } + else /* data segment */ + seg->winFlags=WINF_INITDATA | WINF_READABLE | WINF_WRITEABLE | WINF_NEG_FLAGS; + + if(seg->name == "$$SYMBOLS" || + seg->name == "$$TYPES") + { + seg->winFlags |=WINF_REMOVE; + } + seglist.push_back(seg); + } break; + case LEDATA: + case LEDATA32: + j=0; + prevseg=GetIndex(buf,&j)-1; + if(prevseg<0) + { + ReportError(ERR_INV_SEG); + } + prevseg+=segmin; + if((seglist[prevseg]->attr&SEG_ALIGN)==SEG_ABS) + { + ReportError(ERR_ABS_SEG); + } + prevofs=buf[j]+(buf[j+1]<<8); + j+=2; + if(rectype==LEDATA32) + { + prevofs+=(buf[j]+(buf[j+1]<<8))<<16; + j+=2; + } + for(k=0;j=seglist[prevseg]->length) + { + ReportError(ERR_INV_DATA); + } + if(GetNbit(seglist[prevseg]->datmask,prevofs+k)) + { + if(seglist[prevseg]->data[prevofs+k]!=buf[j]) + { + printf("%08lX: %08lX: %i, %li,%li,%li\n",prevofs+k,j,GetNbit(seglist[prevseg]->datmask,prevofs+k),seglist.size(),segmin,prevseg); + ReportError(ERR_OVERWRITE); + } + } + seglist[prevseg]->data[prevofs+k]=buf[j]; + SetNbit(seglist[prevseg]->datmask,prevofs+k); + } + li_le=PREV_LE; + break; + case LIDATA: + case LIDATA32: + if(lidata) + { + DestroyLIDATA(lidata); + } + j=0; + prevseg=GetIndex(buf,&j)-1; + if(prevseg<0) + { + ReportError(ERR_INV_SEG); + } + prevseg+=segmin; + if((seglist[prevseg]->attr&SEG_ALIGN)==SEG_ABS) + { + ReportError(ERR_ABS_SEG); + } + prevofs=buf[j]+(buf[j+1]<<8); + j+=2; + if(rectype==LIDATA32) + { + prevofs+=(buf[j]+(buf[j+1]<<8))<<16; + j+=2; + } + lidata = new DATABLOCK(); + lidata->data.resize(sizeof(PDATABLOCK)*(1024/sizeof(DATABLOCK)+1)); + lidata->blocks=0; + lidata->dataofs=j; + for(i=0;jdata[0])[i]=BuildLiData(&j); + } + lidata->blocks=i; + lidata->count=1; + + k=prevofs; + EmitLiData(lidata,prevseg,&k); + li_le=(rectype==LIDATA)?PREV_LI:PREV_LI32; + break; + case LPUBDEF: + case LPUBDEF32: + case PUBDEF: + case PUBDEF32: + j=0; + grpnum=GetIndex(buf,&j)-1; + if(grpnum>=0) + { + grpnum+=grpmin; + } + segnum=GetIndex(buf,&j)-1; + if(segnum<0) + { + j+=2; + } + else + { + segnum+=segmin; + } + for(;jaliasName=""; + pubdef->grpnum=grpnum; + pubdef->seg=seglist[segnum]; + name=std::string((char *)&buf[j]+1,buf[j]); + j+=name.size()+1; + if(!case_sensitive) + { + strupr(name); + } + pubdef->ofs=buf[j]+256*buf[j+1]; + j+=2; + if((rectype==PUBDEF32) || (rectype==LPUBDEF32)) + { + pubdef->ofs+=(buf[j]+256*buf[j+1])<<16; + j+=2; + } + pubdef->typenum=GetIndex(buf,&j); + if(rectype==LPUBDEF || rectype==LPUBDEF32) + { + pubdef->modnum=modname.size()-1; + } + else + { + pubdef->modnum=0; + } + if((listnode=publics.find(name)) != publics.end()) + { + for(i=0;isecond.size();i++) + { + if(((PPUBLIC)listnode->second[i])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[i])->aliasName == "") + { + printf("Duplicate public symbol %s\n",name.c_str()); + exit(1); + } + (*((PPUBLIC)listnode->second[i]))=(*pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator l = publics.find(name); + if(l == publics.end()) { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(name,vv)); + } else { + l->second.push_back((void *)pubdef); + } + } + } + break; + case LEXTDEF: + case LEXTDEF32: + case EXTDEF: { + for(j=0;jname=nlist[GetIndex(buf,&j)-1]; + grp->numsegs=0; + while(jsegindex[grp->numsegs]=seglist[i]; + grp->numsegs++; + } + else + { + ReportError(ERR_BAD_GRPDEF); + } + } + grplist.push_back(grp); + } break; + case FIXUPP: + case FIXUPP32: + j=0; + while(jrtype=(buf[j]>>2); + r->ofs=buf[j]*256+buf[j+1]; + j+=2; + r->ofs&=0x3ff; + r->rtype^=FIX_SELFREL; + r->rtype&=FIX_MASK; + switch(r->rtype) + { + case FIX_LBYTE: + case FIX_OFS16: + case FIX_BASE: + case FIX_PTR1616: + case FIX_HBYTE: + case FIX_OFS16_2: + case FIX_OFS32: + case FIX_PTR1632: + case FIX_OFS32_2: + case FIX_SELF_LBYTE: + case FIX_SELF_OFS16: + case FIX_SELF_OFS16_2: + case FIX_SELF_OFS32: + case FIX_SELF_OFS32_2: + break; + default: + ReportError(ERR_BAD_FIXUP); + } + LoadFIXUP(r,&buf[0],&j); + + if(li_le==PREV_LE) + { + r->ofs+=prevofs; + r->seg=seglist[prevseg]; + PRELOC rel = new RELOC(*r); + relocs.push_back(rel); + } + else + { + r->seg=seglist[prevseg]; + i=prevofs; + RelocLIDATA(lidata,&i,r); + free(r); + } + } + else + { + /* THRED subrecord */ + i=buf[j]; /* get thred number */ + j++; + if(i&0x40) /* Frame? */ + { + f_thred[i&3]=i; + /* get index if required */ + if((i&0x1c)<0xc) + { + f_thredindex[i&3]=GetIndex(buf,&j); + } + i&=3; + } + else + { + t_thred[i&3]=i; + /* target always has index */ + t_thredindex[i&3]=GetIndex(buf,&j); + } + } + } + break; + case BAKPAT: + case BAKPAT32: + j=0; + if(jrtype=FIX_SELF_LBYTE; break; + case 1: rel->rtype=FIX_SELF_OFS16; break; + case 2: rel->rtype=FIX_SELF_OFS32; break; + default: + printf("Bad BAKPAT record\n"); + exit(1); + } + rel->ofs=buf[j]+256*buf[j+1]; + j+=2; + if(rectype==BAKPAT32) + { + rel->ofs+=(buf[j]+256*buf[j+1])<<16; + j+=2; + } + rel->seg=seglist[i]; + rel->target=i; + rel->frame=i; + rel->ttype=REL_SEGDISP; + rel->ftype=REL_SEGFRAME; + rel->disp=buf[j]+256*buf[j+1]; + j+=2; + if(rectype==BAKPAT32) + { + rel->disp+=(buf[j]+256*buf[j+1])<<16; + j+=2; + } + rel->disp+=rel->ofs; + switch(k) + { + case 0: rel->disp++; break; + case 1: rel->disp+=2; break; + case 2: rel->disp+=4; break; + default: + printf("Bad BAKPAT record\n"); + exit(1); + } + relocs.push_back(rel); + } + break; + case LINNUM: + case LINNUM32: + printf("LINNUM record\n"); + break; + case MODEND: + case MODEND32: + done=1; + if(buf[0]&0x40) + { + if(gotstart) + { + ReportError(ERR_MULTIPLE_STARTS); + } + gotstart=1; + j=1; + LoadFIXUP(&startaddr,&buf[0],&j); + if(startaddr.ftype==REL_LILEFRAME) + { + ReportError(ERR_BAD_FIXUP); + } + } + break; + case COMDEF: + for(j=0;jlength=i; + com->isFar=k; + com->modnum=0; + com->name=ext.name; + externs.push_back(ext); + comdefs.push_back(com); + } + + break; + case COMDAT: + case COMDAT32: + printf("COMDAT section\n"); + exit(1); + + break; + case ALIAS: + printf("ALIAS record\n"); + j=0; + name=std::string((char *)&buf[j]+1,buf[j]); + j+=name.size()+1; + if(!case_sensitive) + { + strupr(name); + } + printf("ALIAS name:%s\n",name.c_str()); + aliasName=std::string((char *)&buf[j]+1,buf[j]); + j+=aliasName.size()+1; + if(!case_sensitive) + { + strupr(aliasName); + } + printf("Substitute name:%s\n",aliasName.c_str()); + if(name.size()) + { + printf("Cannot use alias a blank name\n"); + exit(1); + } + if(!aliasName.size()) + { + printf("No Alias name specified for %s\n",name.c_str()); + exit(1); + } + pubdef=new PUBLIC(); + pubdef->seg=0; + pubdef->grpnum=-1; + pubdef->typenum=-1; + pubdef->ofs=0; + pubdef->modnum=0; + pubdef->aliasName=aliasName; + if((listnode=publics.find(name)) != publics.end()) + { + for(i=0;isecond.size();i++) + { + if(((PPUBLIC)listnode->second[i])->modnum==pubdef->modnum) + { + if(((PPUBLIC)listnode->second[i])->aliasName != "") + { + printf("Warning, two aliases for %s, using %s\n",name.c_str(),((PPUBLIC)listnode->second[i])->aliasName.c_str()); + } + free(pubdef); + pubdef=NULL; + break; + } + } + } + if(pubdef) + { + SORTLIST::iterator l = publics.find(name); + if(l == publics.end()) { + std::vector vv; + vv.push_back((void *)pubdef); + publics.insert(std::make_pair(name,vv)); + } else { + l->second.push_back((void *)pubdef); + } + } + break; + default: + ReportError(ERR_UNKNOWN_RECTYPE); + } + filepos+=4+reclength; + modpos+=4+reclength; + } + if(lidata) + { + DestroyLIDATA(lidata); + } + return 0; +} + +void loadlib(FILE *libfile,std::string libname) +{ + unsigned int i,j,k,n; + std::string name; + unsigned short modpage; + PLIBFILE p; + SORTLIST symlist; + + libfiles.push_back(LIBFILE()); + p=&libfiles[libfiles.size()-1]; + + p->filename=libname; + + if(fread(&buf[0],1,3,libfile)!=3) + { + printf("Error reading from file\n"); + exit(1); + } + p->blocksize=buf[1]+256*buf[2]; + if(fread(&buf[0],1,p->blocksize,libfile)<1) + { + printf("Error reading from file\n"); + exit(1); + } + p->blocksize+=3; + p->dicstart=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24); + p->numdicpages=buf[4]+256*buf[5]; + p->flags=buf[6]; + p->libtype='O'; + + fseek(libfile,p->dicstart,SEEK_SET); + + for(i=0;inumdicpages;i++) + { + if(fread(&buf[0],1,512,libfile)!=512) + { + printf("Error reading from file\n"); + exit(1); + } + for(j=0;j<37;j++) + { + k=buf[j]*2; + if(k) + { + name=std::string((char *)&buf[k+1],buf[k]); + k+=buf[k]+1; + modpage=buf[k]+256*buf[k+1]; + if(!(p->flags&LIBF_CASESENSITIVE) || !case_sensitive) + { + strupr(name); + } + if(name[name.size()-1]=='!') + { + name = ""; + } + else + { + std::vector items; + items.resize(modpage); + symlist.insert(std::make_pair(name,items)); + } + } + } + } + + p->symbols=symlist; + p->modsloaded=0; +} + +void loadlibmod(UINT libnum,UINT modpage) +{ + PLIBFILE p; + FILE *libfile; + UINT i; + + p=&libfiles[libnum]; + + /* don't open a module we've loaded already */ + for(i=0;imodsloaded;i++) + { + if(p->modlist[i]==modpage) return; + } + + libfile=fopen(p->filename.c_str(),"rb"); + if(!libfile) + { + printf("Error opening file %s\n",p->filename.c_str()); + exit(1); + } + fseek(libfile,modpage*p->blocksize,SEEK_SET); + switch(p->libtype) + { + case 'O': + loadmod(libfile); + break; + case 'C': + loadcofflibmod(p,libfile); + break; + default: + printf("Unknown library file format\n"); + exit(1); + } + + p->modlist[p->modsloaded]=modpage; + p->modsloaded++; + fclose(libfile); +} + +void loadres(FILE *f) +{ + unsigned char buf[32]; + static unsigned char buf2[32]={0,0,0,0,0x20,0,0,0,0xff,0xff,0,0,0xff,0xff,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + UINT i,j; + UINT hdrsize,datsize; + std::vector data; + std::vector hdr; + + if(fread(buf,1,32,f)!=32) + { + printf("Invalid resource file\n"); + exit(1); + } + if(memcmp(buf,buf2,32)) + { + printf("Invalid resource file\n"); + exit(1); + } + printf("Loading Win32 Resource File\n"); + while(!feof(f)) + { + i=ftell(f); + if(i&3) + { + fseek(f,4-(i&3),SEEK_CUR); + } + i=fread(buf,1,8,f); + if(i==0 && feof(f)) return; + if(i!=8) + { + printf("Invalid resource file, no header\n"); + exit(1); + } + datsize=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24); + hdrsize=buf[4]+(buf[5]<<8)+(buf[6]<<16)+(buf[7]<<24); + if(hdrsize<16) + { + printf("Invalid resource file, bad header\n"); + exit(1); + } + hdr.resize(hdrsize); + if(fread(&hdr[0],1,hdrsize-8,f)!=(hdrsize-8)) + { + printf("Invalid resource file, missing header\n"); + exit(1); + } + /* if this is a NULL resource, then skip */ + if(!datsize && (hdrsize==32) && !memcmp(buf2+8,&hdr[0],24)) + { + continue; + } + if(datsize) + { + data.resize(datsize); + if(fread(&data[0],1,datsize,f)!=datsize) + { + printf("Invalid resource file, no data\n"); + exit(1); + } + } + else data.resize(0); + RESOURCE res; + res.data=data; + res.length=datsize; + i=0; + hdrsize-=8; + if((hdr[i]==0xff) && (hdr[i+1]==0xff)) + { + res.xtypename.resize(0); + res.typeid=hdr[i+2]+256*hdr[i+3]; + i+=4; + } + else + { + for(j=i;(j<(hdrsize-1))&&(hdr[j]|hdr[j+1]);j+=2); + if(hdr[j]|hdr[j+1]) + { + printf("Invalid resource file, bad name\n"); + exit(1); + } + res.xtypename.resize(j-i+2); + memcpy(&res.xtypename[0],&hdr[i],j-i+2); + i=j+5; + i&=0xfffffffc; + } + if(i>hdrsize) + { + printf("Invalid resource file, overflow\n"); + exit(1); + } + if((hdr[i]==0xff) && (hdr[i+1]==0xff)) + { + res.name.resize(0); + res.id=hdr[i+2]+256*hdr[i+3]; + i+=4; + } + else + { + for(j=i;(j<(hdrsize-1))&&(hdr[j]|hdr[j+1]);j+=2); + if(hdr[j]|hdr[j+1]) + { + printf("Invalid resource file,bad name (2)\n"); + exit(1); + } + res.name.resize(j-i+2); + memcpy(&res.name[0],&hdr[i],j-i+2); + i=j+5; + i&=0xfffffffc; + } + i+=6; /* point to Language ID */ + if(i>hdrsize) + { + printf("Invalid resource file, overflow(2)\n"); + exit(1); + } + res.languageid=hdr[i]+256*hdr[i+1]; + resource.push_back(res); + } +} diff --git a/reactos/tools/ppc-build/alink/output.cpp b/reactos/tools/ppc-build/alink/output.cpp new file mode 100644 index 00000000000..262fbb810ee --- /dev/null +++ b/reactos/tools/ppc-build/alink/output.cpp @@ -0,0 +1,2435 @@ +#include "alink.h" +#include + +static unsigned char defaultStub[]={ + 0x4D,0x5A,0x6C,0x00,0x01,0x00,0x00,0x00, + 0x04,0x00,0x11,0x00,0xFF,0xFF,0x03,0x00, + 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0E,0x1F,0xBA,0x0E,0x00,0xB4,0x09,0xCD, + 0x21,0xB8,0x00,0x4C,0xCD,0x21,0x54,0x68, + 0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72, + 0x61,0x6D,0x20,0x72,0x65,0x71,0x75,0x69, + 0x72,0x65,0x73,0x20,0x57,0x69,0x6E,0x33, + 0x32,0x0D,0x0A,0x24,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static UINT defaultStubSize=sizeof(defaultStub); + +void GetFixupTarget(PRELOC r,PSEG *bseg,UINT *tofs,int isFlat) +{ + PSEG baseseg = 0; + PSEG targseg = 0; + UINT targofs = 0; + UINT frameaddr = 0; + + if( r->seg ) + r->outputPos=r->seg->getbase()+r->ofs; + + switch(r->ftype) + { + case REL_SEGFRAME: + case REL_LILEFRAME: + baseseg=r->seg; + frameaddr = r->outputPos; + break; + case REL_GRPFRAME: + baseseg=r->seg; + break; + case REL_EXTFRAME: + switch(externs[r->frame].flags) + { + case EXT_MATCHEDPUBLIC: + if(!externs[r->frame].pubdef) + { + printf("Reloc:Unmatched extern %s\n",externs[r->frame].name.c_str()); + errcount++; + break; + } + + baseseg=externs[r->frame].pubdef->seg; + r->seg = baseseg; + frameaddr = externs[r->frame].pubdef->ofs + r->seg->getbase(); + break; + case EXT_MATCHEDIMPORT: + baseseg=impdefs[externs[r->frame].impnum].seg; + r->seg = baseseg; + break; + default: + errcount++; + exit(1); + break; + } + break; + default: + printf("Reloc:Unsupported FRAME type %i\n",r->ftype); + errcount++; + exit(1); + } + if(!baseseg) + { + printf("Undefined base seg\n"); + exit(1); + } /* this is a fix for TASM FLAT model, where FLAT group has no segments */ + + switch(r->ttype) + { + case REL_EXTDISP: + case REL_EXTONLY: + switch(externs[r->target].flags) + { + case EXT_MATCHEDPUBLIC: + if(!externs[r->target].pubdef) + { + printf("Reloc:Unmatched extern %s\n",externs[r->frame].name.c_str()); + errcount++; + break; + } + + targseg=externs[r->target].pubdef->seg; + targofs=externs[r->target].pubdef->ofs; + r->seg = targseg; + break; + case EXT_MATCHEDIMPORT: + targseg=impdefs[externs[r->target].impnum].seg; + targofs=impdefs[externs[r->target].impnum].ofs; + r->seg = targseg; + break; + default: + printf("Reloc:Unmatched external referenced in frame\n"); + errcount++; + targseg=seglist[0]; + targofs=0; + break; + } + targofs+=r->disp; + break; + case REL_SEGONLY: + targseg=r->targseg; + targofs=0; + break; + case REL_SEGDISP: + targseg=r->targseg; + targofs = r->disp; + break; + case REL_GRPONLY: + targseg=grplist[r->target]->seg; + targofs=0; + break; + case REL_GRPDISP: + targseg=grplist[r->target]->seg; + targofs=r->disp; + break; + default: + printf("Reloc:Unsupported TARGET type %i\n",r->ttype); + errcount++; + } + if(targseg<0) + { + printf("undefined seg\n"); + exit(1); + } + if(!errcount && !targseg) + { + printf("Reloc: no target segment\n"); + + errcount++; + } + if(!errcount && !baseseg) + { + printf("reloc: no base segment\n"); + + errcount++; + } + + if(!errcount) + { +/* + if(((seglist[targseg]->attr&SEG_ALIGN)!=SEG_ABS) && + ((seglist[baseseg]->attr&SEG_ALIGN)!=SEG_ABS)) + { + if(seglist[baseseg]->getbase()>seglist[targseg]->getbase()) + { + printf("Reloc:Negative base address\n"); + errcount++; + } + targofs+=seglist[targseg]->getbase()-seglist[baseseg]->getbase(); + } +*/ + if((baseseg->attr&SEG_ALIGN)==SEG_ABS) + { + //printf("Warning: Reloc frame is absolute segment\n"); + targseg=baseseg; + } + else if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + //printf("Warning: Reloc target is in absolute segment\n"); + targseg=baseseg; + } + if(!isFlat || ((baseseg->attr&SEG_ALIGN)==SEG_ABS)) + { + if(baseseg->getbase()>(targseg->getbase()+targofs)) + { + printf("Error: target address out of frame\n"); + printf("Base=%08X,target=%08X\n", + baseseg->getbase(),targseg->getbase()+targofs); + errcount++; + } + targofs+=targseg->getbase()-baseseg->getbase(); + *bseg=baseseg; + *tofs=targofs; + } + else + { + *bseg=0; + *tofs=targofs+targseg->getbase(); + if(r->rtype == FIX_REL32 ) + *tofs -= frameaddr; + } + } + else + { + printf("relocation error occurred\n"); + *bseg=0; + *tofs=0; + exit(1); + } +} + + +void OutputCOMfile(const std::string &outname) +{ + long i,j; + UINT started; + UINT lastout; + PSEG targseg; + UINT targofs; + FILE*outfile; + PSEG seg; + unsigned short temps; + unsigned long templ; + + if(impsreq) + { + ReportError(ERR_ILLEGAL_IMPORTS); + } + + errcount=0; + if(gotstart) + { + GetFixupTarget(&startaddr,&seg,&startaddr.ofs,FALSE); + if(errcount) + { + printf("Invalid start address record\n"); + exit(1); + } + + if((startaddr.ofs+startaddr.seg->getbase())!=0x100) + { + printf("Warning, start address not 0100h as required for COM file\n"); + } + } + else + { + printf("Warning, no entry point specified\n"); + } + + for(i=0;iseg; + switch(relocs[i]->rtype) + { + case FIX_BASE: + case FIX_PTR1616: + case FIX_PTR1632: + if((targseg->attr&SEG_ALIGN)!=SEG_ABS) + { + printf("Reloc %li:Segment selector relocations are not supported in COM files\n",i); + errcount++; + } + else + { + j=relocs[i]->ofs; + if(relocs[i]->rtype==FIX_PTR1616) + { + if(targofs>0xffff) + { + printf("Relocs %li:Offset out of range\n",i); + errcount++; + } + temps=get16(seg->data,j); + temps+=targofs; + temps+=targseg->getbase()&0xf; /* non-para seg */ + put16(seg->data,j,temps); + j+=2; + } + else if(relocs[i]->rtype==FIX_PTR1632) + { + templ=get32(seg->data,j); + templ+=targofs; + templ+=targseg->getbase()&0xf; /* non-para seg */ + put32(seg->data,j,templ); + j+=4; + } + temps = get16(seg->data,j); + temps+=targseg->absframe; + put16(seg->data,j,temps); + } + break; + case FIX_OFS32: + case FIX_OFS32_2: + templ=get32(seg->data,relocs[i]->ofs); + templ+=targofs; + templ+=targseg->getbase()&0xf; /* non-para seg */ + put32(seg->data,relocs[i]->ofs,templ); + break; + case FIX_OFS16: + case FIX_OFS16_2: + if(targofs>0xffff) + { + printf("Relocs %li:Offset out of range\n",i); + errcount++; + } + temps=get16(seg->data, relocs[i]->ofs); + temps+=targofs; + temps+=targseg->getbase()&0xf; /* non-para seg */ + put16(seg->data, relocs[i]->ofs, temps); + break; + case FIX_LBYTE: + seg->data[relocs[i]->ofs]+=targofs&0xff; + seg->data[relocs[i]->ofs]+=targseg->getbase()&0xf; /* non-para seg */ + break; + case FIX_HBYTE: + templ=targofs+(targseg->getbase()&0xf); /* non-para seg */ + seg->data[relocs[i]->ofs]+=(templ>>8)&0xff; + break; + case FIX_SELF_LBYTE: + if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targseg->getbase()+targofs; + j-=seg->getbase()+relocs[i]->ofs+1; + if((j<-128)||(j>127)) + { + printf("Error: Reloc %li out of range\n",i); + } + else + { + seg->data[relocs[i]->ofs]+=j; + } + } + break; + case FIX_SELF_OFS16: + case FIX_SELF_OFS16_2: + if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targseg->getbase()+targofs; + j-=seg->getbase()+relocs[i]->ofs+2; + if((j<-32768)||(j>32767)) + { + printf("Error: Reloc %li out of range\n",i); + } + else + { + temps=get16(seg->data, relocs[i]->ofs); + temps+=j; + put16(seg->data, relocs[i]->ofs, temps); + } + } + break; + case FIX_SELF_OFS32: + case FIX_SELF_OFS32_2: + if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targseg->getbase()+targofs; + j-=seg->getbase()+relocs[i]->ofs+4; + templ=get32(seg->data, relocs[i]->ofs); + templ+=j; + put32(seg->data, relocs[i]->ofs, templ); + } + break; + default: + printf("Reloc %li:Relocation type %i not supported\n",i,relocs[i]->rtype); + errcount++; + } + } + + if(errcount!=0) + { + exit(1); + } + outfile=fopen(outname.c_str(),"wb"); + if(!outfile) + { + printf("Error writing to file %s\n",outname.c_str()); + exit(1); + } + + started=lastout=0; + + for(i=0;iattr&SEG_ALIGN) !=SEG_ABS)) + { + if(started>outlist[i]->getbase()) + { + printf("Segment overlap\n"); + fclose(outfile); + exit(1); + } + if(padsegments) + { + while(startedgetbase()) + { + fputc(0,outfile); + started++; + } + } + else + { + started=outlist[i]->getbase(); + } + for(j=0;jlength;j++) + { + if(started>=0x100) + { + if(GetNbit(outlist[i]->datmask,j)) + { + for(;lastoutdata[j],outfile); + lastout=started+1; + } + else if(padsegments) + { + fputc(0,outfile); + lastout=started+1; + } + } + else + { + lastout=started+1; + if(GetNbit(outlist[i]->datmask,j)) + { + printf("Warning - data at offset %08lX (%s:%08lX) discarded\n",started,outlist[i]->name.c_str(),j); + } + } + started++; + } + } + } + + fclose(outfile); +} + +void OutputEXEfile(const std::string &outname) +{ + long i,j; + UINT started,lastout; + PSEG targseg; + UINT targofs; + FILE*outfile; + std::vector headbuf; + long relcount; + int gotstack; + UINT totlength; + PSEG seg; + unsigned short temps; + unsigned long templ; + + if(impsreq) + { + ReportError(ERR_ILLEGAL_IMPORTS); + } + + errcount=0; + gotstack=0; + headbuf.resize(0x40 + (4*relocs.size())); + relcount=0; + + for(i=0;i<0x40;i++) + { + headbuf[i]=0; + } + + headbuf[0x00]='M'; /* sig */ + headbuf[0x01]='Z'; + put16(headbuf, 0x0c, maxalloc); + headbuf[0x18]=0x40; + + if(gotstart) + { + GetFixupTarget(&startaddr,&seg,&startaddr.ofs,FALSE); + if(errcount) + { + printf("Invalid start address record\n"); + exit(1); + } + + i=startaddr.seg->getbase(); + startaddr.ofs+=i&0xf; + i>>=4; + if((startaddr.ofs>65535)||(i>65535)||((startaddr.seg->attr&SEG_ALIGN)==SEG_ABS)) + { + printf("Invalid start address\n"); + errcount++; + } + else + { + put16(headbuf, 0x14, startaddr.ofs); + put16(headbuf, 0x16, i); + } + } + else + { + printf("Warning, no entry point specified\n"); + } + + totlength=0; + + for(i=0;iattr&SEG_ALIGN)!=SEG_ABS) + { + totlength=outlist[i]->getbase()+outlist[i]->length; + if((outlist[i]->attr&SEG_COMBINE)==SEG_STACK) + { + if(gotstack) + { + printf("Internal error - stack segments not combined\n"); + exit(1); + } + gotstack=1; + if((outlist[i]->length>65536)||(outlist[i]->length==0)) + { + printf("SP value out of range\n"); + errcount++; + } + if((outlist[i]->getbase()>0xfffff) || ((outlist[i]->getbase()&0xf)!=0)) + { + printf("SS value out of range\n"); + errcount++; + } + if(!errcount) + { + put16(headbuf, 0x0e, outlist[i]->getbase() >> 4); + put16(headbuf, 0x10, outlist[i]->length); + } + } + } + } + + if(!gotstack) + { + printf("Warning - no stack\n"); + } + + for(i=0;iseg; + GetFixupTarget(relocs[i],&targseg,&targofs,FALSE); + switch(relocs[i]->rtype) + { + case FIX_BASE: + case FIX_PTR1616: + case FIX_PTR1632: + j=relocs[i]->ofs; + if(relocs[i]->rtype==FIX_PTR1616) + { + if(targofs>0xffff) + { + printf("Relocs %li:Offset out of range\n",i); + errcount++; + } + temps=get16(seg->data,j); + temps+=targofs; + temps+=targseg->getbase()&0xf; /* non-para seg */ + put16(seg->data,j,temps); + j+=2; + } + else if(relocs[i]->rtype==FIX_PTR1632) + { + templ=get32(seg->data,j); + templ+=targofs; + templ+=targseg->getbase()&0xf; /* non-para seg */ + put32(seg->data,j,templ); + j+=4; + } + if((targseg->attr&SEG_ALIGN)!=SEG_ABS) + { + if(targseg->getbase()>0xfffff) + { + printf("Relocs %li:Segment base out of range\n",i); + errcount++; + } + temps=get16(seg->data,j); + temps+=(targseg->getbase()>>4); + put16(seg->data,j,temps); + templ=seg->getbase()>>4; + put16(headbuf,0x40+relcount*4+2,templ); + templ=(seg->getbase()&0xf)+j; + put16(headbuf,0x40+relcount+4,templ); + relcount++; + } + else + { + temps=get16(seg->data,j); + temps+=targseg->absframe; + put16(seg->data,j,temps); + } + break; + case FIX_OFS32: + case FIX_OFS32_2: + templ=get32(seg->data,relocs[i]->ofs); + templ+=targofs; + templ+=targseg->getbase()&0xf; /* non-para seg */ + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_OFS16: + case FIX_OFS16_2: + if(targofs>0xffff) + { + printf("Relocs %li:Offset out of range\n",i); + errcount++; + } + temps = get32(seg->data, relocs[i]->ofs); + temps+=targofs; + temps+=targseg->getbase()&0xf; /* non-para seg */ + put32(seg->data, relocs[i]->ofs, temps); + break; + case FIX_LBYTE: + seg->data[relocs[i]->ofs]+=targofs&0xff; + seg->data[relocs[i]->ofs]+=targseg->getbase()&0xf; /* non-para seg */ + break; + case FIX_HBYTE: + templ=targofs+(targseg->getbase()&0xf); /* non-para seg */ + seg->data[relocs[i]->ofs]+=(templ>>8)&0xff; + break; + case FIX_SELF_LBYTE: + if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targseg->getbase()+targofs; + j-=seg->getbase()+relocs[i]->ofs+1; + if((j<-128)||(j>127)) + { + printf("Error: Reloc %li out of range\n",i); + } + else + { + seg->data[relocs[i]->ofs]+=j; + } + } + break; + case FIX_SELF_OFS16: + case FIX_SELF_OFS16_2: + if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targseg->getbase()+targofs; + j-=seg->getbase()+relocs[i]->ofs+2; + if((j<-32768)||(j>32767)) + { + printf("Error: Reloc %li out of range\n",i); + } + else + { + temps = get32(seg->data, relocs[i]->ofs); + temps+=j; + put32(seg->data, relocs[i]->ofs, temps); + } + } + break; + case FIX_SELF_OFS32: + case FIX_SELF_OFS32_2: + if((targseg->attr&SEG_ALIGN)==SEG_ABS) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targseg->getbase()+targofs; + j-=seg->getbase()+relocs[i]->ofs+4; + templ=get32(seg->data,relocs[i]->ofs); + templ+=j; + put32(seg->data,relocs[i]->ofs,templ); + } + break; + default: + printf("Reloc %li:Relocation type %i not supported\n",i,relocs[i]->rtype); + errcount++; + } + } + + if(relcount>65535) + { + printf("Too many relocations\n"); + exit(1); + } + + put32(headbuf, 0x06, relcount); + i=relcount*4+0x4f; + i>>=4; + totlength+=i<<4; + put32(headbuf, 0x08, i); + i=totlength%512; + put32(headbuf, 0x02, i); + i=(totlength+0x1ff)>>9; + if(i>65535) + { + printf("File too large\n"); + exit(1); + } + put32(headbuf, 0x04, i); + + if(errcount!=0) + { + exit(1); + } + + outfile=fopen(outname.c_str(),"wb"); + if(!outfile) + { + printf("Error writing to file %s\n",outname.c_str()); + exit(1); + } + + i=get32(headbuf, 8) * 16; + if(fwrite(&headbuf[0],1,i,outfile)!=i) + { + printf("Error writing to file %s\n",outname.c_str()); + exit(1); + } + + started=0; + lastout=0; + + for(i=0;iattr&SEG_ALIGN) !=SEG_ABS)) + { + if(started>outlist[i]->getbase()) + { + printf("Segment overlap\n"); + fclose(outfile); + exit(1); + } + if(padsegments) + { + while(startedgetbase()) + { + fputc(0,outfile); + started++; + } + } + else + { + started=outlist[i]->getbase(); + } + for(j=0;jlength;j++) + { + if(GetNbit(outlist[i]->datmask,j)) + { + for(;lastoutdata[j],outfile); + lastout=started+1; + } + else if(padsegments) + { + fputc(0,outfile); + lastout=started+1; + } + started++; + } + } + } + + if(lastout!=started) + { + fseek(outfile,0,SEEK_SET); + lastout+=(headbuf[8]+256*headbuf[9])<<4; + i=lastout%512; + put32(headbuf, 2, i); + i=(lastout+0x1ff)>>9; + put32(headbuf, 4, i); + i=((totlength-lastout)+0xf)>>4; + if(i>65535) + { + printf("Memory requirements too high\n"); + } + put32(headbuf, 10, i); + if(fwrite(&headbuf[0],1,12,outfile)!=12) + { + printf("Error writing to file\n"); + exit(1); + } + } + fclose(outfile); +} + +long createOutputSection(char *name,UINT winFlags) +{ + UINT j; + PSEG seg = new SEG(); + + outlist.push_back(seg); + seglist.push_back(seg); + seg->name = name; + seg->classindex=-1; + seg->overlayindex=-1; + j=outlist[outlist.size()-1]->getbase()+outlist[outlist.size()-1]->length; + j+=(objectAlign-1); + j&=(0xffffffff-(objectAlign-1)); + seg->setbase(j); + seg->length=0; + seg->data.resize(0); + seg->datmask.resize(0); + seg->absofs=seglist.size()-1; + seg->attr=SEG_BYTE | SEG_PRIVATE; + seg->winFlags=winFlags ^ WINF_NEG_FLAGS; + return outlist.size()-1; +} + +void BuildPEImports(long impsectNum,PUCHAR objectTable) +{ + long i,j,k; + std::vector reqimps; + std::vector dllNames; + UINT reqcount=0; + std::vector dllNumImps, dllImpsDone, dllImpNameSize; + UINT dllCount=0,dllNameSize=0,namePos; + PSEG impsect; + UINT thunkPos,thunk2Pos,impNamePos; + + if(impsectNum<0) return; + for(i=0;isetbase(k+imageBase); /* get base address of section */ + + impsect->length=(dllCount+1)*PE_IMPORTDIRENTRY_SIZE+dllNameSize; + if(impsect->length&3) impsect->length+=4-(impsect->length&3); /* align to 4-byte boundary */ + thunkPos=impsect->getbase()+impsect->length; + for(j=0,i=0;jlength+=i*2*4; /* update length of section too. */ + + for(j=0,i=0;jlength+=i; + + impsect->data.resize(impsect->length); + impsect->datmask.resize((impsect->length+7)/8); + for(i=0;i<(impsect->length+7)/8;i++) + { + impsect->datmask[i]=0xff; + } + + /* end of directory entries=name table */ + namePos=impsect->getbase()+(dllCount+1)*PE_IMPORTDIRENTRY_SIZE; + for(i=0;idata, j, thunkPos-imageBase); /* address of first thunk table */ + put32(impsect->data, j+4, 0); /* zero out time stamp */ + put32(impsect->data, j+8, 0); /* zero out version number */ + put32(impsect->data, j+12, namePos-imageBase); /* address of DLL name */ + thunk2Pos=thunkPos+(dllNumImps[i]+1)*4; /* address of second thunk table */ + put32(impsect->data, j+16, thunk2Pos-imageBase); /* store it */ + + /* add name to table */ + strcpy((char *)(&impsect->data[0])+namePos-impsect->getbase(),(char *)dllNames[i].c_str()); + namePos+=dllNames[i].size()+1; + if(namePos&1) + { + impsect->data[namePos-impsect->getbase()]=0; + namePos++; + } + /* add imported names to table */ + for(k=0;kdata, thunkPos-impsect->getbase(), impNamePos-imageBase); + put32(impsect->data, thunk2Pos-impsect->getbase(), impNamePos-imageBase); + + /* no hint */ + put16(impsect->data, impNamePos-impsect->getbase(), 0); + impNamePos+=2; + /* store name */ + strcpy((char *)(&impsect->data[0])+impNamePos-impsect->getbase(), + (char *)impdefs[reqimps[k]].imp_name.c_str()); + impNamePos+=strlen(impdefs[reqimps[k]].imp_name.c_str())+1; + if(impNamePos&1) + { + impsect->data[impNamePos-impsect->getbase()]=0; + impNamePos++; + } + } + else + { + /* store ordinal number in thunk tables */ + j=impdefs[reqimps[k]].ordinal+PE_ORDINAL_FLAG; + put32(impsect->data, thunkPos-impsect->getbase(), j); + put32(impsect->data, thunk2Pos-impsect->getbase(), j); + } + impdefs[reqimps[k]].abs=impsect->absofs; + impdefs[reqimps[k]].ofs=thunk2Pos-impsect->getbase(); + thunkPos+=4; + thunk2Pos+=4; + } + /* zero out end of thunk tables */ + put32(impsect->data, thunkPos-impsect->getbase(), 0); + put32(impsect->data, thunk2Pos-impsect->getbase(), 0); + thunkPos=thunk2Pos+4; + } + /* zero out the final entry to mark the end of the table */ + j=i*PE_IMPORTDIRENTRY_SIZE; + for(i=0;idata[j]=0; + } + + k=impsect->length; + k+=objectAlign-1; + k&=(0xffffffff-(objectAlign-1)); + impsect->virtualSize=k; + put32(objectTable, 8, k); /* store virtual size (in memory) of segment */ + + k=impsect->length; + put32(objectTable, 16, k); /* store initialised data size */ + + return; +} + +int compar( const void *a, const void *b ) +{ + PRELOC aa = *((PRELOC *)a); + PRELOC bb = *((PRELOC *)b); + + return (aa->outputPos < bb->outputPos) ? -1 : (aa->outputPos > bb->outputPos) ? 1 : 0; +} + +void BuildPERelocs(long relocSectNum,PUCHAR objectTable) +{ + int i,j,r; + PSEG relocSect, seg; + UINT curStartPos; + UINT curBlockPos; + UINT k; + PSEG targseg; + UINT targofs; + unsigned long templ, tinit; + unsigned short temps; + + /* do fixups */ + for(i=0;iseg; + GetFixupTarget(relocs[i],&targseg,&targofs,TRUE); + + assert(seg->length > relocs[i]->ofs+3); + + switch(relocs[i]->rtype) + { + case FIX_BASE: + case FIX_PTR1616: + case FIX_PTR1632: + if(targseg<0) + { + printf("Reloc %li:Segment selector relocations are not supported in PE files\n",i); + printf("rtype=%02X, frame=%04X, target=%04X, ftype=%02X, ttype=%02X\n", + relocs[i]->rtype,relocs[i]->frame,relocs[i]->target,relocs[i]->ftype, + relocs[i]->ttype); + + errcount++; + } + else + { + j=relocs[i]->ofs; + if(relocs[i]->rtype==FIX_PTR1616) + { + if(targofs>0xffff) + { + printf("Relocs %li:Warning 32 bit offset in 16 bit field\n",i); + } + targofs&=0xffff; + temps=get16(seg->data, j); + temps+=targofs; + put16(seg->data, j, temps); + j+=2; + } + else if(relocs[i]->rtype==FIX_PTR1632) + { + templ = get32(seg->data, j); + templ+=targofs; + put32(seg->data, j, templ); + j+=4; + } + temps = get16(seg->data, j); + temps+=targseg->absframe; + put16(seg->data, j, temps); + } + break; + case FIX_OFS32: + case FIX_OFS32_2: + templ = get32(seg->data, relocs[i]->ofs); + templ+=targofs; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_PPC_ADDR24: + templ = get32(seg->data, relocs[i]->ofs); + tinit = templ; templ = targofs; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_PPC_REL24: + templ = get32(seg->data, relocs[i]->ofs); + tinit = templ; + //templ += (targofs - seg->getbase() - relocs[i]->ofs) & 0x3ffffc; + //templ |= tinit & 3; + templ = (templ & 0xfc000003) | + (targofs - seg->getbase() - relocs[i]->ofs) & 0x3fffffc; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_PPC_SECTOFF: + templ = get32(seg->data, relocs[i]->ofs); + tinit = templ; templ =+ targofs - imageBase; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_PPC_RVA16LO: + templ = get16(seg->data, relocs[i]->ofs); + tinit = templ; templ = targofs; + put16(seg->data, relocs[i]->ofs, templ); + break; + case FIX_PPC_RVA16HA: + templ = get16(seg->data, relocs[i]->ofs) << 16; + tinit = templ; templ = targofs; + /* High adjust */ + if( templ & 0x8000 ) templ += 0x8000; + put16(seg->data, relocs[i]->ofs, templ >> 16); + break; + case FIX_ADDR32: + templ = get32(seg->data, relocs[i]->ofs); + tinit = templ; templ = targofs; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_RVA32: + templ = get32(seg->data, relocs[i]->ofs); + tinit = templ; templ =targofs - imageBase; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_REL32: + templ = get32(seg->data, relocs[i]->ofs); + tinit = templ; templ=targofs; + put32(seg->data, relocs[i]->ofs, templ); + break; + case FIX_OFS16: + case FIX_OFS16_2: + if(targofs>0xffff) + { + printf("Relocs %li:Warning 32 bit offset in 16 bit field\n",i); + } + targofs&=0xffff; + temps = get16(seg->data, relocs[i]->ofs); + temps+=targofs; + put16(seg->data, relocs[i]->ofs, temps); + break; + case FIX_LBYTE: + case FIX_HBYTE: + printf("Error: Byte relocations not supported in PE files\n"); + errcount++; + break; + case FIX_SELF_LBYTE: + if(targseg>=0) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targofs; + j-=(seg->getbase()+relocs[i]->ofs+1); + if((j<-128)||(j>127)) + { + printf("Error: Reloc %li out of range\n",i); + } + else + { + seg->data[relocs[i]->ofs]+=j; + } + } + break; + case FIX_SELF_OFS16: + case FIX_SELF_OFS16_2: + if(targseg>=0) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targofs; + j-=(seg->getbase()+relocs[i]->ofs+2); + if((j<-32768)||(j>32767)) + { + printf("Error: Reloc %li out of range\n",i); + } + else + { + temps = get16(seg->data, relocs[i]->ofs); + temps+=j; + put16(seg->data, relocs[i]->ofs, temps); + } + } + break; + case FIX_SELF_OFS32: + case FIX_SELF_OFS32_2: + if(targseg>=0) + { + printf("Error: Absolute Reloc target not supported for self-relative fixups\n"); + errcount++; + } + else + { + j=targofs; + j-=(seg->getbase()+relocs[i]->ofs+4); + templ = get32(seg->data, relocs[i]->ofs); + templ+=j; + put32(seg->data, relocs[i]->ofs, templ); + } + break; + default: + printf("Reloc %li:Relocation type %i not supported\n",i,relocs[i]->rtype); + errcount++; + } + } + + /* get reloc section */ + relocSect=outlist[relocSectNum]; /* get section structure */ + + /* sort relocations into order of increasing address */ + qsort(&relocs[0], relocs.size(), sizeof(relocs[0]), &compar); + + for(i=0,curStartPos=0,curBlockPos=0;irtype) + { + case FIX_SELF_OFS32: + case FIX_SELF_OFS32_2: + case FIX_SELF_OFS16: + case FIX_SELF_OFS16_2: + case FIX_SELF_LBYTE: + case FIX_RVA32: + continue; /* self-relative fixups and RVA fixups don't relocate */ + default: + break; + } + if(relocs[i]->outputPos>=(curStartPos+0x1000)) /* more than 4K past block start? */ + { + j=relocSect->length&3; + if(j) /* unaligned block position */ + { + relocSect->length+=4-j; /* update length to align block */ + /* and block memory */ + relocSect->data.resize(relocSect->length); + /* update size of current reloc block */ + k = get32(relocSect->data, curBlockPos+4); + k+=4-j; + put32(relocSect->data, curBlockPos+4, k); + for(j=4-j;j>0;j--) + { + relocSect->data[relocSect->length-j]=0; + } + } + curBlockPos=relocSect->length; /* get address in section of current block */ + relocSect->length+=8; /* 8 bytes block header */ + /* increase size of block */ + relocSect->data.resize(relocSect->length); + /* store reloc base address, and block size */ + curStartPos=relocs[i]->outputPos&0xfffff000; /* start of mem page */ + + /* start pos is relative to image base */ + put32(relocSect->data, curBlockPos, curStartPos-imageBase); + put32(relocSect->data, curBlockPos+4, 8); /* start size is 8 bytes */ + } + relocSect->data.resize(relocSect->length+2); + + j=relocs[i]->outputPos-curStartPos; /* low 12 bits of address */ + switch(relocs[i]->rtype) + { + case FIX_PTR1616: + case FIX_OFS16: + case FIX_OFS16_2: + j|= PE_REL_LOW16; + break; + case FIX_PTR1632: + case FIX_OFS32: + case FIX_OFS32_2: + j|= PE_REL_OFS32; + } + /* store relocation */ + put16(relocSect->data, relocSect->length, j); + /* update block length */ + relocSect->length+=2; + /* update size of current reloc block */ + k = get32(relocSect->data, curBlockPos+4); + k+=2; + put32(relocSect->data, curBlockPos+4, k); + } + /* if no fixups, then build NOP fixups, to make Windows NT happy */ + /* when it trys to relocate image */ + if(relocSect->length==0) + { + /* 12 bytes for dummy section */ + relocSect->length=12; + relocSect->data.resize(12); + /* zero it out for now */ + for(i=0;i<12;i++) relocSect->data[i]=0; + relocSect->data[4]=12; /* size of block */ + } + + relocSect->datmask.resize((relocSect->length+7)/8); + for(i=0;i<(relocSect->length+7)/8;i++) + { + relocSect->datmask[i]=0xff; + } + + objectTable+=PE_OBJECTENTRY_SIZE*relocSectNum; /* point to reloc object entry */ + k=relocSect->length; + k+=objectAlign-1; + k&=(0xffffffff-(objectAlign-1)); + relocSect->virtualSize=k; + put32(objectTable, 8, k); /* store virtual size (in memory) of segment */ + put32(objectTable, 16, relocSect->length); /* store initialised data size /*/ + + k = get32(objectTable, -PE_OBJECTENTRY_SIZE+20); + /* add physical length of prev object */ + k += get32(objectTable, -PE_OBJECTENTRY_SIZE+16); + + k+=fileAlign-1; + k&=(0xffffffff-(fileAlign-1)); /* aligned */ + + /* k is now physical location of this object */ + + put32(objectTable, 20, k); /* store physical file offset */ + /* get virtual start of prev object */ + k = get32(objectTable, -PE_OBJECTENTRY_SIZE+12); + k += get32(objectTable, -PE_OBJECTENTRY_SIZE+8); + + /* store base address (RVA) of section */ + put32(objectTable, 12, k); + + relocSect->setbase(k+imageBase); /* relocate section */ + + return; +} + +void BuildPEExports(long SectNum,PUCHAR objectTable,PUCHAR name) +{ + long i,j; + UINT k; + PSEG expSect; + UINT namelen; + UINT numNames=0; + UINT RVAStart; + UINT nameRVAStart; + UINT ordinalStart; + UINT nameSpaceStart; + UINT minOrd; + UINT maxOrd; + UINT numOrds; + std::vector nameList; + PEXPREC curName; + + if(!expdefs.size() || (SectNum<0)) return; /* return if no exports */ + expSect=outlist[SectNum]; + + if(name) + { + namelen=strlen((char *)name); + /* search backwards for path separator */ + for(i=namelen-1;(i>=0) && (name[i]!=PATH_CHAR);i--); + if(i>=0) /* if found path separator */ + { + name+=(i+1); /* update name pointer past path */ + namelen -= (i+1); /* and reduce length */ + } + } + else namelen=0; + + expSect->length=PE_EXPORTHEADER_SIZE+4*expdefs.size()+namelen+1; + /* min section size= header size + num exports * pointer size */ + /* plus space for null-terminated name */ + + minOrd=0xffffffff; /* max ordinal num */ + maxOrd=0; + + for(i=0;ilength+=expdefs[i].exp_name.length()+7; + numNames++; + } + + if(expdefs[i].flags&EXP_ORD) /* ordinal? */ + { + if(expdefs[i].ordinalmaxOrd) maxOrd=expdefs[i].ordinal; + } + } + + numOrds=expdefs.size(); /* by default, number of RVAs=number of exports */ + if(maxOrd>=minOrd) /* actually got some ordinal references? */ + { + i=maxOrd-minOrd+1; /* get number of ordinals */ + if(i>expdefs.size()) /* if bigger range than number of exports */ + { + expSect->length+=4*(i-expdefs.size()); /* up length */ + numOrds=i; /* get new num RVAs */ + } + } + else + { + minOrd=1; /* if none defined, min is set to 1 */ + } + + expSect->data.resize(expSect->length); + + objectTable+=PE_OBJECTENTRY_SIZE*SectNum; /* point to reloc object entry */ + k=expSect->length; + k+=objectAlign-1; + k&=(0xffffffff-(objectAlign-1)); + expSect->virtualSize=k; + put32(objectTable, 8, k); /* store virtual size (in memory) of segment */ + k=expSect->length; + put32(objectTable, 16, k); /* store initialised data size */ + + k =get32(objectTable, -PE_OBJECTENTRY_SIZE+20); /* get physical start of prev object */ + k+=get32(objectTable, -PE_OBJECTENTRY_SIZE+16); /* add physical length of prev object */ + + k+=fileAlign-1; + k&=(0xffffffff-(fileAlign-1)); /* aligned */ + + /* k is now physical location of this object */ + + put32(objectTable, 20, k); /* store physical file offset */ + + k = get32(objectTable, -PE_OBJECTENTRY_SIZE+12); /* get virtual start of prev object */ + k+= get32(objectTable, -PE_OBJECTENTRY_SIZE+8); /* add virtual length of prev object */ + + /* store base address (RVA) of section */ + put32(objectTable, 12, k); + + expSect->setbase(k+imageBase); /* relocate section */ + + /* start with buf=all zero */ + for(i=0;ilength;i++) expSect->data[i]=0; + + /* store creation time of export data */ + k=(UINT)time(NULL); + put32(expSect->data, 4, k); + put32(expSect->data, 16, minOrd); /* store ordinal base */ + + /* store number of RVAs */ + put32(expSect->data, 20, numOrds); + + RVAStart=PE_EXPORTHEADER_SIZE; /* start address of RVA table */ + nameRVAStart=RVAStart+numOrds*4; /* start of name table entries */ + ordinalStart=nameRVAStart+numNames*4; /* start of associated ordinal entries */ + nameSpaceStart=ordinalStart+numNames*2; /* start of actual names */ + + /* store number of named exports */ + put32(expSect->data, 24, numNames); + + /* store address of address table */ + put32(expSect->data, 28, RVAStart+expSect->getbase()-imageBase); + + /* store address of name table */ + put32(expSect->data, 32, nameRVAStart+expSect->getbase()-imageBase); + + /* store address of ordinal table */ + put32(expSect->data, 36, ordinalStart+expSect->getbase()-imageBase); + + /* process numbered exports */ + for(i=0;idata, RVAStart+4*(expdefs[i].ordinal-minOrd)); + if(k) /* error if already used */ + { + printf("Duplicate export ordinal %i\n",expdefs[i].ordinal); + exit(1); + } + /* get RVA of export entry */ + k=expdefs[i].pubdef->ofs+ + expdefs[i].pubdef->seg->getbase()- + imageBase; + /* store it */ + put32(expSect->data, RVAStart+4*(expdefs[i].ordinal-minOrd), k); + } + } + + /* process non-numbered exports */ + for(i=0,j=RVAStart;idata, j); + if(k) j+=4; + } + while(k); /* move through table until we find a free spot */ + /* get RVA of export entry */ + k=expdefs[i].pubdef->ofs; + k+=expdefs[i].pubdef->seg->getbase(); + k-=imageBase; + /* store RVA */ + put32(expSect->data, j, k); + expdefs[i].ordinal=(j-RVAStart)/4+minOrd; /* store ordinal */ + j+=4; + } + } + + if(numNames) /* sort name table if present */ + { + nameList.resize(numNames); + j=0; /* no entries yet */ + for(i=0;i=0;j--) + { + /* break out if we're above previous entry */ + if(curName->exp_name > nameList[j]->exp_name) + { + break; + } + /* else move entry up */ + nameList[j+1]=nameList[j]; + } + j++; /* move to one after better entry */ + nameList[j]=curName; /* insert current entry into position */ + } + /* and store */ + for(i=0;idata, ordinalStart, nameList[i]->ordinal-minOrd); + ordinalStart+=2; + /* store name RVA */ + put32(expSect->data, nameRVAStart, nameSpaceStart+expSect->getbase()-imageBase); + nameRVAStart+=4; + /* store name */ + for(j=0;nameList[i]->exp_name[j];j++,nameSpaceStart++) + { + expSect->data[nameSpaceStart]=nameList[i]->exp_name[j]; + } + /* store NULL */ + expSect->data[nameSpaceStart]=0; + nameSpaceStart++; + } + } + + /* store library name */ + for(j=0;jdata[nameSpaceStart+j]=name[j]; + } + if(namelen) + { + expSect->data[nameSpaceStart+j]=0; + /* store name RVA */ + put32(expSect->data, 12, nameSpaceStart+expSect->getbase()-imageBase); + } + + expSect->datmask.resize((expSect->length+7)/8); + for(i=0;i<(expSect->length+7)/8;i++) + { + expSect->datmask[i]=0xff; + } + + return; +} + +void BuildPEResources(long sectNum,PUCHAR objectTable) +{ + long i,j; + UINT k; + SEG *ressect; + RESOURCE curres; + int numtypes,numnamedtypes; + int numPairs,numnames,numids; + UINT nameSize,dataSize; + UINT tableSize,dataListSize; + UINT namePos,dataPos,tablePos,dataListPos; + UINT curTypePos,curNamePos,curLangPos; + unsigned char *curTypeName,*curName; + int curTypeId,curId; + + if((sectNum<0) || !resource.size()) return; + + objectTable+=PE_OBJECTENTRY_SIZE*sectNum; /* point to import object entry */ + k=get32(objectTable, -PE_OBJECTENTRY_SIZE+20); /* get physical start of prev object */ + k+=get32(objectTable, -PE_OBJECTENTRY_SIZE+16); /* add physical length of prev object */ + + k+=fileAlign-1; + k&=(0xffffffff-(fileAlign-1)); /* aligned */ + + /* k is now physical location of this object */ + + put32(objectTable, 20, k); /* store physical file offset */ + k = get32(objectTable, 12); /* get virtual start of prev object */ + k+= get32(objectTable, 8); /* add virtual length of prev object */ + + /* store base address (RVA) of section */ + put32(objectTable, 12, k); + + ressect=outlist[sectNum]; + ressect->setbase(k); /* get base RVA of section */ + + /* sort into type-id order */ + for(i=1;i=0;j--) + { + if(resource[j].xtypename.size()) + { + if(!curres.xtypename.size()) break; + if(_wstricmp(&curres.xtypename[0],&resource[j].xtypename[0])>0) break; + if(_wstricmp(&curres.xtypename[0],&resource[j].xtypename[0])==0) + { + if(resource[j].name.size()) + { + if(!curres.name.size()) break; + if(_wstricmp(&curres.name[0],&resource[j].name[0])>0) break; + if(_wstricmp(&curres.name[0],&resource[j].name[0])==0) + { + if(resource[j].languageid>curres.languageid) + break; + if(resource[j].languageid==curres.languageid) + { + printf("Error duplicate resource ID\n"); + exit(1); + } + } + } + else + { + if(!curres.name.size()) + { + if(curres.id>resource[j].id) break; + if(curres.id==resource[j].id) + { + if(resource[j].languageid>curres.languageid) + break; + if(resource[j].languageid==curres.languageid) + { + printf("Error duplicate resource ID\n"); + exit(1); + } + } + } + } + } + } + else + { + if(!curres.xtypename.size()) + { + if(curres.typeid>resource[j].typeid) break; + if(curres.typeid==resource[j].typeid) + { + if(resource[j].name.size()) + { + if(!curres.name.size()) break; + if(_wstricmp(&curres.name[0],&resource[j].name[0])>0) break; + if(_wstricmp(&curres.name[0],&resource[j].name[0])==0) + { + if(resource[j].languageid>curres.languageid) + break; + if(resource[j].languageid==curres.languageid) + { + printf("Error duplicate resource ID\n"); + exit(1); + } + } + } + else + { + if(!curres.name.size()) + { + if(curres.id>resource[j].id) break; + if(curres.id==resource[j].id) + { + if(resource[j].languageid>curres.languageid) + break; + if(resource[j].languageid==curres.languageid) + { + printf("Error duplicate resource ID\n"); + exit(1); + } + } + } + } + } + } + } + resource[j+1]=resource[j]; + } + j++; + resource[j]=curres; + } + + nameSize=0; + dataSize=0; + for(i=0;i0) && !_wstricmp(&resource[i].xtypename[0],&resource[i-1].xtypename[0])) + { + if(resource[i].name.size()) + { + if(_wstricmp(&resource[i].name[0],&resource[i-1].name[0])==0) + numPairs--; + } + else + { + if(!resource[i-1].name.size() && (resource[i].id ==resource[i-1].id)) + numPairs--; + } + continue; + } + numnamedtypes++; + } + numtypes=numnamedtypes; + for(;i0) && !resource[i-1].xtypename.size() && (resource[i].typeid==resource[i-1].typeid)) + { + if(resource[i].name.size()) + { + if(_wstricmp(&resource[i].name[0],&resource[i-1].name[0])==0) + numPairs--; + } + else + { + if(!resource[i-1].name.size() && (resource[i].id ==resource[i-1].id)) + numPairs--; + } + continue; + } + numtypes++; + } + + tableSize=(resource.size()+numtypes+numPairs)*PE_RESENTRY_SIZE+ + (numtypes+numPairs+1)*PE_RESDIR_SIZE; + dataListSize=resource.size()*PE_RESDATAENTRY_SIZE; + + tablePos=0; + dataListPos=tableSize; + namePos=tableSize+dataListSize; + dataPos=tableSize+nameSize+dataListSize+3; + dataPos&=0xfffffffc; + + ressect->length=dataPos+dataSize; + + ressect->data.resize(ressect->length); + + ressect->datmask.resize((ressect->length+7)/8); + + /* empty section to start with */ + for(i=0;ilength;i++) + ressect->data[i]=0; + + /* build master directory */ + /* store time/date of creation */ + k=(UINT)time(NULL); + put32(ressect->data, 4, k); + put32(ressect->data, 12, numnamedtypes); + + tablePos=16+numtypes*PE_RESENTRY_SIZE; + curTypePos=16; + curTypeName=NULL; + curTypeId=-1; + for(i=0;idata, curTypePos, namePos); + curTypeName=&resource[i].xtypename[0]; + k=_wstrlen(curTypeName); + put16(ressect->data, namePos, k); + namePos+=2; + memcpy(&ressect->data[0]+namePos,curTypeName,k*2); + namePos+=k*2; + curTypeId=-1; + } + else + { + curTypeName=NULL; + curTypeId=resource[i].typeid; + put32(ressect->data, curTypePos, curTypeId); + } + put32(ressect->data, curTypePos+4, tablePos); + + numnames=numids=0; + for(j=i;ji) && (_wstricmp(&resource[j].name[0],&resource[j-1].name[0])!=0)) + || (j==i)) + numnames++; + } + else + { + if(((j>i) && (resource[j-1].name.size() || (resource[j].id!=resource[j-1].id))) + || (j==i)) + numids++; + } + } + /* store time/date of creation */ + k=(UINT)time(NULL); + put32(ressect->data, tablePos+4, k); + put16(ressect->data, tablePos+12, numnames); + put16(ressect->data, tablePos+14, numids); + + curNamePos=tablePos+PE_RESDIR_SIZE; + curName=NULL; + curId=-1; + tablePos+=PE_RESDIR_SIZE+(numids+numnames)*PE_RESENTRY_SIZE; + curTypePos+=PE_RESENTRY_SIZE; + } + if(!(resource[i].name.size() && curName && + !_wstricmp(&resource[i].name[0],curName)) + && !(!resource[i].name.size() && !curName && curId==resource[i].id)) + { + if(resource[i].name.size()) + { + put32(ressect->data, curNamePos, namePos); + curName=&resource[i].name[0]; + k=_wstrlen(curName); + put16(ressect->data, namePos, k); + namePos+=2; + memcpy(&ressect->data[0]+namePos,curName,k*2); + namePos+=k*2; + curId=-1; + } + else + { + curName=NULL; + curId=resource[i].id; + put32(ressect->data, curNamePos, curId); + } + put32(ressect->data, curNamePos+4, 0x80000000 | tablePos); + + numids=0; + for(j=i;jdata, tablePos+4, k); + put16(ressect->data, tablePos+12, numnames); + put16(ressect->data, tablePos+14, numids); + + curLangPos=tablePos+PE_RESDIR_SIZE; + tablePos+=PE_RESDIR_SIZE+numids*PE_RESENTRY_SIZE; + curNamePos+=PE_RESENTRY_SIZE; + } + put32(ressect->data, curLangPos, resource[i].languageid); + put32(ressect->data, curLangPos+4, dataListPos); + curLangPos+=PE_RESENTRY_SIZE; + + put32(ressect->data, dataListPos, dataPos+ressect->getbase()); + put32(ressect->data, dataListPos+4, resource[i].length); + memcpy(&ressect->data[0]+dataPos,&resource[i].data[0],resource[i].length); + dataPos+=resource[i].length+3; + dataPos&=0xfffffffc; + dataListPos+=PE_RESDATAENTRY_SIZE; + } + + /* mark whole section as required output */ + for(i=0;i<(ressect->length+7)/8;i++) + ressect->datmask[i]=0xff; + + /* update object table */ + ressect->setbase(ressect->getbase()+imageBase); + + k=ressect->length; + k+=objectAlign-1; + k&=(0xffffffff-(objectAlign-1)); + ressect->virtualSize=k; + put32(objectTable, 8, k); /* store virtual size (in memory) of segment */ + k=ressect->length; + put32(objectTable, 16, k); /* store initialised data size */ + return; +} + +void getStub(PUCHAR *pstubData,UINT *pstubSize) +{ + FILE *f; + unsigned char headbuf[0x1c]; + std::vector buf; + UINT imageSize; + UINT headerSize; + UINT relocSize; + UINT relocStart; + int i; + + if(stubName != "") + { + f=fopen((char *)stubName.c_str(),"rb"); + if(!f) + { + printf("Unable to open stub file %s\n",stubName.c_str()); + exit(1); + } + if(fread(headbuf,1,0x1c,f)!=0x1c) /* try and read 0x1c bytes */ + { + printf("Error reading from file %s\n",stubName.c_str()); + exit(1); + } + if((headbuf[0]!=0x4d) || (headbuf[1]!=0x5a)) + { + printf("Stub not valid EXE file\n"); + exit(1); + } + /* get size of image */ + imageSize=headbuf[2]+(headbuf[3]<<8)+((headbuf[4]+(headbuf[5]<<8))<<9); + if(imageSize%512) imageSize-=512; + headerSize=(headbuf[8]+(headbuf[9]<<8))<<4; + relocSize=(headbuf[6]+(headbuf[7]<<8))<<2; + imageSize-=headerSize; + printf("imageSize=%i\n",imageSize); + printf("header=%i\n",headerSize); + printf("reloc=%i\n",relocSize); + + /* allocate buffer for load image */ + buf.resize(imageSize+0x40+((relocSize+0xf)&0xfffffff0)); + /* copy header */ + for(i=0;i<0x1c;i++) buf[i]=headbuf[i]; + + relocStart=headbuf[0x18]+(headbuf[0x19]<<8); + /* load relocs */ + fseek(f,relocStart,SEEK_SET); + if(fread(&buf[0x40],1,relocSize,f)!=relocSize) + { + printf("Error reading from file %s\n",stubName.c_str()); + exit(1); + } + + /* paragraph align reloc size */ + relocSize+=0xf; + relocSize&=0xfffffff0; + + /* move to start of data */ + fseek(f,headerSize,SEEK_SET); + /* new header is 4 paragraphs long + relocSize*/ + relocSize>>=4; + relocSize+=4; + put16(buf, 8, relocSize); + headerSize=relocSize<<4; + /* load data into correct position */ + if(fread(&buf[headerSize],1,imageSize,f)!=imageSize) + { + printf("Error reading from file %s\n",stubName.c_str()); + exit(1); + } + /* relocations start at 0x40 */ + put16(buf, 0x18, 0x40); + imageSize+=headerSize; /* total file size */ + /* store pointer and size */ + (*pstubData)=&buf[0]; + (*pstubSize)=imageSize; + i=imageSize%512; /* size mod 512 */ + imageSize=(imageSize+511)>>9; /* number of 512-byte pages */ + put16(buf, 2, i); + put16(buf, 4, imageSize); + } + else + { + (*pstubData)=defaultStub; + (*pstubSize)=defaultStubSize; + } +} + +void OutputWin32file(const std::string &outname) +{ + long i,j,k; + UINT started; + UINT lastout; + PSEG seg; + std::vector headbuf; + PUCHAR stubData; + FILE*outfile; + UINT headerSize; + UINT headerVirtSize; + UINT stubSize; + long nameIndex; + UINT sectionStart; + UINT headerStart; + long relocSectNum,importSectNum,exportSectNum,resourceSectNum; + long importSectLoc = 0, importSectSize = 0; + long exportSectLoc = 0, exportSectSize = 0; + long resourceSectLoc = 0, resourceSectSize = 0; + long relocSectLoc = 0, relocSectSize = 0; + UINT codeBase=0; + UINT dataBase=0; + UINT codeSize=0; + UINT dataSize=0; + + printf("Generating PE file %s\n",outname.c_str()); + + errcount=0; + + /* allocate section entries for imports, exports and relocs if required */ + if(impsreq) + { + importSectNum=createOutputSection("imports", + WINF_INITDATA | WINF_SHARED | WINF_READABLE); + } + else + { + importSectNum=-1; + } + + if(expdefs.size()) + { + exportSectNum=createOutputSection("exports", + WINF_INITDATA | WINF_SHARED | WINF_READABLE); + } + else + { + exportSectNum=-1; + } + + /* Windows NT requires a reloc section to relocate image files, even */ + /* if it contains no actual fixups */ + relocSectNum=createOutputSection("relocs", + WINF_INITDATA | WINF_SHARED | WINF_DISCARDABLE | WINF_READABLE); + + if(resource.size()) + { + resourceSectNum=createOutputSection("resource", + WINF_INITDATA | WINF_SHARED | WINF_READABLE); + } + else + { + resourceSectNum=-1; + } + + /* build header */ + getStub(&stubData,&stubSize); + + headerStart=stubSize; /* get start of PE header */ + headerStart+=7; + headerStart&=0xfffffff8; /* align PE header to 8 byte boundary */ + + headerSize=PE_HEADBUF_SIZE+outlist.size()*PE_OBJECTENTRY_SIZE+stubSize; + headerVirtSize=headerSize+(objectAlign-1); + headerVirtSize&=(0xffffffff-(objectAlign-1)); + headerSize+=(fileAlign-1); + headerSize&=(0xffffffff-(fileAlign-1)); + + + headbuf.resize(headerSize); + + for(i=0;iname; + if(name.size() > 8) name = name.substr(0,8); + + if(name.size()) + { + strncpy((char *)&headbuf[j],name.c_str(),name.size()); + } + k=outlist[i]->virtualSize; /* get virtual size */ + put32(headbuf, j+8, k); /* store virtual size (in memory) of segment */ + + if(!padsegments) /* if not padding segments, reduce space consumption */ + { + for(k=outlist[i]->length-1;(k>=0)&&!GetNbit(outlist[i]->datmask,k);k--); + k++; /* k=initialised length */ + } + put32(headbuf, j+16, k); /* store initialised data size */ + put32(headbuf, j+20, sectionStart); /* store physical file offset */ + + k+=fileAlign-1; + k&=(0xffffffff-(fileAlign-1)); /* aligned initialised length */ + + sectionStart+=k; /* update section start address for next section */ + + outlist[i]->setbase(outlist[i]->getbase()+headerVirtSize+imageBase); + put32(headbuf, j+12, outlist[i]->getbase()-imageBase); + k=(outlist[i]->winFlags ^ WINF_NEG_FLAGS) & WINF_IMAGE_FLAGS; /* get characteristice for section */ + put32(headbuf, j+36, k); /* store characteristics */ + } + + put16(headbuf, headerStart+PE_NUMOBJECTS, outlist.size()); /* store number of sections */ + + /* build import, export and relocation sections */ + + BuildPEImports(importSectNum,&headbuf[headerStart+PE_HEADBUF_SIZE]); + BuildPEExports(exportSectNum,&headbuf[headerStart+PE_HEADBUF_SIZE],(unsigned char *)outname.c_str()); + BuildPERelocs(relocSectNum,&headbuf[headerStart+PE_HEADBUF_SIZE]); + BuildPEResources(resourceSectNum,&headbuf[headerStart+PE_HEADBUF_SIZE]); + +#if 0 + for(k=headerStart+PE_HEADBUF_SIZE;k=32) && (headbuf[k]<128) ? headbuf[k] : '.'); + } + printf("\n"); + } +#endif + + if(errcount) + { + exit(1); + } + + /* get start address */ + if(gotstart) + { + GetFixupTarget(&startaddr,&seg,&startaddr.ofs,TRUE); + if(errcount) + { + printf("Invalid start address record\n"); + exit(1); + } + i=startaddr.ofs; + i-=imageBase; /* RVA */ + put32(headbuf, headerStart + PE_ENTRYPOINT, i); + if(buildDll) /* if library */ + { + /* flag that entry point should always be called */ + put16(headbuf, headerStart+PE_DLLFLAGS, 15); + } + } + else + { + printf("Warning, no entry point specified\n"); + } + + if(importSectNum>=0) /* if imports, add section entry */ + { + importSectLoc = outlist[importSectNum]->getbase()-imageBase; + importSectSize = outlist[importSectNum]->length; + } + else + { + for(i = 0; i < seglist.size(); i++) + { + if(seglist[i]) + { + if(seglist[i]->name == ".idata") + { + importSectLoc = seglist[i]->getbase() - imageBase; + importSectSize = seglist[i]->length; + } + } + } + } + + printf("importSectLoc %x importSectSize %x\n", + importSectLoc, importSectSize); + + if(importSectLoc) /* if imports, add section entry */ + { + put32(headbuf, headerStart + PE_IMPORTRVA, importSectLoc); + put32(headbuf, headerStart + PE_IMPORTSIZE, importSectSize); + } + + if(exportSectNum>=0) /* if exports, add section entry */ + { + exportSectLoc = outlist[exportSectNum]->getbase()-imageBase; + exportSectSize = outlist[exportSectNum]->length; + } + else + { + for(i = 0; i < seglist.size() && seglist[i]; i++) + { + if(seglist[i]->name == ".edata") + { + exportSectLoc = seglist[i]->getbase() - imageBase; + exportSectSize = seglist[i]->length; + } + } + } + + printf("exportSectLoc %x exportSectSize %x\n", + exportSectLoc, exportSectSize); + + if(exportSectLoc) + { + put32(headbuf, headerStart+PE_EXPORTRVA, exportSectLoc); + put32(headbuf, headerStart+PE_EXPORTSIZE, exportSectSize); + } + + if(relocSectNum>=0) /* if relocs, add section entry */ + { + relocSectLoc = outlist[relocSectNum]->getbase()-imageBase; + relocSectSize = outlist[relocSectNum]->length; + } + else + { + for(i = 0; i < seglist.size() && seglist[i]; i++) + { + if(seglist[i]->name == "relocs") + { + relocSectLoc = seglist[i]->getbase() - imageBase; + relocSectSize = seglist[i]->length; + } + } + } + + printf("relocSectLoc %x relocSectSize %x\n", + relocSectLoc, relocSectSize); + + if(relocSectLoc) /* if relocs, add section entry */ + { + put32(headbuf, headerStart + PE_FIXUPRVA, relocSectLoc); + put32(headbuf, headerStart + PE_FIXUPSIZE, relocSectSize); + } + + if(resourceSectNum>=0) /* if resources, add section entry */ + { + resourceSectLoc = outlist[resourceSectNum]->getbase()-imageBase; + resourceSectSize = outlist[resourceSectNum]->length; + } + else + { + for(i = 0; i < seglist.size() && seglist[i]; i++) + { + if(seglist[i]->name == ".rsrc") + { + resourceSectLoc = seglist[i]->getbase() - imageBase; + resourceSectSize = seglist[i]->length; + } + } + } + + printf("resourceSectLoc %x resourceSectSize %x\n", + resourceSectLoc, resourceSectSize); + + if(resourceSectLoc) /* if relocs, add section entry */ + { + put32(headbuf, headerStart + PE_RESOURCERVA, resourceSectLoc); + put32(headbuf, headerStart + PE_RESOURCESIZE, resourceSectSize); + } + + j=headerStart+PE_HEADBUF_SIZE+(outlist.size()-1)*PE_OBJECTENTRY_SIZE; + + i = get32(headbuf, j+12); + i+= get32(headbuf, j+8); /* add virtual size of section */ + + put32(headbuf, headerStart + PE_IMAGESIZE, i); + put32(headbuf, headerStart + PE_CODEBASE, codeBase); + put32(headbuf, headerStart + PE_DATABASE, dataBase); + put32(headbuf, headerStart + PE_CODESIZE, codeSize); + put32(headbuf, headerStart + PE_INITDATASIZE, dataSize); + + /* zero out section start for all zero-length segments */ + j=headerStart+PE_HEADBUF_SIZE; + for(i=0;iattr&SEG_ALIGN) !=SEG_ABS)) + { + /* ensure section is aligned to file-Align */ + while(ftell(outfile)&(fileAlign-1)) + { + fputc(0,outfile); + } + if(started>outlist[i]->getbase()) + { + printf("Segment overlap\n"); + printf("Next addr=%08X,base=%08X\n",started,outlist[i]->getbase()); + fclose(outfile); + exit(1); + } + if(padsegments) + { + while(startedgetbase()) + { + fputc(0,outfile); + started++; + } + } + else + { + started=outlist[i]->getbase(); + } + for(j=0;jlength;j++) + { + if(GetNbit(outlist[i]->datmask,j)) + { + for(;lastoutdata[j],outfile); + lastout=started+1; + } + else if(padsegments) + { + fputc(0,outfile); + lastout=started+1; + } + started++; + } + started=lastout=outlist[i]->getbase()+outlist[i]->virtualSize; + } + } + + fclose(outfile); +} + diff --git a/reactos/tools/ppc-build/alink/readme.txt b/reactos/tools/ppc-build/alink/readme.txt new file mode 100644 index 00000000000..933ad904996 --- /dev/null +++ b/reactos/tools/ppc-build/alink/readme.txt @@ -0,0 +1,10 @@ +What's here as been modified for use with a PowerPC elf toolchain, but retains +every original feature for x86 as well. + +General modifications: + +- Addition of elf32 input support +- PowerPC and x86 relocation types for elf +- Small bugfixes + +elf.c is based on coff.c, modified to deal with elf sections, symbols etc. diff --git a/reactos/tools/ppc-build/alink/tests/test.c b/reactos/tools/ppc-build/alink/tests/test.c new file mode 100644 index 00000000000..76e8197013a --- /dev/null +++ b/reactos/tools/ppc-build/alink/tests/test.c @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/reactos/tools/ppc-build/alink/tests/test.obj b/reactos/tools/ppc-build/alink/tests/test.obj new file mode 100644 index 0000000000000000000000000000000000000000..aeadb144d7bb3c987a55f936fd64aec4f367227b GIT binary patch literal 456 zcmeys$jl&ibcOR91_lNmAZB1_VAM+~N=+^)O9gX*gc=a{z&J3POMpSIB(?^v#n;#ZBmz^ z=|zdT3Pq`frI|&k#R}n>dB#S(Tq@Yi3vgv%_`t}_u%UB}Gfe&g0}~@R$Wb_f0|SEq zP?8DmT%h}*04N0#2LT8LR0vWFBEU490tpfZ1`G^5gjJEOLa!vXq6DN1>=1; + } + return count; +} + +void ReportError(long errnum) +{ + UINT tot,i; + + printf("\nError in file at %08lX",filepos); + switch(errnum) + { + case ERR_EXTRA_DATA: + printf(" - extra data in record\n"); + break; + case ERR_NO_HEADER: + printf(" - no header record\n"); + break; + case ERR_NO_RECDATA: + printf(" - record data not present\n"); + break; + case ERR_NO_MEM: + printf(" - insufficient memory\n"); + break; + case ERR_INV_DATA: + printf(" - invalid data address\n"); + break; + case ERR_INV_SEG: + printf(" - invalid segment number\n"); + break; + case ERR_BAD_FIXUP: + printf(" - invalid fixup record\n"); + break; + case ERR_BAD_SEGDEF: + printf(" - invalid segment definition record\n"); + break; + case ERR_ABS_SEG: + printf(" - data emitted to absolute segment\n"); + break; + case ERR_DUP_PUBLIC: + printf(" - duplicate public definition\n"); + break; + case ERR_NO_MODEND: + printf(" - unexpected end of file (no MODEND record)\n"); + break; + case ERR_EXTRA_HEADER: + printf(" - duplicate module header\n"); + break; + case ERR_UNKNOWN_RECTYPE: + printf(" - unknown object module record type %02X\n",rectype); + break; + case ERR_SEG_TOO_LARGE: + printf(" - 4Gb Non-Absolute segments not supported.\n"); + break; + case ERR_MULTIPLE_STARTS: + printf(" - start address defined in more than one module.\n"); + break; + case ERR_BAD_GRPDEF: + printf(" - illegal group definition\n"); + break; + case ERR_OVERWRITE: + printf(" - overlapping data regions\n"); + break; + case ERR_INVALID_COMENT: + printf(" - COMENT record format invalid\n"); + break; + case ERR_ILLEGAL_IMPORTS: + printf(" - Imports required to link, and not supported by output file type\n"); + break; + default: + printf("\n"); + } + printf("seg count = %i\n",seglist.size()); + printf("extcount=%i\n",externs.size()); + printf("grpcount=%i\n",grplist.size()); + printf("comcount=%i\n",comdefs.size()); + printf("fixcount=%i\n",relocs.size()); + printf("impcount=%i\n",impdefs.size()); + printf("expcount=%i\n",expdefs.size()); + printf("modcount=%i\n",modname.size()); + + for(i=0,tot=0;idata.size()) + tot+=seglist[i]->length; + } + printf("total segment size=%08X\n",tot); + + exit(1); +} + +unsigned short wtoupper(unsigned short a) +{ + if(a>=256) return a; + return toupper(a); +} + +int wstricmp(const char *s1,const char *s2) +{ + int i=0; + unsigned short a,b; + + while(TRUE) + { + a=s1[i]+(s1[i+1]<<8); + b=s2[i]+(s2[i+1]<<8); + if(wtoupper(a)wtoupper(b)) return +1; + if(!a) return 0; + i+=2; + } +} + +int wstrlen(const char *s) +{ + int i; + for(i=0;s[i]||s[i+1];i+=2); + return i/2; +} + +void *checkMalloc(size_t x) +{ + void *p; + + p=malloc(x); + if(!p) + { + fprintf(stderr,"Error, Insufficient memory in call to malloc\n"); + exit(1); + } + return p; +} + +void *checkRealloc(void *p,size_t x) +{ + p=realloc(p,x); + if(!p) + { + fprintf(stderr,"Error, Insufficient memory in call to realloc\n"); + exit(1); + } + return p; +} + +char *checkStrdup(const char *s) +{ + char *p; + + if(!s) + { + fprintf(stderr,"Error, Taking duplicate of NULL pointer in call to strdup\n"); + exit(1); + } + p=strdup(s); + if(!p) + { + fprintf(stderr,"Error, Insufficient memory in call to strdup\n"); + exit(1); + } + return p; +} + +int _wstricmp(unsigned char *a, unsigned char *b) +{ + uint16_t *a16 = (uint16_t*)a, *b16 = (uint16_t*)b; + while(*a16 && (*a16 == *b16)) { a16++; b16++; } + return (*a16 < *b16) ? ((*a16 > *b16) ? 1 : 0) : -1; +} + +int _wstrlen(unsigned char *a) +{ + uint16_t *a16 = (uint16_t*)a; + while(*a16++); + return a16 - ((uint16_t *)a); +} From 036f2c1f6c6fa4701396748a18ea83aa9a991d6e Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 5 Jan 2007 05:45:52 +0000 Subject: [PATCH 64/81] ldscript used to link reactos ppc executables. svn path=/branches/powerpc/; revision=25301 --- reactos/tools/ppc-build/ldscript | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 reactos/tools/ppc-build/ldscript diff --git a/reactos/tools/ppc-build/ldscript b/reactos/tools/ppc-build/ldscript new file mode 100644 index 00000000000..11fd10be4a8 --- /dev/null +++ b/reactos/tools/ppc-build/ldscript @@ -0,0 +1,62 @@ +/* Default linker script, for normal executables */ +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", + "elf32-powerpc") +OUTPUT_ARCH(powerpc:common) +SECTIONS +{ + .text : + { + __text_start__ = .; + *(.text) + *(init) + *(INIT) + __text_end__ = .; + } + .data : + { + *(.data) + *(.data2) + *(.rdata) + *(.sdata) + *(.pdata) + } + .rodata : + { + *(.rodata) + } + .idata : + { + SORT(*)(.idata$2) + SORT(*)(.idata$3) + LONG(0); LONG(0); LONG(0); LONG(0); LONG(0); + SORT(*)(.idata$4) + SORT(*)(.idata$5) + SORT(*)(.idata$6) + SORT(*)(.idata$7) + } + .edata : + { + *(.edata) + } + .bss : + { + *(.bss) + *(COMMON) + } + .rela.text : + { + *(.rela.text) + } + .rela.data : + { + *(.rela.data) + } + .rela.rodata : + { + *(.rela.rodata) + } + .rela.got2 : + { + *(.rela.got2) + } +} From fb9f4b89c9b250d87e6f7c35c564541719fe2ebe Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 5 Jan 2007 05:50:55 +0000 Subject: [PATCH 65/81] A test to see if things are mostly working. You can build it and then load them on a prep box. You'll see output on the serial port if they linked and bound properly. I have a patch for gxemul that can load pecoff and bind imports, that can be used for this purpose. svn path=/branches/powerpc/; revision=25302 --- reactos/tools/ppc-build/serialtest/makefile | 16 ++++++++ reactos/tools/ppc-build/serialtest/serial.c | 37 +++++++++++++++++++ reactos/tools/ppc-build/serialtest/serial.def | 5 +++ reactos/tools/ppc-build/serialtest/serial.h | 21 +++++++++++ .../tools/ppc-build/serialtest/serialtest.c | 17 +++++++++ 5 files changed, 96 insertions(+) create mode 100644 reactos/tools/ppc-build/serialtest/makefile create mode 100644 reactos/tools/ppc-build/serialtest/serial.c create mode 100644 reactos/tools/ppc-build/serialtest/serial.def create mode 100644 reactos/tools/ppc-build/serialtest/serial.h create mode 100644 reactos/tools/ppc-build/serialtest/serialtest.c diff --git a/reactos/tools/ppc-build/serialtest/makefile b/reactos/tools/ppc-build/serialtest/makefile new file mode 100644 index 00000000000..ae37d6d326c --- /dev/null +++ b/reactos/tools/ppc-build/serialtest/makefile @@ -0,0 +1,16 @@ +all: serialtest.exe serial.dll + +libserial.a serial.exp: + reactos-powerpc-dlltool -D serial.dll -e serial.exp -l libserial.a -d serial.def -k -A -S reactos-powerpc-as -L reactos-powerpc-ld + +serialtest.exe: serial.h serialtest.c libserial.a + reactos-powerpc-gcc -Wl,--image-base=0x400000 -Wl,--entry,main -nostdlib -nostartfiles -o $@ serialtest.c -L. -lserial + +serial.dll: serial.o serial.exp + reactos-powerpc-gcc -Wl,--image-base=0x600000 -Wl,--entry,sync -nostdlib -nostartfiles -shared -o $@ serial.o serial.exp + +serial.o: serial.c + reactos-powerpc-gcc -c $< + +clean: + rm -rf *.o *.a *.exp *.dll diff --git a/reactos/tools/ppc-build/serialtest/serial.c b/reactos/tools/ppc-build/serialtest/serial.c new file mode 100644 index 00000000000..1e4211ab594 --- /dev/null +++ b/reactos/tools/ppc-build/serialtest/serial.c @@ -0,0 +1,37 @@ +#include "serial.h" + +void sync() { + __asm__("eieio\n\t" + "sync"); +} + +void send(char *serport, char c) { + /* Wait for Clear to Send */ + while( !(serport[LSR] & 0x20) ) sync(); + + serport[THR] = c; + sync(); +} + +char recv(char *serport) { + char c; + + while( !(serport[LSR] & 1) ) sync(); + + c = serport[RCV]; + sync(); +} + +void setup(char *serport, int baud) { + int x = 115200 / baud; + serport[LCR] = 128; + sync(); + serport[BAUDLOW] = x & 255; + sync(); + serport[BAUDHIGH] = x >> 8; + sync(); + serport[LCR] = 3; + sync(); + serport[IER] = 0; + sync(); +} diff --git a/reactos/tools/ppc-build/serialtest/serial.def b/reactos/tools/ppc-build/serialtest/serial.def new file mode 100644 index 00000000000..ed7443d15ff --- /dev/null +++ b/reactos/tools/ppc-build/serialtest/serial.def @@ -0,0 +1,5 @@ +LIBRARY SERIAL.DLL +EXPORTS +setup@8 +send@8 +recv@4 diff --git a/reactos/tools/ppc-build/serialtest/serial.h b/reactos/tools/ppc-build/serialtest/serial.h new file mode 100644 index 00000000000..b589ea0aa57 --- /dev/null +++ b/reactos/tools/ppc-build/serialtest/serial.h @@ -0,0 +1,21 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#define RCV 0 +#define THR 0 +#define BAUDLOW 0 +#define BAUDHIGH 1 +#define IER 1 +#define FCR 2 +#define ISR 2 +#define LCR 3 +#define MCR 4 +#define LSR 5 +#define MSR 6 +#define SPR 7 + +extern void send(char *serport, char c); +extern char recv(char *serport); +extern void setup(char *serport, int baud); + +#endif//SERIAL_H diff --git a/reactos/tools/ppc-build/serialtest/serialtest.c b/reactos/tools/ppc-build/serialtest/serialtest.c new file mode 100644 index 00000000000..dd3f2708c56 --- /dev/null +++ b/reactos/tools/ppc-build/serialtest/serialtest.c @@ -0,0 +1,17 @@ +#include "serial.h" + +int main() { + int i; + char *iobase = (char *)0x80000000; + char *serport = iobase + 0x3f8; + + setup( serport, 9600 ); + + for( i = ' '; i <= '~'; i++ ) { + send(serport, i); + } + send(serport, 0xa); + + return 0; +} + From 81a8d71a9d71042f5195df29d37d4ec4ba913c08 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 5 Jan 2007 05:56:26 +0000 Subject: [PATCH 66/81] Compiler driver wrapper for building pe-powerpcle executables. Expects access to a powerpc gcc and ld, as well as alink. The scripts in here are transformed by sed ala GNU configure. fork_win32 and fork_unix provide a uniform way of calling an external program and reading stderr. dlltool.cpp is a minimalist what-if about replacing binutils' dlltool. It's not used by might be instructive. svn path=/branches/powerpc/; revision=25303 --- .../ppc-build/compdvr/compdvr-dlltool.in | 7 + .../tools/ppc-build/compdvr/compdvr-gcc.in | 60 ++ reactos/tools/ppc-build/compdvr/compdvr-ld.in | 30 + .../ppc-build/compdvr/compdvr-windres.in | 7 + reactos/tools/ppc-build/compdvr/compdvr.cpp | 363 +++++++++++ reactos/tools/ppc-build/compdvr/dlltool.cpp | 566 ++++++++++++++++++ reactos/tools/ppc-build/compdvr/fork_execvp.h | 28 + reactos/tools/ppc-build/compdvr/fork_unix.cpp | 66 ++ .../tools/ppc-build/compdvr/fork_win32.cpp | 109 ++++ 9 files changed, 1236 insertions(+) create mode 100755 reactos/tools/ppc-build/compdvr/compdvr-dlltool.in create mode 100644 reactos/tools/ppc-build/compdvr/compdvr-gcc.in create mode 100644 reactos/tools/ppc-build/compdvr/compdvr-ld.in create mode 100644 reactos/tools/ppc-build/compdvr/compdvr-windres.in create mode 100644 reactos/tools/ppc-build/compdvr/compdvr.cpp create mode 100644 reactos/tools/ppc-build/compdvr/dlltool.cpp create mode 100755 reactos/tools/ppc-build/compdvr/fork_execvp.h create mode 100755 reactos/tools/ppc-build/compdvr/fork_unix.cpp create mode 100755 reactos/tools/ppc-build/compdvr/fork_win32.cpp diff --git a/reactos/tools/ppc-build/compdvr/compdvr-dlltool.in b/reactos/tools/ppc-build/compdvr/compdvr-dlltool.in new file mode 100755 index 00000000000..b81b97270c9 --- /dev/null +++ b/reactos/tools/ppc-build/compdvr/compdvr-dlltool.in @@ -0,0 +1,7 @@ +#!/bin/sh + +DIR=@PREFIX@ +BPREFIX=@BPREFIX@ +TARGET=@TARGET@ + +${BPREFIX}dlltool -S $DIR/bin/${TARGET}as -L $DIR/bin/${TARGET}ld $* diff --git a/reactos/tools/ppc-build/compdvr/compdvr-gcc.in b/reactos/tools/ppc-build/compdvr/compdvr-gcc.in new file mode 100644 index 00000000000..0506084de3a --- /dev/null +++ b/reactos/tools/ppc-build/compdvr/compdvr-gcc.in @@ -0,0 +1,60 @@ +#!/bin/sh + +DIR=@PREFIX@ +CPREFIX=@CPREFIX@ +TARGET=@TARGET@ + +if [ "x$*" = "x-v" ] ; then + exec ${CPREFIX}gcc -v +fi + +includes="-isystem $DIR/lib/mingw-crt-headers -isystem $DIR/lib/gcc-core-headers" + +argstr="" +for arg in $* ; do + if [ x"$arg" = x-mingw ] ; then + argstr="$argstr -isystem $DIR/lib/windows-headers" + else + argstr="$argstr $arg" + fi +done + +TEMP=`mktemp -d` +export TEMP +if [ ! -d $TEMP ] ; then + echo "Could not make temp dir $TEMP" + exit 1 +fi +TMP=$TEMP + +`dirname $0`/${TARGET}driver-gcc \ + -mlittle \ + -nostdinc \ + -D__cdecl__= \ + -D__stdcall__= \ + -D__fastcall__= \ + -D__declspec\(x\)= \ + -D__cdecl= \ + -D__stdcall= \ + -D__fastcall= \ + -Dcdecl= \ + -Dstdcall= \ + -Dfastcall= \ + -Ddllimport= \ + -Ddllexport= \ + -Du_short=unsigned\ short \ + -Du_long=unsigned\ long \ + -Du_int=unsigned\ int \ + -Du_char=unsigned\ char \ + -ldscript ${DIR}/lib/ldscript \ + -gcc-name ${CPREFIX}gcc \ + -link-stage-name ${DIR}/bin/${TARGET}ld \ + -extra-link-stage $DIR/bin/alink.exe \ + -mingw-lib-dir $DIR/lib \ + $includes \ + $argstr +#include +#include +#include +#include +#include +#include +#include +#include +#include "fork_execvp.h" + +/* tool for transforming gcc -### output and using it to drive the compiler + * elements ourselves. Most importantly, we need to know what file gcc asks + * the linker to input and output, and add an intermediate stage with alink. + */ + +typedef enum { empty, found_q, found_bs } break_t; + +template +T break_arguments( const std::string &line ) { + break_t state = empty; + T args; + std::string arg; + + for( size_t i = 0; i < line.size(); i++ ) { + switch( state ) { + case empty: + if( line[i] == '\"' ) { + state = found_q; + } + break; + + case found_q: + if( line[i] == '\\' ) state = found_bs; + else if( line[i] == '\"' ) { + state = empty; + args.push_back(arg); + arg = ""; + } else arg += line[i]; + break; + + case found_bs: + state = found_q; + arg += line[i]; + break; + } + } + + return args; +} + +template +std::vector get_arg_ptrs +( const T &arg_strings ) { + std::vector arg_out; + for( size_t i = 0; i < arg_strings.size(); i++ ) + arg_out.push_back( (char *)arg_strings[i].c_str() ); + arg_out.push_back(0); + return arg_out; +} + +int execute_command( bool verbose, const std::vector &args ) { + std::string error; + std::vector args_ptrs; + const char *tag = "executable"; + + if( verbose ) { + fprintf( stderr, "\n" ); + for( size_t i = 0; i < args.size(); i++ ) { + fprintf( stderr, "<%s>%s\n", tag, args[i].c_str(), tag ); + tag = "argument"; + } + } + + Process p = fork_execvp( args ); + + while( p && p->ProcessStarted() && !p->EndOfStream() ) + fprintf( stderr, "%s", p->ReadStdError().c_str() ); + + if( verbose ) { + fprintf( stderr, "%d\n", p->GetStatus() ); + fprintf( stderr, "\n" ); + } + + return p ? p->GetStatus() : -1; +} + +std::string make_tmp_name() { + int fd; + std::string name; + + while( true ) { + name = tmpnam(NULL); + name += ".obj"; + if( (fd = creat( name.c_str(), 0644 )) != -1 ) { + close(fd); + return name; + } + } +} + +void recognize_arg( std::vector &args, + std::string &result, + size_t &i, + const std::string &argname, + const std::string &short_argname = "" ) { + if( (short_argname.size() && (args[i] == short_argname)) || + (args[i] == argname) ) { + result = args[i+1]; + args.erase(args.begin()+i); + args.erase(args.begin()+i--); + } else if( args[i].substr(0,argname.size()+1) == argname + "=" ) { + result = args[i].substr(argname.size()+1); + args.erase(args.begin()+i--); + } +} + +int run_ld( bool verbose, bool nostdlib, bool nostartfiles, bool is_dll, + bool make_map, + const std::string &lib_dir, + const std::string &extra_linker_stage, + const std::string &ldscript, + const std::vector &arg_vect ) { + bool use_libgcc = false; + std::vector args = arg_vect; + std::string temp_name = make_tmp_name(), real_output, + entry_point, image_base, subsystem = "windows", + make_dll, file_align, section_align, base_file; + std::vector::iterator i = + std::find(args.begin(),args.end(),"-lgcc"); + + if( i != args.end() ) { + args.erase( i ); + use_libgcc = true; + } + + if( !nostartfiles ) { + if( make_dll.size() ) + args.push_back(lib_dir + "/dllcrt2.o"); + else + args.push_back(lib_dir + "/crt2.o"); + } + + if( !nostdlib ) { + args.push_back(std::string("-L") + lib_dir); + args.push_back("-lkernel32"); + args.push_back("-lmsvcrt"); + args.push_back("-lcrtdll"); + args.push_back("-lmingw32"); + } + if( use_libgcc ) + args.push_back(lib_dir + "/libgcc.a"); + + if( verbose ) + args.insert(args.begin()+1,"-v"); + + args.insert(args.begin()+1,"-T"); + args.insert(args.begin()+2,ldscript); + args.insert(args.begin()+1,"-r"); + args.insert(args.begin()+1,"--start-group"); + args.push_back("--end-group"); + + for( size_t i = 0; i < args.size(); i++ ) { + if( args[i] == "-o" && i < args.size()-1 ) { + real_output = args[++i]; + args[i] = temp_name; + } else if( args[i].substr(0,4) == "-mdll" ) { + args.erase(args.begin()+i--); + make_dll = "-dll"; + } + + recognize_arg( args, entry_point, i, "--entry", "-e" ); + recognize_arg( args, image_base, i, "--image-base" ); + recognize_arg( args, subsystem, i, "--subsystem" ); + recognize_arg( args, file_align, i, "--file-alignment" ); + recognize_arg( args, section_align, i, "--section-alignment" ); + recognize_arg( args, base_file, i, "--base-file" ); + } + + if( execute_command( verbose, args ) ) + return 1; + + if( base_file.size() ) { + FILE *f = fopen(base_file.c_str(), "wb"); + if( !f ) { + fprintf(stderr, "\n"); + perror(base_file.c_str()); + fprintf(stderr, "\n"); + return 1; + } + fclose(f); + } + + args.clear(); + args.push_back( extra_linker_stage ); + if(make_map) + args.push_back("-m+"); + args.push_back( "-oPE" ); + args.push_back( "-o" ); + args.push_back( real_output ); + args.push_back( "-subsys" ); + args.push_back( subsystem ); + + if( entry_point.size() ) { + size_t at = 0; + args.push_back("-entry"); + // Entry points will be specified with leading '_', probably + if( entry_point[0] == '_' ) + entry_point = entry_point.substr(1); + at = entry_point.find('@'); + if( at != std::string::npos ) + entry_point = entry_point.substr(0,at); + args.push_back(entry_point); + } + + if( image_base.size() ) { + args.push_back("-base"); + args.push_back(image_base); + } + + if( file_align.size() ) { + args.push_back("-filealign"); + args.push_back(file_align); + } + + if( section_align.size() ) { + args.push_back("-objectalign"); + args.push_back(section_align); + } + + if( make_dll.size() ) { + args.push_back(make_dll); + } + + if( real_output.size() ) { + args.push_back( temp_name ); + int res = execute_command( verbose, args ); + unlink( temp_name.c_str() ); + return res; + } else return 0; +} + +int main( int argc, char **argv ) { + bool verbose = false, ld_mode = false, nostdlib = false, + nostartfiles = false, is_dll = false, make_map = false; + int err_fd[2], read_len, child_pid_gcc, child_pid_command, status = 0; + std::string gcc_name, gcc_hash_output, gcc_line, linker_name = "ld", + mingw_lib_dir, ldscript; + std::string extra_linker_stage; + std::vector gcc_args_str, + subcmd_args; + std::vector arguments_for_gcc; + char buf[1024]; + + for( int i = 1; i < argc; i++ ) { + if( std::string("-gcc-name") == argv[i] && i < argc-1 ) { + gcc_name = argv[++i]; + } else if( std::string("-ldscript") == argv[i] && i < argc-1 ) { + ldscript = argv[++i]; + } else if( std::string("-link-stage-name") == argv[i] && i < argc-1 ) { + linker_name = argv[++i]; + } else if( std::string("-extra-link-stage") == argv[i] && i < argc-1 ) { + extra_linker_stage = argv[++i]; + } else if( std::string("-mingw-lib-dir") == argv[i] && i < argc-1 ) { + mingw_lib_dir = argv[++i]; + } else if( std::string("-v") == argv[i] ) { + verbose = true; + } else if( std::string("-pipe") == argv[i] ) { + /* ignore */ + } else if( std::string("-T") == argv[i] ) { + /* ignore */ + i++; + } else if( std::string("-nostdlib") == argv[i] ) { + nostdlib = true; + } else if( std::string("-nostartfiles") == argv[i] ) { + nostartfiles = true; + } else if( std::string("-shared") == argv[i] ) { + is_dll = true; + } else if( std::string("-map") == argv[i] ) { + make_map = true; + } else { + gcc_args_str.push_back(argv[i]); + } + } + + /* We never use the system start files or standard libs */ + gcc_args_str.insert(gcc_args_str.begin()+1,"-nostdlib"); + gcc_args_str.insert(gcc_args_str.begin()+1,"-nostartfiles"); + + if( std::string(argv[0]).find("ld") != std::string::npos ) { + gcc_args_str.insert + ( gcc_args_str.begin(), linker_name ); + return run_ld + ( verbose, nostdlib, nostartfiles, is_dll, make_map, mingw_lib_dir, + extra_linker_stage, ldscript, gcc_args_str ); + } + if( verbose ) fprintf( stderr, "\n" ); + + // Stack on driver name and dump commands flag + gcc_args_str.insert(gcc_args_str.begin(),std::string("-###")); + gcc_args_str.insert(gcc_args_str.begin(),gcc_name); + + /* Redirect stderr to our pipe */ + if( verbose ) { + const char *tag = "executable"; + fprintf( stderr, "\n" ); + for( size_t i = 0; i < gcc_args_str.size(); i++ ) { + fprintf( stderr, " <%s>%s\n", + tag, gcc_args_str[i].c_str(), + tag ); + tag = "arg"; + } + fprintf( stderr, "\n" ); + } + + Process p = fork_execvp( gcc_args_str ); + + while( p && p->ProcessStarted() && !p->EndOfStream() ) + gcc_hash_output += p->ReadStdError(); + + std::istringstream iss( gcc_hash_output ); + + if( p->GetStatus() ) goto final; + + while( std::getline( iss, gcc_line, '\n' ) ) { + // command line + if( gcc_line.size() > 2 && gcc_line[0] == ' ' ) { + subcmd_args = + break_arguments >( gcc_line ); + + if( subcmd_args.size() < 1 ) continue; + + if( subcmd_args[0].find("collect2") != std::string::npos || + subcmd_args[0].find("ld") != std::string::npos ) { + if( run_ld( verbose, nostdlib, nostartfiles, is_dll, make_map, + mingw_lib_dir, extra_linker_stage, ldscript, + subcmd_args ) ) + goto final; + else + continue; + } + + if( verbose ) + subcmd_args.insert(subcmd_args.begin()+1,"-v"); + + if( execute_command + ( verbose, subcmd_args ) ) + goto final; + } else if( verbose ) + fprintf( stderr, "%s\n", gcc_line.c_str() ); + } + goto theend; + + final: + status = 1; + + theend: + if( verbose ) { + fprintf( stderr, "%d\n", status ); + fprintf( stderr, "\n" ); + } + return status; +} diff --git a/reactos/tools/ppc-build/compdvr/dlltool.cpp b/reactos/tools/ppc-build/compdvr/dlltool.cpp new file mode 100644 index 00000000000..572d579c392 --- /dev/null +++ b/reactos/tools/ppc-build/compdvr/dlltool.cpp @@ -0,0 +1,566 @@ +#include +#include +#include +#include +#include +#include +#include + +/* + * .idata$2_liba_dll # liba import directory + * __dll_liba_import_directory: + * .rva __dll_tail + * .long 0 + * .long 0 + * .rva __liba_dll_name + * .rva __liba_dll_fthunk + * .idata$2_libb_dll # libb import directory + * __dll_libb_import_directory: + * 20 bytes ... + * .idata$3 # Zero entry + * __dll_tail: + * 20 zeroes ... + * .idata$4_liba_dll # Import Lookup Table + * __dll_liba_ilt: + * .idata$4_liba_fun1_ilt + * __dll_liba_fun1_ilt: + * .rva __dll_liba_fun1_hint + * .idata$4_liba_fun2_ilt + * __dll_libb_fun2_ilt: + * .rva __dll_liba_fun1_hint + * .idata$4_libb_dll # Import Lookup Table + * .idata$5_libb_fun1_ilt + * .idata$5_libb_fun2_ilt + * .idata$5_liba_dll # Import Address Table + * .idata$5_liba_fun1_iat + * __dll_liba_fun1_ia: + * .long 0 + * .idata$5_liba_fun2_iat + * .idata$5_libb_dll # Import Address Table + * .idata$5_libb_fun1_iat + * .idata$5_libb_fun2_iat + * .idata$6_liba_dll # Hint Table + * .idata$6_liba_fun1_hint + * .idata$6_liba_fun2_hint + * .idata$6_libb_dll # Hint Table + * .idata$6_liba_fun1_hint + * .idata$6_liba_fun2_hint + * .idata$7_liba_dll # DLL Name + * __liba_dll_name: + * .asciz "liba.dll" + * .idata$7_libb_dll # DLL Name + * __libb_dll_name: + * .asciz "libb.dll" + * + */ + +std::string uppercase( const std::string &mcase ) { + std::string out; + for( std::string::const_iterator i = mcase.begin(); + i != mcase.end(); + i++ ) { + out += toupper(*i); + } + return out; +} + +std::string comment_strip( const std::string &line ) { + size_t s = line.find(';'); + if( s != std::string::npos ) return line.substr(0,s); + else return line; +} + +class DefFile { +public: + class Export { + public: + Export( const std::string &name, const std::string &alias = "", + int ordinal = -1 ) : + name(name), alias_of(alias), ordinal(ordinal) {} + + const std::string &getName() const { return name; } + const std::string &getAliasOf() const { return alias_of; } + int getOrdinal() const { return ordinal; } + + private: + std::string name; + std::string alias_of; + int ordinal; + }; + + DefFile() : ordbase(1), mode(0) { } + + static std::string clean_for_symbol( const std::string &s ) { + std::string out; + + for( size_t i = 0; i < s.size(); i++ ) { + out += isalpha(s[i]) ? s[i] : '_'; + } + + return out; + } + + static std::string section( const std::string &name ) { + return std::string("\t.section\t") + name + "\n"; + } + + static std::string symbol( const std::string &name ) { + return name + ":\n"; + } + + static std::string global( const std::string &name ) { + return std::string("\t.global\t") + name + "\n"; + } + + static std::string global_sym( const std::string &name ) { + return global(name) + symbol(name); + } + + static std::string impsym( const std::string &name, size_t i ) { + std::ostringstream oss; + oss << name << "_" << i; + return oss.str(); + } + + std::string archive_deco( const std::string &sym ) { + return std::string("__dll_archive_") + libsym + "_" + sym; + } + + static std::string rva( const std::string &symbol ) { + return std::string("\t.rva\t") + symbol + "\n"; + } + + std::string common_name( size_t i, const std::string &_name = "" ) const { + size_t at; + std::string name = _name; + + if( !name.size() ) name = exports[i].getName(); + if( !name.size() ) { + std::ostringstream oss; + oss << libsym << "_ordinal_" << i; + return oss.str(); + } + + if( name[0] == '@' ) name = name.substr(1); + at = name.find('@'); + if( at != std::string::npos ) + name = name.substr(0,at); + + return name; + } + + size_t count_names() const { + size_t res = 0; + for( size_t i = 0; i < exports.size(); i++ ) + if( exports[i].getName().size() ) ++res; + return res; + } + + bool parse( int ln, const std::string &line ) { + std::string command; + std::string stripped_line = comment_strip(line); + + std::istringstream iss(stripped_line); + + bool got_word = iss >> command; + + if( uppercase(command) == "LIBRARY" ) { + if( mode ) { + fprintf( stderr, "Got library out of turn on line %d\n", ln ); + return false; + } + mode++; + iss >> libname; + libsym = clean_for_symbol(libname); + import_directory_entry = archive_deco("import_directory_entry"); + import_directory_term = archive_deco("import_directory_term"); + dll_name_text = archive_deco("dll_name"); + original_first_thunk = archive_deco("ofirst_thk"); + original_first_thunk_term = original_first_thunk + "_term"; + first_thunk = archive_deco("first_thk"); + first_thunk_term = first_thunk + "_term"; + import_desc_table = archive_deco("import_desc"); + } else if( uppercase(command) == "EXPORTS" ) { + if( !mode ) { + fprintf( stderr, "Got exports out of turn on line %d\n", ln ); + return false; + } + mode++; + } else if( got_word ) { + size_t equal, at; + std::string name, alias, name_alias, ordinal_maybe; + int ordinal = -1; + + if( mode != 2 ) { + fprintf( stderr, "Got extraneous input on line %d\n", ln ); + return false; + } + + name_alias = command; + if( iss >> ordinal_maybe ) + ordinal = atoi(ordinal_maybe.substr(1).c_str()); + + equal = name_alias.find('='); + if( equal == std::string::npos ) { + name = name_alias; + } else { + name = name_alias.substr(0,equal); + equal++; + alias = name_alias.substr(equal); + } + + if( kill_at ) { + at = name.find('@'); + if( at != std::string::npos ) + name = name.substr(0,at); + at = alias.find('@'); + if( at != std::string::npos ) + alias = alias.substr(0,at); + } + + Export ex(name,alias,ordinal); + + export_byname.insert( std::make_pair(name, exports.size()) ); + exports.push_back(ex); + } + + return true; + } + + std::string makeExportData() const { + std::ostringstream oss; + + oss << section(".edata") + << longdata(0) + << longdata(time(NULL)) + << longdata(0) + << rva(libsym) + << longdata(ordbase) + << longdata(exports.size()) + << longdata(count_names()) + << rva("exported_functions") + << rva("exported_names") + << rva("exported_ordinals") + << global_sym(libsym) + << asciz(libname) + << align(4) + << symbol("exported_functions"); + + for( size_t i = 0; i < exports.size(); i++ ) { + oss << "\t.rva\t" << common_name(i) << "\n"; + } + + oss << "exported_ordinals:\n"; + int lastord = ordbase; + for( size_t i = 0; i < exports.size(); i++ ) { + if( exports[i].getOrdinal() != -1 ) + lastord = exports[i].getOrdinal(); + else + lastord++; + oss << "\t.short\t" << lastord << "\n"; + } + + oss << "exported_names:\n"; + + for( size_t i = 0; i < exports.size(); i++ ) { + if( exports[i].getName().size() ) { + oss << "\t.rva\texport_name_" << (int)i << "\n"; + } + } + + for( size_t i = 0; i < exports.size(); i++ ) { + if( exports[i].getName().size() ) { + oss << "export_name_" << (int)i + << ":\t.asciz\t\"" + << exports[i].getName() << "\"\n"; + } + } + + oss << "# End of exports\n"; + + return oss.str(); + } + + static std::string align(int n) { + std::ostringstream oss; + oss << "\t.align\t" << n << "\n"; + return oss.str(); + } + + static std::string longdata(long l) { + std::ostringstream oss; + oss << "\t.long\t" << l << "\n"; + return oss.str(); + } + + static std::string shortdata(int i) { + std::ostringstream oss; + oss << "\t.short\t" << i << "\n"; + return oss.str(); + } + + static std::string space(int s) { + std::ostringstream oss; + oss << "\t.space\t" << s << "\n"; + return oss.str(); + } + + static std::string asciz(const std::string &s) { + std::string quote = "\""; + if(s.size() && s[0] == '\"') + quote = ""; + return std::string("\t.asciz\t") + quote + s + quote + "\n"; + } + + std::string makeArchiveHeader() const { + std::ostringstream oss; + + oss << section(".idata$2") + << global_sym(import_directory_entry) + << rva(original_first_thunk) + << longdata(0) + << longdata(0) + << rva(dll_name_text) + << section(".idata$4") + << global_sym(original_first_thunk) + << section(".idata$5") + << global_sym(first_thunk) + << section(".idata$6") + << global_sym(import_desc_table); + + return oss.str(); + } + + std::string makeArchiveFooter() const { + std::ostringstream oss; + + oss << section(".idata$3") + << global_sym(import_directory_term) + << space(20) + << global_sym(original_first_thunk_term) + << longdata(0) + << global_sym(first_thunk_term) + << longdata(0) + << section(".idata$7") + << global_sym(dll_name_text) + << asciz(libname); + + return oss.str(); + } + + std::string makePerImportData( size_t i ) const { + std::ostringstream oss; + + oss << section(".text") + << global_sym(common_name(i)) + << "\taddi\t1,1,16\n" + << "\tmflr\t0\n" + << "\tstw\t0,0(1)\n" + << "\tlis\t0," << impsym(first_thunk,i) << "@ha\n" + << "\tori\t0,0," << impsym(first_thunk,i) << "@l\n" + << "\tlwz\t0," << (4 * i) << "(0)\n" + << "\tmtlr\t0\n" + << "\tblrl\n" + << "\tlwz\t0,0(1)\n" + << "\taddi\t1,1,-16\n" + << "\tblr\n" + << rva(impsym(original_first_thunk,i)) + << rva(impsym(import_desc_table,i)) + << rva(impsym(first_thunk,i)) + << rva(import_directory_entry) + << rva(import_directory_term) + << section(".idata$4") + << symbol(impsym(original_first_thunk,i)) + << rva(impsym(import_desc_table,i)) + << section(".idata$5") + << symbol(impsym(import_desc_table,i)) + << shortdata(exports[i].getOrdinal()) + << asciz(exports[i].getName()) + << section(".idata$6") + << symbol(impsym(first_thunk,i)) + << rva(impsym(import_desc_table,i)); + + return oss.str(); + } + + size_t numFunctions() const { return exports.size(); } + + void setKillAt( bool kill ) { kill_at = kill; } + +private: + bool kill_at; + std::string libname, libsym; + std::string import_directory_entry, import_directory_term; + std::string original_first_thunk, first_thunk, dll_name_text; + std::string original_first_thunk_term, first_thunk_term; + std::string import_desc_table; + std::vector exports; + std::map export_byname; + int ordbase, mode; +}; + +std::string maketemp +( const std::string &prefix, + const std::string &suffix, + const std::string &payload ) { + std::string template_accum = + std::string("/tmp/") + prefix + "XXXXXX"; + std::vector storage, duplicate; + + for( size_t i = 0; i < template_accum.size(); i++ ) + storage.push_back(template_accum[i]); + storage.push_back(0); + + duplicate = storage; + std::string result; + mktemp(&duplicate[0]); + result = &duplicate[0]; + result += suffix; + std::ofstream of; + of.open(result.c_str()); + of << payload; + of.close(); + + return result; +} + +void _check( const std::string &varname, const std::string &varval ) { + if( !varval.size() ) { + fprintf( stderr, "You must specify %s\n", varname.c_str() ); + exit(1); + } +} + +#define check(x) _check(#x,x) + +bool parseArg(int argc, char **argv, + std::string &argval, + const char *short_n, + const char *long_n = 0, + const char *extra_n = 0) +{ + std::string argv_i; + bool got_val = false; + + if( !long_n ) { long_n = short_n; } + + for( int i = 0; i < argc; i++ ) { + argv_i = argv[i]; + if( argv_i == short_n ) { + if( i < argc-1 ) + argval = argv[i+1]; + got_val = true; + } else if( argv_i == long_n ) { + if( i < argc-1 ) + argval = argv[i+1]; + got_val = true; + } else if( argv_i.substr(0,strlen(long_n)+1) == + std::string(long_n) + "=" ) { + argval = argv_i.substr(strlen(long_n)+1); + got_val = true; + } + } + + if( !got_val && extra_n ) + return parseArg(argc,argv,argval,short_n,extra_n); + + return got_val; +} + +int main( int argc, char **argv ) { + int i, ln = 0; + bool dont_delete = false, kill_at = false; + DefFile f; + std::string line; + std::string def_file, exp_file, dll_name, imp_name, + as_name = "as", ar_name = "ar cq", foo; + std::ifstream in_def; + + parseArg(argc,argv,def_file,"-d","--def","--input-def"); + parseArg(argc,argv,exp_file,"-e","--exp","--output-exp"); + parseArg(argc,argv,imp_name,"-l","--lib","--output-lib"); + parseArg(argc,argv,dll_name,"-D","--dll","--dll-name"); + parseArg(argc,argv,as_name, "-S","--as"); + dont_delete = parseArg(argc,argv,foo,"-n"); + kill_at = parseArg(argc,argv,foo,"-k"); + + check(def_file); + check(imp_name); + + int err = 0; + std::string export_file, archive_header_file, archive_footer_file; + std::vector archive_member_files; + std::ostringstream make_exp; + std::ostringstream make_lib, archive_it; + + f.setKillAt(kill_at); + + in_def.open(def_file.c_str()); + while( std::getline(in_def,line) ) + if(!f.parse(++ln,line)) { + fprintf( stderr, "Ungrammatic def file\n" ); + goto cleanup; + } + in_def.close(); + + unlink(imp_name.c_str()); + + export_file = maketemp("exports",".s",f.makeExportData()); + archive_header_file = maketemp("arch_hdr",".s",f.makeArchiveHeader()); + archive_footer_file = maketemp("arch_end",".s",f.makeArchiveFooter()); + for( size_t i = 0; i < f.numFunctions(); i++ ) + archive_member_files.push_back + (maketemp("arch_mem",".s",f.makePerImportData(i))); + + if( exp_file.size() ) { + make_exp << as_name << " -mlittle -o " << exp_file << " " << export_file; + + fprintf( stderr, "execute %s\n", make_exp.str().c_str() ); + + if( (err = system(make_exp.str().c_str())) ) { + fprintf(stderr, "Failed to execute %s\n", make_exp.str().c_str()); + goto cleanup; + } + } + + make_lib << as_name << " -mlittle -o " << archive_header_file << ".o " + << archive_header_file + << " && " + << as_name << " -mlittle -o " << archive_footer_file << ".o " + << archive_footer_file; + + archive_it << ar_name << " " << imp_name << " " + << archive_header_file << ".o"; + for( size_t i = 0; i < f.numFunctions(); i++ ) { + make_lib << " && " + << as_name << " -mlittle -o " + << archive_member_files[i] << ".o " + << archive_member_files[i]; + archive_it << " " << archive_member_files[i] << ".o"; + } + + archive_it << " " << archive_footer_file << ".o"; + make_lib << " && " << archive_it.str(); + + fprintf( stderr, "execute %s\n", make_lib.str().c_str() ); + + if( (err = system(make_lib.str().c_str())) ) { + fprintf(stderr, "Failed to execute %s\n", make_exp.str().c_str()); + goto cleanup; + } + +cleanup: + if( !dont_delete ) { + unlink(export_file.c_str()); + unlink(archive_header_file.c_str()); + unlink((archive_header_file + ".o").c_str()); + unlink(archive_footer_file.c_str()); + unlink((archive_footer_file + ".o").c_str()); + for( size_t i = 0; i < f.numFunctions(); i++ ) { + unlink(archive_member_files[i].c_str()); + unlink((archive_member_files[i] + ".o").c_str()); + } + } + + return err; +} diff --git a/reactos/tools/ppc-build/compdvr/fork_execvp.h b/reactos/tools/ppc-build/compdvr/fork_execvp.h new file mode 100755 index 00000000000..107ab5da485 --- /dev/null +++ b/reactos/tools/ppc-build/compdvr/fork_execvp.h @@ -0,0 +1,28 @@ +#ifndef FORK_EXECVP_H +#define FORK_EXECVP_H + +#include +#include + +class ProcessHolder { +public: + virtual ~ProcessHolder() { } + virtual std::string ReadStdError() = 0; + virtual bool ProcessStarted() const = 0; + virtual bool EndOfStream() const = 0; + virtual int GetStatus() const = 0; +}; + +class Process { +public: + Process( ProcessHolder *h ) : holder(h) { } + ~Process() { delete holder; } + ProcessHolder *operator -> () const { return holder; } + operator ProcessHolder *() const { return (holder && holder->ProcessStarted()) ? holder : NULL; } +private: + ProcessHolder *holder; +}; + +ProcessHolder *fork_execvp( const std::vector &args ); + +#endif//FORK_EXECVP_H diff --git a/reactos/tools/ppc-build/compdvr/fork_unix.cpp b/reactos/tools/ppc-build/compdvr/fork_unix.cpp new file mode 100755 index 00000000000..be37903ca06 --- /dev/null +++ b/reactos/tools/ppc-build/compdvr/fork_unix.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include "fork_execvp.h" + +class UnixProcessHolder : public ProcessHolder { +public: + UnixProcessHolder( const std::vector &args ) + : read_fd(-1), child_pid(-1), at_end(false), status(-1) { + std::vector argvect(args.size()+1); + for( size_t i = 0; i < args.size(); i++ ) + argvect[i] = (char *)args[i].c_str(); + argvect[args.size()] = 0; + + int err_fd[2]; + + if( pipe( err_fd ) == -1 ) + return; + + fflush(stdout); + + child_pid = fork(); + + if( !child_pid ) { + dup2( err_fd[1], 2 ); + close( err_fd[0] ); + close( err_fd[1] ); + + execvp(args[0].c_str(), &argvect[0] ); + exit(1); + } else { + close( err_fd[1] ); + read_fd = err_fd[0]; + } + } + + ~UnixProcessHolder() { + close( read_fd ); + } + + std::string ReadStdError() { + char buf[1024]; + int rl = read( read_fd, buf, sizeof(buf) ); + if( rl < 1 ) { + at_end = true; + waitpid( child_pid, &status, 0 ); + return ""; + } + return std::string(buf, rl); + } + + bool ProcessStarted() const { return child_pid != -1; } + bool EndOfStream() const { return at_end; } + int GetStatus() const { return status; } + +private: + bool at_end; + int read_fd; + int child_pid; + int status; +}; + +ProcessHolder *fork_execvp( const std::vector &args ) { + return new UnixProcessHolder( args ); +} diff --git a/reactos/tools/ppc-build/compdvr/fork_win32.cpp b/reactos/tools/ppc-build/compdvr/fork_win32.cpp new file mode 100755 index 00000000000..1b3bc5ca32c --- /dev/null +++ b/reactos/tools/ppc-build/compdvr/fork_win32.cpp @@ -0,0 +1,109 @@ +#include +#include "fork_execvp.h" + +class Win32ProcessHolder : public ProcessHolder { +public: + Win32ProcessHolder( const std::string &args ) + : ErrorRead(INVALID_HANDLE_VALUE), + ProcessHandle(INVALID_HANDLE_VALUE), + StreamEnded(false) { + HANDLE ErrorWrite = NULL, ErrorReadTemp = NULL; + PROCESS_INFORMATION pi = { }; + SECURITY_ATTRIBUTES sa = { }; + STARTUPINFO si = { }; + + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + + if(!CreatePipe(&ErrorReadTemp, &ErrorWrite, &sa, 0)) return; + + if(!DuplicateHandle(GetCurrentProcess(), ErrorReadTemp, + GetCurrentProcess(), &ErrorRead, + 0, FALSE, + DUPLICATE_SAME_ACCESS)) return; + + CloseHandle(ErrorReadTemp); + + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + si.hStdError = ErrorWrite; + + if(!CreateProcess(NULL, (char *)args.c_str(), NULL, NULL, TRUE, + 0, NULL, NULL, &si, &pi)) return; + + ProcessHandle = pi.hProcess; + + CloseHandle(ErrorWrite); + } + + ~Win32ProcessHolder() { + CloseHandle( ErrorRead ); + CloseHandle( ProcessHandle ); + } + + std::string ReadStdError() { + char Buf[1024]; + DWORD ReadBytes; + + if( StreamEnded ) return ""; + + StreamEnded = + !ReadFile(ErrorRead, Buf, sizeof(Buf), &ReadBytes, NULL) || + !ReadBytes; + + if( !StreamEnded ) return std::string(Buf, ReadBytes); + else return ""; + } + + bool EndOfStream() const { + return StreamEnded; + } + + bool ProcessStarted() const { + return ProcessHandle != INVALID_HANDLE_VALUE; + } + + int GetStatus() const { + DWORD Status = 1; + if( ProcessHandle != INVALID_HANDLE_VALUE ) { + WaitForSingleObject( ProcessHandle, INFINITE ); + GetExitCodeProcess( ProcessHandle, &Status ); + } + return Status; + } + +private: + bool StreamEnded; + HANDLE ErrorRead, ProcessHandle; +}; + +std::string quote_escape( const std::string &_str ) { + std::string str = _str; + size_t q; + + q = str.find('\"'); + while( q != std::string::npos ) { + str.replace(q, 1, "\\\""); + q = str.find('\"'); + } + + return std::string("\"") + str + "\""; +} + +ProcessHolder *fork_execvp( const std::vector &args ) { + std::string argstring; + ProcessHolder *holder; + + for( std::vector::const_iterator i = args.begin(); + i != args.end(); + i++ ) { + if( i != args.begin() ) + argstring += " "; + argstring += quote_escape(*i); + } + + return new Win32ProcessHolder( argstring ); +} From 49cba5d4e369d63770d0869e185488296e813e8e Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 5 Jan 2007 06:02:56 +0000 Subject: [PATCH 67/81] Pre-transformed, modified headers suitable for use with -isystem when building reactos-ppc code. svn path=/branches/powerpc/; revision=25304 --- reactos/tools/ppc-build/core-headers/README | 14 + .../tools/ppc-build/core-headers/altivec.h | 11507 ++++++++++++++++ reactos/tools/ppc-build/core-headers/cxxabi.h | 528 + reactos/tools/ppc-build/core-headers/float.h | 162 + .../ppc-build/core-headers/g++-v3/algorithm | 71 + .../core-headers/g++-v3/backward/algo.h | 149 + .../core-headers/g++-v3/backward/algobase.h | 95 + .../core-headers/g++-v3/backward/alloc.h | 52 + .../g++-v3/backward/backward_warning.h | 39 + .../core-headers/g++-v3/backward/bvector.h | 68 + .../core-headers/g++-v3/backward/complex.h | 43 + .../core-headers/g++-v3/backward/defalloc.h | 117 + .../core-headers/g++-v3/backward/deque.h | 70 + .../core-headers/g++-v3/backward/fstream.h | 52 + .../core-headers/g++-v3/backward/function.h | 130 + .../core-headers/g++-v3/backward/hash_map.h | 72 + .../core-headers/g++-v3/backward/hash_set.h | 69 + .../core-headers/g++-v3/backward/hashtable.h | 76 + .../core-headers/g++-v3/backward/heap.h | 71 + .../core-headers/g++-v3/backward/iomanip.h | 70 + .../core-headers/g++-v3/backward/iostream.h | 60 + .../core-headers/g++-v3/backward/istream.h | 43 + .../core-headers/g++-v3/backward/iterator.h | 191 + .../core-headers/g++-v3/backward/list.h | 70 + .../core-headers/g++-v3/backward/map.h | 69 + .../core-headers/g++-v3/backward/multimap.h | 69 + .../core-headers/g++-v3/backward/multiset.h | 69 + .../core-headers/g++-v3/backward/new.h | 42 + .../core-headers/g++-v3/backward/ostream.h | 38 + .../core-headers/g++-v3/backward/pair.h | 70 + .../core-headers/g++-v3/backward/queue.h | 41 + .../core-headers/g++-v3/backward/rope.h | 60 + .../core-headers/g++-v3/backward/set.h | 69 + .../core-headers/g++-v3/backward/slist.h | 56 + .../core-headers/g++-v3/backward/stack.h | 72 + .../core-headers/g++-v3/backward/stream.h | 38 + .../core-headers/g++-v3/backward/streambuf.h | 40 + .../core-headers/g++-v3/backward/strstream | 179 + .../core-headers/g++-v3/backward/tempbuf.h | 78 + .../core-headers/g++-v3/backward/tree.h | 55 + .../core-headers/g++-v3/backward/vector.h | 70 + .../core-headers/g++-v3/bits/allocator.h | 134 + .../core-headers/g++-v3/bits/atomicity.h | 46 + .../core-headers/g++-v3/bits/basic_ios.h | 467 + .../core-headers/g++-v3/bits/basic_ios.tcc | 200 + .../core-headers/g++-v3/bits/basic_string.h | 2369 ++++ .../core-headers/g++-v3/bits/basic_string.tcc | 975 ++ .../g++-v3/bits/boost_concept_check.h | 932 ++ .../core-headers/g++-v3/bits/char_traits.h | 376 + .../core-headers/g++-v3/bits/cmath.tcc | 54 + .../core-headers/g++-v3/bits/codecvt.h | 478 + .../core-headers/g++-v3/bits/concept_check.h | 85 + .../core-headers/g++-v3/bits/concurrence.h | 95 + .../g++-v3/bits/cpp_type_traits.h | 345 + .../core-headers/g++-v3/bits/deque.tcc | 719 + .../core-headers/g++-v3/bits/fstream.tcc | 877 ++ .../core-headers/g++-v3/bits/functexcept.h | 85 + .../core-headers/g++-v3/bits/gslice.h | 165 + .../core-headers/g++-v3/bits/gslice_array.h | 220 + .../core-headers/g++-v3/bits/indirect_array.h | 212 + .../core-headers/g++-v3/bits/ios_base.h | 969 ++ .../core-headers/g++-v3/bits/istream.tcc | 1192 ++ .../core-headers/g++-v3/bits/list.tcc | 377 + .../core-headers/g++-v3/bits/locale_classes.h | 599 + .../core-headers/g++-v3/bits/locale_facets.h | 4558 ++++++ .../g++-v3/bits/locale_facets.tcc | 2744 ++++ .../core-headers/g++-v3/bits/localefwd.h | 192 + .../core-headers/g++-v3/bits/mask_array.h | 209 + .../core-headers/g++-v3/bits/ostream.tcc | 699 + .../core-headers/g++-v3/bits/postypes.h | 215 + .../core-headers/g++-v3/bits/slice_array.h | 273 + .../core-headers/g++-v3/bits/sstream.tcc | 227 + .../core-headers/g++-v3/bits/stl_algo.h | 5148 +++++++ .../core-headers/g++-v3/bits/stl_algobase.h | 842 ++ .../core-headers/g++-v3/bits/stl_bvector.h | 876 ++ .../core-headers/g++-v3/bits/stl_construct.h | 157 + .../core-headers/g++-v3/bits/stl_deque.h | 1501 ++ .../core-headers/g++-v3/bits/stl_function.h | 898 ++ .../core-headers/g++-v3/bits/stl_heap.h | 467 + .../core-headers/g++-v3/bits/stl_iterator.h | 772 ++ .../g++-v3/bits/stl_iterator_base_funcs.h | 179 + .../g++-v3/bits/stl_iterator_base_types.h | 170 + .../core-headers/g++-v3/bits/stl_list.h | 1255 ++ .../core-headers/g++-v3/bits/stl_map.h | 694 + .../core-headers/g++-v3/bits/stl_multimap.h | 677 + .../core-headers/g++-v3/bits/stl_multiset.h | 585 + .../core-headers/g++-v3/bits/stl_numeric.h | 326 + .../core-headers/g++-v3/bits/stl_pair.h | 147 + .../core-headers/g++-v3/bits/stl_queue.h | 472 + .../g++-v3/bits/stl_raw_storage_iter.h | 113 + .../core-headers/g++-v3/bits/stl_relops.h | 137 + .../core-headers/g++-v3/bits/stl_set.h | 593 + .../core-headers/g++-v3/bits/stl_stack.h | 272 + .../core-headers/g++-v3/bits/stl_tempbuf.h | 171 + .../core-headers/g++-v3/bits/stl_threads.h | 150 + .../core-headers/g++-v3/bits/stl_tree.h | 1283 ++ .../g++-v3/bits/stl_uninitialized.h | 297 + .../core-headers/g++-v3/bits/stl_vector.h | 932 ++ .../g++-v3/bits/stream_iterator.h | 214 + .../core-headers/g++-v3/bits/streambuf.tcc | 163 + .../g++-v3/bits/streambuf_iterator.h | 258 + .../core-headers/g++-v3/bits/stringfwd.h | 69 + .../core-headers/g++-v3/bits/type_traits.h | 405 + .../core-headers/g++-v3/bits/valarray_after.h | 499 + .../core-headers/g++-v3/bits/valarray_array.h | 625 + .../g++-v3/bits/valarray_array.tcc | 240 + .../g++-v3/bits/valarray_before.h | 701 + .../core-headers/g++-v3/bits/vector.tcc | 414 + .../ppc-build/core-headers/g++-v3/bitset | 1229 ++ .../ppc-build/core-headers/g++-v3/cassert | 48 + .../ppc-build/core-headers/g++-v3/cctype | 83 + .../ppc-build/core-headers/g++-v3/cerrno | 55 + .../ppc-build/core-headers/g++-v3/cfloat | 50 + .../ppc-build/core-headers/g++-v3/ciso646 | 37 + .../ppc-build/core-headers/g++-v3/climits | 51 + .../ppc-build/core-headers/g++-v3/clocale | 62 + .../tools/ppc-build/core-headers/g++-v3/cmath | 595 + .../ppc-build/core-headers/g++-v3/complex | 1226 ++ .../ppc-build/core-headers/g++-v3/csetjmp | 65 + .../ppc-build/core-headers/g++-v3/csignal | 61 + .../ppc-build/core-headers/g++-v3/cstdarg | 60 + .../ppc-build/core-headers/g++-v3/cstddef | 56 + .../ppc-build/core-headers/g++-v3/cstdio | 185 + .../ppc-build/core-headers/g++-v3/cstdlib | 204 + .../ppc-build/core-headers/g++-v3/cstring | 128 + .../tools/ppc-build/core-headers/g++-v3/ctime | 81 + .../ppc-build/core-headers/g++-v3/cwchar | 275 + .../ppc-build/core-headers/g++-v3/cwctype | 110 + .../core-headers/g++-v3/debug/bitset | 299 + .../core-headers/g++-v3/debug/debug.h | 531 + .../ppc-build/core-headers/g++-v3/debug/deque | 386 + .../core-headers/g++-v3/debug/formatter.h | 391 + .../core-headers/g++-v3/debug/hash_map | 38 + .../core-headers/g++-v3/debug/hash_map.h | 270 + .../core-headers/g++-v3/debug/hash_multimap.h | 261 + .../core-headers/g++-v3/debug/hash_multiset.h | 236 + .../core-headers/g++-v3/debug/hash_set | 38 + .../core-headers/g++-v3/debug/hash_set.h | 245 + .../ppc-build/core-headers/g++-v3/debug/list | 505 + .../ppc-build/core-headers/g++-v3/debug/map | 38 + .../ppc-build/core-headers/g++-v3/debug/map.h | 323 + .../core-headers/g++-v3/debug/multimap.h | 314 + .../core-headers/g++-v3/debug/multiset.h | 320 + .../core-headers/g++-v3/debug/safe_base.h | 207 + .../core-headers/g++-v3/debug/safe_iterator.h | 618 + .../g++-v3/debug/safe_iterator.tcc | 140 + .../core-headers/g++-v3/debug/safe_sequence.h | 180 + .../ppc-build/core-headers/g++-v3/debug/set | 38 + .../ppc-build/core-headers/g++-v3/debug/set.h | 325 + .../core-headers/g++-v3/debug/string | 1001 ++ .../core-headers/g++-v3/debug/vector | 412 + .../tools/ppc-build/core-headers/g++-v3/deque | 81 + .../ppc-build/core-headers/g++-v3/exception | 120 + .../core-headers/g++-v3/exception_defines.h | 47 + .../core-headers/g++-v3/ext/algorithm | 518 + .../g++-v3/ext/bitmap_allocator.h | 859 ++ .../core-headers/g++-v3/ext/debug_allocator.h | 121 + .../core-headers/g++-v3/ext/enc_filebuf.h | 68 + .../core-headers/g++-v3/ext/functional | 395 + .../core-headers/g++-v3/ext/hash_fun.h | 122 + .../core-headers/g++-v3/ext/hash_map | 447 + .../core-headers/g++-v3/ext/hash_set | 439 + .../core-headers/g++-v3/ext/hashtable.h | 994 ++ .../core-headers/g++-v3/ext/iterator | 113 + .../g++-v3/ext/malloc_allocator.h | 118 + .../ppc-build/core-headers/g++-v3/ext/memory | 171 + .../core-headers/g++-v3/ext/mt_allocator.h | 718 + .../core-headers/g++-v3/ext/new_allocator.h | 113 + .../ppc-build/core-headers/g++-v3/ext/numeric | 148 + .../core-headers/g++-v3/ext/pod_char_traits.h | 158 + .../core-headers/g++-v3/ext/pool_allocator.h | 255 + .../ppc-build/core-headers/g++-v3/ext/rb_tree | 97 + .../ppc-build/core-headers/g++-v3/ext/rope | 2494 ++++ .../core-headers/g++-v3/ext/ropeimpl.h | 1539 +++ .../ppc-build/core-headers/g++-v3/ext/slist | 906 ++ .../core-headers/g++-v3/ext/stdio_filebuf.h | 162 + .../g++-v3/ext/stdio_sync_filebuf.h | 281 + .../ppc-build/core-headers/g++-v3/fstream | 847 ++ .../ppc-build/core-headers/g++-v3/functional | 58 + .../ppc-build/core-headers/g++-v3/iomanip | 300 + .../tools/ppc-build/core-headers/g++-v3/ios | 53 + .../ppc-build/core-headers/g++-v3/iosfwd | 168 + .../ppc-build/core-headers/g++-v3/iostream | 80 + .../ppc-build/core-headers/g++-v3/istream | 778 ++ .../ppc-build/core-headers/g++-v3/iterator | 76 + .../ppc-build/core-headers/g++-v3/limits | 1143 ++ .../tools/ppc-build/core-headers/g++-v3/list | 82 + .../ppc-build/core-headers/g++-v3/locale | 49 + .../tools/ppc-build/core-headers/g++-v3/map | 74 + .../ppc-build/core-headers/g++-v3/memory | 375 + .../tools/ppc-build/core-headers/g++-v3/new | 101 + .../ppc-build/core-headers/g++-v3/numeric | 72 + .../ppc-build/core-headers/g++-v3/ostream | 552 + .../bits/atomic_word.h | 35 + .../bits/basic_file.h | 110 + .../bits/c++allocator.h | 37 + .../bits/c++config.h | 1297 ++ .../powerpc-unknown-linux-gnu/bits/c++io.h | 86 + .../bits/c++locale.h | 99 + .../bits/codecvt_specializations.h | 478 + .../bits/ctype_base.h | 56 + .../bits/ctype_inline.h | 69 + .../bits/ctype_noninline.h | 159 + .../bits/gthr-default.h | 517 + .../bits/gthr-posix.h | 517 + .../bits/gthr-single.h | 239 + .../powerpc-unknown-linux-gnu/bits/gthr.h | 103 + .../bits/messages_members.h | 104 + .../bits/os_defines.h | 46 + .../bits/time_members.h | 68 + .../tools/ppc-build/core-headers/g++-v3/queue | 78 + .../tools/ppc-build/core-headers/g++-v3/set | 74 + .../ppc-build/core-headers/g++-v3/sstream | 643 + .../tools/ppc-build/core-headers/g++-v3/stack | 73 + .../ppc-build/core-headers/g++-v3/stdexcept | 148 + .../ppc-build/core-headers/g++-v3/streambuf | 784 ++ .../ppc-build/core-headers/g++-v3/string | 60 + .../ppc-build/core-headers/g++-v3/typeinfo | 156 + .../ppc-build/core-headers/g++-v3/utility | 70 + .../ppc-build/core-headers/g++-v3/valarray | 1017 ++ .../ppc-build/core-headers/g++-v3/vector | 83 + reactos/tools/ppc-build/core-headers/g2c.h | 234 + reactos/tools/ppc-build/core-headers/iso646.h | 48 + reactos/tools/ppc-build/core-headers/limits.h | 125 + .../tools/ppc-build/core-headers/ppc-asm.h | 164 + reactos/tools/ppc-build/core-headers/spe.h | 1110 ++ reactos/tools/ppc-build/core-headers/stdarg.h | 133 + .../tools/ppc-build/core-headers/stdbool.h | 53 + reactos/tools/ppc-build/core-headers/stddef.h | 426 + .../tools/ppc-build/core-headers/syslimits.h | 8 + reactos/tools/ppc-build/core-headers/unwind.h | 232 + .../tools/ppc-build/core-headers/varargs.h | 7 + 232 files changed, 96539 insertions(+) create mode 100644 reactos/tools/ppc-build/core-headers/README create mode 100644 reactos/tools/ppc-build/core-headers/altivec.h create mode 100644 reactos/tools/ppc-build/core-headers/cxxabi.h create mode 100644 reactos/tools/ppc-build/core-headers/float.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/algorithm create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/algo.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/algobase.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/alloc.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/backward_warning.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/bvector.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/complex.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/defalloc.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/deque.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/fstream.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/function.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_map.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_set.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/hashtable.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/heap.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/iomanip.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/iostream.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/istream.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/iterator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/list.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/map.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/multimap.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/multiset.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/new.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/ostream.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/pair.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/queue.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/rope.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/set.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/slist.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/stack.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/stream.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/streambuf.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/strstream create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/tempbuf.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/tree.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/backward/vector.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/atomicity.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/boost_concept_check.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/char_traits.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/cmath.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/codecvt.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/concept_check.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/concurrence.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/cpp_type_traits.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/deque.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/fstream.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/functexcept.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice_array.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/indirect_array.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/ios_base.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/istream.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/list.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_classes.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/localefwd.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/mask_array.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/ostream.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/postypes.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/slice_array.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/sstream.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algo.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algobase.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_bvector.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_construct.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_deque.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_function.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_heap.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_funcs.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_types.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_list.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_map.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multimap.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multiset.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_numeric.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_pair.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_queue.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_raw_storage_iter.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_relops.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_set.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_stack.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tempbuf.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_threads.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tree.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_uninitialized.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_vector.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stream_iterator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf_iterator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/stringfwd.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/type_traits.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_after.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_before.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bits/vector.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/bitset create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cassert create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cctype create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cerrno create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cfloat create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ciso646 create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/climits create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/clocale create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cmath create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/complex create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/csetjmp create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/csignal create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cstdarg create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cstddef create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cstdio create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cstdlib create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cstring create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ctime create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cwchar create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/cwctype create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/bitset create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/debug.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/deque create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/formatter.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multimap.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multiset.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/list create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/map create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/map.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/multimap.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/multiset.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_base.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.tcc create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_sequence.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/set create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/set.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/string create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/debug/vector create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/deque create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/exception create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/exception_defines.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/algorithm create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/bitmap_allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/debug_allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/enc_filebuf.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/functional create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_fun.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_map create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_set create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/hashtable.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/iterator create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/malloc_allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/memory create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/mt_allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/new_allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/numeric create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/pod_char_traits.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/pool_allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/rb_tree create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/rope create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/ropeimpl.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/slist create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_filebuf.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_sync_filebuf.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/fstream create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/functional create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/iomanip create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ios create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/iosfwd create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/iostream create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/istream create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/iterator create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/limits create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/list create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/locale create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/map create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/memory create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/new create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/numeric create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/ostream create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/atomic_word.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/basic_file.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++allocator.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++config.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++io.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++locale.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/codecvt_specializations.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_base.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_inline.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_noninline.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-default.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-posix.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-single.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/messages_members.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/os_defines.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/time_members.h create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/queue create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/set create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/sstream create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/stack create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/stdexcept create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/streambuf create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/string create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/typeinfo create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/utility create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/valarray create mode 100644 reactos/tools/ppc-build/core-headers/g++-v3/vector create mode 100644 reactos/tools/ppc-build/core-headers/g2c.h create mode 100644 reactos/tools/ppc-build/core-headers/iso646.h create mode 100644 reactos/tools/ppc-build/core-headers/limits.h create mode 100644 reactos/tools/ppc-build/core-headers/ppc-asm.h create mode 100644 reactos/tools/ppc-build/core-headers/spe.h create mode 100644 reactos/tools/ppc-build/core-headers/stdarg.h create mode 100644 reactos/tools/ppc-build/core-headers/stdbool.h create mode 100644 reactos/tools/ppc-build/core-headers/stddef.h create mode 100644 reactos/tools/ppc-build/core-headers/syslimits.h create mode 100644 reactos/tools/ppc-build/core-headers/unwind.h create mode 100644 reactos/tools/ppc-build/core-headers/varargs.h diff --git a/reactos/tools/ppc-build/core-headers/README b/reactos/tools/ppc-build/core-headers/README new file mode 100644 index 00000000000..7086a7782d4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/README @@ -0,0 +1,14 @@ +This README file is copied into the directory for GCC-only header files +when fixincludes is run by the makefile for GCC. + +Many of the files in this directory were automatically edited from the +standard system header files by the fixincludes process. They are +system-specific, and will not work on any other kind of system. They +are also not part of GCC. The reason we have to do this is because +GCC requires ANSI C headers and many vendors supply ANSI-incompatible +headers. + +Because this is an automated process, sometimes headers get "fixed" +that do not, strictly speaking, need a fix. As long as nothing is broken +by the process, it is just an unfortunate collateral inconvenience. +We would like to rectify it, if it is not "too inconvenient". diff --git a/reactos/tools/ppc-build/core-headers/altivec.h b/reactos/tools/ppc-build/core-headers/altivec.h new file mode 100644 index 00000000000..779b4280ba5 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/altivec.h @@ -0,0 +1,11507 @@ +/* PowerPC AltiVec include file. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* Implemented to conform to the specification included in the AltiVec + Technology Programming Interface Manual (ALTIVECPIM/D 6/1999 Rev 0). */ + +#ifndef _ALTIVEC_H +#define _ALTIVEC_H 1 + +#if !defined(__VEC__) || !defined(__ALTIVEC__) +#error Use the "-maltivec" flag to enable PowerPC AltiVec support +#endif + +/* If __APPLE_ALTIVEC__ is defined, the compiler supports 'vector', + 'pixel' and 'bool' as context-sensitive AltiVec keywords (in + non-AltiVec contexts, they revert to their original meanings, + if any), so we do not need to define them as macros. */ + +#if !defined(__APPLE_ALTIVEC__) +/* You are allowed to undef these for C++ compatibility. */ +#define vector __vector +#define pixel __pixel +#define bool __bool +#endif + +/* Condition register codes for AltiVec predicates. */ + +#define __CR6_EQ 0 +#define __CR6_EQ_REV 1 +#define __CR6_LT 2 +#define __CR6_LT_REV 3 + +/* These are easy... Same exact arguments. */ + +#define vec_vaddcuw vec_addc +#define vec_vand vec_and +#define vec_vandc vec_andc +#define vec_vrfip vec_ceil +#define vec_vcmpbfp vec_cmpb +#define vec_vcmpgefp vec_cmpge +#define vec_vctsxs vec_cts +#define vec_vctuxs vec_ctu +#define vec_vexptefp vec_expte +#define vec_vrfim vec_floor +#define vec_lvx vec_ld +#define vec_lvxl vec_ldl +#define vec_vlogefp vec_loge +#define vec_vmaddfp vec_madd +#define vec_vmhaddshs vec_madds +#define vec_vmladduhm vec_mladd +#define vec_vmhraddshs vec_mradds +#define vec_vnmsubfp vec_nmsub +#define vec_vnor vec_nor +#define vec_vor vec_or +#define vec_vpkpx vec_packpx +#define vec_vperm vec_perm +#define vec_vrefp vec_re +#define vec_vrfin vec_round +#define vec_vrsqrtefp vec_rsqrte +#define vec_vsel vec_sel +#define vec_vsldoi vec_sld +#define vec_vsl vec_sll +#define vec_vslo vec_slo +#define vec_vspltisb vec_splat_s8 +#define vec_vspltish vec_splat_s16 +#define vec_vspltisw vec_splat_s32 +#define vec_vsr vec_srl +#define vec_vsro vec_sro +#define vec_stvx vec_st +#define vec_stvxl vec_stl +#define vec_vsubcuw vec_subc +#define vec_vsum2sws vec_sum2s +#define vec_vsumsws vec_sums +#define vec_vrfiz vec_trunc +#define vec_vxor vec_xor + +#ifdef __cplusplus + +extern "C++" { + +/* Prototypes for builtins that take literals and must always be + inlined. */ +inline __vector float vec_ctf (__vector unsigned int, const int) __attribute__ ((always_inline)); +inline __vector float vec_ctf (__vector signed int, const int) __attribute__ ((always_inline)); +inline __vector float vec_vcfsx (__vector signed int a1, const int a2) __attribute__ ((always_inline)); +inline __vector float vec_vcfux (__vector unsigned int a1, const int a2) __attribute__ ((always_inline)); +inline __vector signed int vec_cts (__vector float, const int) __attribute__ ((always_inline)); +inline __vector unsigned int vec_ctu (__vector float, const int) __attribute__ ((always_inline)); +inline void vec_dss (const int) __attribute__ ((always_inline)); + +inline void vec_dst (const __vector unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector __bool char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector signed short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector __bool short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector __pixel *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector signed int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector __bool int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const __vector float *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const unsigned long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dst (const float *, int, const int) __attribute__ ((always_inline)); + +inline void vec_dstst (const __vector unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector __bool char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector signed short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector __bool short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector __pixel *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector signed int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector __bool int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const __vector float *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const unsigned long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstst (const float *, int, const int) __attribute__ ((always_inline)); + +inline void vec_dststt (const __vector unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector __bool char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector signed short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector __bool short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector __pixel *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector signed int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector __bool int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const __vector float *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const unsigned long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dststt (const float *, int, const int) __attribute__ ((always_inline)); + +inline void vec_dstt (const __vector unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector __bool char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector signed short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector __bool short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector __pixel *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector signed int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector __bool int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const __vector float *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const unsigned char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const signed char *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const unsigned short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const short *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const unsigned int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const int *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const unsigned long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const long *, int, const int) __attribute__ ((always_inline)); +inline void vec_dstt (const float *, int, const int) __attribute__ ((always_inline)); + +inline __vector float vec_sld (__vector float, __vector float, const int) __attribute__ ((always_inline)); +inline __vector signed int vec_sld (__vector signed int, __vector signed int, const int) __attribute__ ((always_inline)); +inline __vector unsigned int vec_sld (__vector unsigned int, __vector unsigned int, const int) __attribute__ ((always_inline)); +inline __vector __bool int vec_sld (__vector __bool int, __vector __bool int, const int) __attribute__ ((always_inline)); +inline __vector signed short vec_sld (__vector signed short, __vector signed short, const int) __attribute__ ((always_inline)); +inline __vector unsigned short vec_sld (__vector unsigned short, __vector unsigned short, const int) __attribute__ ((always_inline)); +inline __vector __bool short vec_sld (__vector __bool short, __vector __bool short, const int) __attribute__ ((always_inline)); +inline __vector __pixel vec_sld (__vector __pixel, __vector __pixel, const int) __attribute__ ((always_inline)); +inline __vector signed char vec_sld (__vector signed char, __vector signed char, const int) __attribute__ ((always_inline)); +inline __vector unsigned char vec_sld (__vector unsigned char, __vector unsigned char, const int) __attribute__ ((always_inline)); +inline __vector __bool char vec_sld (__vector __bool char, __vector __bool char, const int) __attribute__ ((always_inline)); +inline __vector signed char vec_splat (__vector signed char, const int) __attribute__ ((always_inline)); +inline __vector unsigned char vec_splat (__vector unsigned char, const int) __attribute__ ((always_inline)); +inline __vector __bool char vec_splat (__vector __bool char, const int) __attribute__ ((always_inline)); +inline __vector signed short vec_splat (__vector signed short, const int) __attribute__ ((always_inline)); +inline __vector unsigned short vec_splat (__vector unsigned short, const int) __attribute__ ((always_inline)); +inline __vector __bool short vec_splat (__vector __bool short, const int) __attribute__ ((always_inline)); +inline __vector __pixel vec_splat (__vector __pixel, const int) __attribute__ ((always_inline)); +inline __vector float vec_splat (__vector float, const int) __attribute__ ((always_inline)); +inline __vector signed int vec_splat (__vector signed int, const int) __attribute__ ((always_inline)); +inline __vector unsigned int vec_splat (__vector unsigned int, const int) __attribute__ ((always_inline)); +inline __vector __bool int vec_splat (__vector __bool int, const int) __attribute__ ((always_inline)); +inline __vector signed char vec_splat_s8 (const int) __attribute__ ((always_inline)); +inline __vector signed short vec_splat_s16 (const int) __attribute__ ((always_inline)); +inline __vector signed int vec_splat_s32 (const int) __attribute__ ((always_inline)); +inline __vector unsigned char vec_splat_u8 (const int) __attribute__ ((always_inline)); +inline __vector unsigned short vec_splat_u16 (const int) __attribute__ ((always_inline)); +inline __vector unsigned int vec_splat_u32 (const int) __attribute__ ((always_inline)); +inline __vector float vec_vspltw (__vector float a1, const int a2) __attribute__ ((always_inline)); +inline __vector __bool int vec_vspltw (__vector __bool int a1, const int a2) __attribute__ ((always_inline)); +inline __vector signed int vec_vspltw (__vector signed int a1, const int a2) __attribute__ ((always_inline)); +inline __vector unsigned int vec_vspltw (__vector unsigned int a1, const int a2) __attribute__ ((always_inline)); +inline __vector __bool short vec_vsplth (__vector __bool short a1, const int a2) __attribute__ ((always_inline)); +inline __vector signed short vec_vsplth (__vector signed short a1, const int a2) __attribute__ ((always_inline)); +inline __vector unsigned short vec_vsplth (__vector unsigned short a1, const int a2) __attribute__ ((always_inline)); +inline __vector __pixel vec_vsplth (__vector __pixel a1, const int a2) __attribute__ ((always_inline)); +inline __vector __bool char vec_vspltb (__vector __bool char a1, const int a2) __attribute__ ((always_inline)); +inline __vector signed char vec_vspltb (__vector signed char a1, const int a2) __attribute__ ((always_inline)); +inline __vector unsigned char vec_vspltb (__vector unsigned char a1, const int a2) __attribute__ ((always_inline)); + +/* vec_step */ + +template +struct __vec_step_help +{ + // All proper __vector types will specialize _S_elem. +}; + +template<> +struct __vec_step_help<__vector signed short> +{ + static const int _S_elem = 8; +}; + +template<> +struct __vec_step_help<__vector unsigned short> +{ + static const int _S_elem = 8; +}; + +template<> +struct __vec_step_help<__vector __bool short> +{ + static const int _S_elem = 8; +}; + +template<> +struct __vec_step_help<__vector __pixel> +{ + static const int _S_elem = 8; +}; + +template<> +struct __vec_step_help<__vector signed int> +{ + static const int _S_elem = 4; +}; + +template<> +struct __vec_step_help<__vector unsigned int> +{ + static const int _S_elem = 4; +}; + +template<> +struct __vec_step_help<__vector __bool int> +{ + static const int _S_elem = 4; +}; + +template<> +struct __vec_step_help<__vector unsigned char> +{ + static const int _S_elem = 16; +}; + +template<> +struct __vec_step_help<__vector signed char> +{ + static const int _S_elem = 16; +}; + +template<> +struct __vec_step_help<__vector __bool char> +{ + static const int _S_elem = 16; +}; + +template<> +struct __vec_step_help<__vector float> +{ + static const int _S_elem = 4; +}; + +#define vec_step(t) __vec_step_help::_S_elem + +/* vec_abs */ + +inline __vector signed char +vec_abs (__vector signed char a1) +{ + return __builtin_altivec_abs_v16qi (a1); +} + +inline __vector signed short +vec_abs (__vector signed short a1) +{ + return __builtin_altivec_abs_v8hi (a1); +} + +inline __vector signed int +vec_abs (__vector signed int a1) +{ + return __builtin_altivec_abs_v4si (a1); +} + +inline __vector float +vec_abs (__vector float a1) +{ + return __builtin_altivec_abs_v4sf (a1); +} + +/* vec_abss */ + +inline __vector signed char +vec_abss (__vector signed char a1) +{ + return __builtin_altivec_abss_v16qi (a1); +} + +inline __vector signed short +vec_abss (__vector signed short a1) +{ + return __builtin_altivec_abss_v8hi (a1); +} + +inline __vector signed int +vec_abss (__vector signed int a1) +{ + return __builtin_altivec_abss_v4si (a1); +} + +/* vec_add */ + +inline __vector signed char +vec_add (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_add (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_add (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_add (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_add (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_add (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_add (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_add (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_add (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_add (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_add (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_add (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_add (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_add (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_add (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_add (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_add (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_add (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_add (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vaddfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vaddfp */ + +inline __vector float +vec_vaddfp (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vaddfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vadduwm */ + +inline __vector signed int +vec_vadduwm (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vadduwm (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vadduwm (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vadduwm (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vadduwm (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vadduwm (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vadduhm */ + +inline __vector signed short +vec_vadduhm (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vadduhm (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vadduhm (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vadduhm (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vadduhm (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vadduhm (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vaddubm */ + +inline __vector signed char +vec_vaddubm (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vaddubm (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vaddubm (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vaddubm (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vaddubm (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vaddubm (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_addc */ + +inline __vector unsigned int +vec_addc (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vaddcuw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_adds */ + +inline __vector unsigned char +vec_adds (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_adds (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_adds (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_adds (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_adds (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_adds (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned short +vec_adds (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_adds (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_adds (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_adds (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_adds (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_adds (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned int +vec_adds (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_adds (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_adds (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_adds (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_adds (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_adds (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vaddsws */ + +inline __vector signed int +vec_vaddsws (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vaddsws (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vaddsws (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vadduws */ + +inline __vector unsigned int +vec_vadduws (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vadduws (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vadduws (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vaddshs */ + +inline __vector signed short +vec_vaddshs (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vaddshs (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vaddshs (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vadduhs */ + +inline __vector unsigned short +vec_vadduhs (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vadduhs (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vadduhs (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vaddsbs */ + +inline __vector signed char +vec_vaddsbs (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vaddsbs (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vaddsbs (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vaddubs */ + +inline __vector unsigned char +vec_vaddubs (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vaddubs (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vaddubs (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_and */ + +inline __vector float +vec_and (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_and (__vector float a1, __vector __bool int a2) +{ + return (__vector float) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_and (__vector __bool int a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_and (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_and (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_and (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_and (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_and (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_and (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_and (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_and (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_and (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_and (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_and (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_and (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_and (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_and (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_and (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_and (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_and (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_and (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_and (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_and (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_and (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vand ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_andc */ + +inline __vector float +vec_andc (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_andc (__vector float a1, __vector __bool int a2) +{ + return (__vector float) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_andc (__vector __bool int a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_andc (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_andc (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_andc (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_andc (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_andc (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_andc (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_andc (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_andc (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_andc (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_andc (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_andc (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_andc (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_andc (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_andc (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_andc (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_andc (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_andc (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_andc (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_andc (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_andc (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_andc (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vandc ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_avg */ + +inline __vector unsigned char +vec_avg (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vavgub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_avg (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vavgsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned short +vec_avg (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vavguh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_avg (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vavgsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned int +vec_avg (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vavguw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_avg (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vavgsw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vavgsw */ + +inline __vector signed int +vec_vavgsw (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vavgsw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vavguw */ + +inline __vector unsigned int +vec_vavguw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vavguw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vavgsh */ + +inline __vector signed short +vec_vavgsh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vavgsh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vavguh */ + +inline __vector unsigned short +vec_vavguh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vavguh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vavgsb */ + +inline __vector signed char +vec_vavgsb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vavgsb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vavgub */ + +inline __vector unsigned char +vec_vavgub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vavgub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_ceil */ + +inline __vector float +vec_ceil (__vector float a1) +{ + return (__vector float) __builtin_altivec_vrfip ((__vector float) a1); +} + +/* vec_cmpb */ + +inline __vector signed int +vec_cmpb (__vector float a1, __vector float a2) +{ + return (__vector signed int) __builtin_altivec_vcmpbfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_cmpeq */ + +inline __vector __bool char +vec_cmpeq (__vector signed char a1, __vector signed char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool char +vec_cmpeq (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool short +vec_cmpeq (__vector signed short a1, __vector signed short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __bool short +vec_cmpeq (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __bool int +vec_cmpeq (__vector signed int a1, __vector signed int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_cmpeq (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_cmpeq (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpeqfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vcmpeqfp */ + +inline __vector __bool int +vec_vcmpeqfp (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpeqfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vcmpequw */ + +inline __vector __bool int +vec_vcmpequw (__vector signed int a1, __vector signed int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_vcmpequw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vcmpequh */ + +inline __vector __bool short +vec_vcmpequh (__vector signed short a1, __vector signed short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __bool short +vec_vcmpequh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vcmpequb */ + +inline __vector __bool char +vec_vcmpequb (__vector signed char a1, __vector signed char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool char +vec_vcmpequb (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_cmpge */ + +inline __vector __bool int +vec_cmpge (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgefp ((__vector float) a1, (__vector float) a2); +} + +/* vec_cmpgt */ + +inline __vector __bool char +vec_cmpgt (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpgtub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool char +vec_cmpgt (__vector signed char a1, __vector signed char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpgtsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool short +vec_cmpgt (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpgtuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __bool short +vec_cmpgt (__vector signed short a1, __vector signed short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpgtsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __bool int +vec_cmpgt (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_cmpgt (__vector signed int a1, __vector signed int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_cmpgt (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vcmpgtfp */ + +inline __vector __bool int +vec_vcmpgtfp (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vcmpgtsw */ + +inline __vector __bool int +vec_vcmpgtsw (__vector signed int a1, __vector signed int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtsw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vcmpgtuw */ + +inline __vector __bool int +vec_vcmpgtuw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtuw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vcmpgtsh */ + +inline __vector __bool short +vec_vcmpgtsh (__vector signed short a1, __vector signed short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpgtsh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vcmpgtuh */ + +inline __vector __bool short +vec_vcmpgtuh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpgtuh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vcmpgtsb */ + +inline __vector __bool char +vec_vcmpgtsb (__vector signed char a1, __vector signed char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpgtsb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vcmpgtub */ + +inline __vector __bool char +vec_vcmpgtub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpgtub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_cmple */ + +inline __vector __bool int +vec_cmple (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgefp ((__vector float) a2, (__vector float) a1); +} + +/* vec_cmplt */ + +inline __vector __bool char +vec_cmplt (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpgtub ((__vector signed char) a2, (__vector signed char) a1); +} + +inline __vector __bool char +vec_cmplt (__vector signed char a1, __vector signed char a2) +{ + return (__vector __bool char) __builtin_altivec_vcmpgtsb ((__vector signed char) a2, (__vector signed char) a1); +} + +inline __vector __bool short +vec_cmplt (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpgtuh ((__vector signed short) a2, (__vector signed short) a1); +} + +inline __vector __bool short +vec_cmplt (__vector signed short a1, __vector signed short a2) +{ + return (__vector __bool short) __builtin_altivec_vcmpgtsh ((__vector signed short) a2, (__vector signed short) a1); +} + +inline __vector __bool int +vec_cmplt (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtuw ((__vector signed int) a2, (__vector signed int) a1); +} + +inline __vector __bool int +vec_cmplt (__vector signed int a1, __vector signed int a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtsw ((__vector signed int) a2, (__vector signed int) a1); +} + +inline __vector __bool int +vec_cmplt (__vector float a1, __vector float a2) +{ + return (__vector __bool int) __builtin_altivec_vcmpgtfp ((__vector float) a2, (__vector float) a1); +} + +/* vec_ctf */ + +inline __vector float +vec_ctf (__vector unsigned int a1, const int a2) +{ + return (__vector float) __builtin_altivec_vcfux ((__vector signed int) a1, a2); +} + +inline __vector float +vec_ctf (__vector signed int a1, const int a2) +{ + return (__vector float) __builtin_altivec_vcfsx ((__vector signed int) a1, a2); +} + +/* vec_vcfsx */ + +inline __vector float +vec_vcfsx (__vector signed int a1, const int a2) +{ + return (__vector float) __builtin_altivec_vcfsx ((__vector signed int) a1, a2); +} + +/* vec_vcfux */ + +inline __vector float +vec_vcfux (__vector unsigned int a1, const int a2) +{ + return (__vector float) __builtin_altivec_vcfux ((__vector signed int) a1, a2); +} + +/* vec_cts */ + +inline __vector signed int +vec_cts (__vector float a1, const int a2) +{ + return (__vector signed int) __builtin_altivec_vctsxs ((__vector float) a1, a2); +} + +/* vec_ctu */ + +inline __vector unsigned int +vec_ctu (__vector float a1, const int a2) +{ + return (__vector unsigned int) __builtin_altivec_vctuxs ((__vector float) a1, a2); +} + +/* vec_dss */ + +inline void +vec_dss (const int a1) +{ + __builtin_altivec_dss (a1); +} + +/* vec_dssall */ + +inline void +vec_dssall (void) +{ + __builtin_altivec_dssall (); +} + +/* vec_dst */ + +inline void +vec_dst (const __vector unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector __bool char *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector signed short *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector __bool short *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector __pixel *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector signed int *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector __bool int *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const __vector float *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const short *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const int *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const unsigned long *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const long *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +inline void +vec_dst (const float *a1, int a2, const int a3) +{ + __builtin_altivec_dst ((void *) a1, a2, a3); +} + +/* vec_dstst */ + +inline void +vec_dstst (const __vector unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector __bool char *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector signed short *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector __bool short *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector __pixel *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector signed int *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector __bool int *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const __vector float *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const short *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const int *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const unsigned long *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const long *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +inline void +vec_dstst (const float *a1, int a2, const int a3) +{ + __builtin_altivec_dstst ((void *) a1, a2, a3); +} + +/* vec_dststt */ + +inline void +vec_dststt (const __vector unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector __bool char *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector signed short *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector __bool short *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector __pixel *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector signed int *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector __bool int *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const __vector float *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const short *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const int *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const unsigned long *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const long *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +inline void +vec_dststt (const float *a1, int a2, const int a3) +{ + __builtin_altivec_dststt ((void *) a1, a2, a3); +} + +/* vec_dstt */ + +inline void +vec_dstt (const __vector unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector __bool char *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector signed short *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector __bool short *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector __pixel *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector signed int *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector __bool int *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const __vector float *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const unsigned char *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const signed char *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const unsigned short *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const short *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const unsigned int *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const int *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const unsigned long *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const long *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +inline void +vec_dstt (const float *a1, int a2, const int a3) +{ + __builtin_altivec_dstt ((void *) a1, a2, a3); +} + +/* vec_expte */ + +inline __vector float +vec_expte (__vector float a1) +{ + return (__vector float) __builtin_altivec_vexptefp ((__vector float) a1); +} + +/* vec_floor */ + +inline __vector float +vec_floor (__vector float a1) +{ + return (__vector float) __builtin_altivec_vrfim ((__vector float) a1); +} + +/* vec_ld */ + +inline __vector float +vec_ld (int a1, const __vector float *a2) +{ + return (__vector float) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector float +vec_ld (int a1, const float *a2) +{ + return (__vector float) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector __bool int +vec_ld (int a1, const __vector __bool int *a2) +{ + return (__vector __bool int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed int +vec_ld (int a1, const __vector signed int *a2) +{ + return (__vector signed int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed int +vec_ld (int a1, const int *a2) +{ + return (__vector signed int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed int +vec_ld (int a1, const long *a2) +{ + return (__vector signed int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_ld (int a1, const __vector unsigned int *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_ld (int a1, const unsigned int *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_ld (int a1, const unsigned long *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector __bool short +vec_ld (int a1, const __vector __bool short *a2) +{ + return (__vector __bool short) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector __pixel +vec_ld (int a1, const __vector __pixel *a2) +{ + return (__vector __pixel) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed short +vec_ld (int a1, const __vector signed short *a2) +{ + return (__vector signed short) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed short +vec_ld (int a1, const short *a2) +{ + return (__vector signed short) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned short +vec_ld (int a1, const __vector unsigned short *a2) +{ + return (__vector unsigned short) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned short +vec_ld (int a1, const unsigned short *a2) +{ + return (__vector unsigned short) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector __bool char +vec_ld (int a1, const __vector __bool char *a2) +{ + return (__vector __bool char) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed char +vec_ld (int a1, const __vector signed char *a2) +{ + return (__vector signed char) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector signed char +vec_ld (int a1, const signed char *a2) +{ + return (__vector signed char) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned char +vec_ld (int a1, const __vector unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvx (a1, (void *) a2); +} + +inline __vector unsigned char +vec_ld (int a1, const unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvx (a1, (void *) a2); +} + +/* vec_lde */ + +inline __vector signed char +vec_lde (int a1, const signed char *a2) +{ + return (__vector signed char) __builtin_altivec_lvebx (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lde (int a1, const unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvebx (a1, (void *) a2); +} + +inline __vector signed short +vec_lde (int a1, const short *a2) +{ + return (__vector signed short) __builtin_altivec_lvehx (a1, (void *) a2); +} + +inline __vector unsigned short +vec_lde (int a1, const unsigned short *a2) +{ + return (__vector unsigned short) __builtin_altivec_lvehx (a1, (void *) a2); +} + +inline __vector float +vec_lde (int a1, const float *a2) +{ + return (__vector float) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector signed int +vec_lde (int a1, const int *a2) +{ + return (__vector signed int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_lde (int a1, const unsigned int *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector signed int +vec_lde (int a1, const long *a2) +{ + return (__vector signed int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_lde (int a1, const unsigned long *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +/* vec_lvewx */ + +inline __vector float +vec_lvewx (int a1, float *a2) +{ + return (__vector float) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector signed int +vec_lvewx (int a1, int *a2) +{ + return (__vector signed int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_lvewx (int a1, unsigned int *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector signed int +vec_lvewx (int a1, long *a2) +{ + return (__vector signed int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +inline __vector unsigned int +vec_lvewx (int a1, unsigned long *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvewx (a1, (void *) a2); +} + +/* vec_lvehx */ + +inline __vector signed short +vec_lvehx (int a1, short *a2) +{ + return (__vector signed short) __builtin_altivec_lvehx (a1, (void *) a2); +} + +inline __vector unsigned short +vec_lvehx (int a1, unsigned short *a2) +{ + return (__vector unsigned short) __builtin_altivec_lvehx (a1, (void *) a2); +} + +/* vec_lvebx */ + +inline __vector signed char +vec_lvebx (int a1, signed char *a2) +{ + return (__vector signed char) __builtin_altivec_lvebx (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvebx (int a1, unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvebx (a1, (void *) a2); +} + +/* vec_ldl */ + +inline __vector float +vec_ldl (int a1, const __vector float *a2) +{ + return (__vector float) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector float +vec_ldl (int a1, const float *a2) +{ + return (__vector float) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector __bool int +vec_ldl (int a1, const __vector __bool int *a2) +{ + return (__vector __bool int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed int +vec_ldl (int a1, const __vector signed int *a2) +{ + return (__vector signed int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed int +vec_ldl (int a1, const int *a2) +{ + return (__vector signed int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed int +vec_ldl (int a1, const long *a2) +{ + return (__vector signed int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned int +vec_ldl (int a1, const __vector unsigned int *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned int +vec_ldl (int a1, const unsigned int *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned int +vec_ldl (int a1, const unsigned long *a2) +{ + return (__vector unsigned int) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector __bool short +vec_ldl (int a1, const __vector __bool short *a2) +{ + return (__vector __bool short) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector __pixel +vec_ldl (int a1, const __vector __pixel *a2) +{ + return (__vector __pixel) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed short +vec_ldl (int a1, const __vector signed short *a2) +{ + return (__vector signed short) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed short +vec_ldl (int a1, const short *a2) +{ + return (__vector signed short) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned short +vec_ldl (int a1, const __vector unsigned short *a2) +{ + return (__vector unsigned short) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned short +vec_ldl (int a1, const unsigned short *a2) +{ + return (__vector unsigned short) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector __bool char +vec_ldl (int a1, const __vector __bool char *a2) +{ + return (__vector __bool char) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed char +vec_ldl (int a1, const __vector signed char *a2) +{ + return (__vector signed char) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector signed char +vec_ldl (int a1, const signed char *a2) +{ + return (__vector signed char) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_ldl (int a1, const __vector unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvxl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_ldl (int a1, const unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvxl (a1, (void *) a2); +} + +/* vec_loge */ + +inline __vector float +vec_loge (__vector float a1) +{ + return (__vector float) __builtin_altivec_vlogefp ((__vector float) a1); +} + +/* vec_lvsl */ + +inline __vector unsigned char +vec_lvsl (int a1, const volatile unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile signed char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile unsigned short *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile short *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile unsigned int *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile int *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile unsigned long *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile long *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsl (int a1, const volatile float *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsl (a1, (void *) a2); +} + +/* vec_lvsr */ + +inline __vector unsigned char +vec_lvsr (int a1, const volatile unsigned char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile signed char *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile unsigned short *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile short *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile unsigned int *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile int *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile unsigned long *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile long *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +inline __vector unsigned char +vec_lvsr (int a1, const volatile float *a2) +{ + return (__vector unsigned char) __builtin_altivec_lvsr (a1, (void *) a2); +} + +/* vec_madd */ + +inline __vector float +vec_madd (__vector float a1, __vector float a2, __vector float a3) +{ + return (__vector float) __builtin_altivec_vmaddfp ((__vector float) a1, (__vector float) a2, (__vector float) a3); +} + +/* vec_madds */ + +inline __vector signed short +vec_madds (__vector signed short a1, __vector signed short a2, __vector signed short a3) +{ + return (__vector signed short) __builtin_altivec_vmhaddshs ((__vector signed short) a1, (__vector signed short) a2, (__vector signed short) a3); +} + +/* vec_max */ + +inline __vector unsigned char +vec_max (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_max (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_max (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_max (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_max (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_max (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned short +vec_max (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_max (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_max (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_max (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_max (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_max (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned int +vec_max (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_max (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_max (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_max (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_max (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_max (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_max (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vmaxfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vmaxfp */ + +inline __vector float +vec_vmaxfp (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vmaxfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vmaxsw */ + +inline __vector signed int +vec_vmaxsw (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vmaxsw (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vmaxsw (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vmaxuw */ + +inline __vector unsigned int +vec_vmaxuw (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vmaxuw (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vmaxuw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vmaxsh */ + +inline __vector signed short +vec_vmaxsh (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vmaxsh (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vmaxsh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmaxuh */ + +inline __vector unsigned short +vec_vmaxuh (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vmaxuh (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vmaxuh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmaxsb */ + +inline __vector signed char +vec_vmaxsb (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vmaxsb (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vmaxsb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vmaxub */ + +inline __vector unsigned char +vec_vmaxub (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vmaxub (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vmaxub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_mergeh */ + +inline __vector __bool char +vec_mergeh (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vmrghb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_mergeh (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmrghb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_mergeh (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmrghb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool short +vec_mergeh (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __pixel +vec_mergeh (__vector __pixel a1, __vector __pixel a2) +{ + return (__vector __pixel) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_mergeh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_mergeh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector float +vec_mergeh (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_mergeh (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_mergeh (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_mergeh (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vmrghw */ + +inline __vector float +vec_vmrghw (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_vmrghw (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vmrghw (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vmrghw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmrghw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vmrghh */ + +inline __vector __bool short +vec_vmrghh (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vmrghh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vmrghh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __pixel +vec_vmrghh (__vector __pixel a1, __vector __pixel a2) +{ + return (__vector __pixel) __builtin_altivec_vmrghh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmrghb */ + +inline __vector __bool char +vec_vmrghb (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vmrghb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vmrghb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmrghb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vmrghb (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmrghb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_mergel */ + +inline __vector __bool char +vec_mergel (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vmrglb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_mergel (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmrglb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_mergel (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmrglb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector __bool short +vec_mergel (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __pixel +vec_mergel (__vector __pixel a1, __vector __pixel a2) +{ + return (__vector __pixel) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_mergel (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_mergel (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector float +vec_mergel (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_mergel (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_mergel (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_mergel (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vmrglw */ + +inline __vector float +vec_vmrglw (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vmrglw (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vmrglw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_vmrglw (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vmrglw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vmrglh */ + +inline __vector __bool short +vec_vmrglh (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vmrglh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vmrglh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __pixel +vec_vmrglh (__vector __pixel a1, __vector __pixel a2) +{ + return (__vector __pixel) __builtin_altivec_vmrglh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmrglb */ + +inline __vector __bool char +vec_vmrglb (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vmrglb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vmrglb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vmrglb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vmrglb (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vmrglb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_mfvscr */ + +inline __vector unsigned short +vec_mfvscr (void) +{ + return (__vector unsigned short) __builtin_altivec_mfvscr (); +} + +/* vec_min */ + +inline __vector unsigned char +vec_min (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_min (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_min (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_min (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vminsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_min (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vminsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_min (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vminsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned short +vec_min (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_min (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_min (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_min (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vminsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_min (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vminsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_min (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vminsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned int +vec_min (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_min (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_min (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_min (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vminsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_min (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vminsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_min (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vminsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_min (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vminfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vminfp */ + +inline __vector float +vec_vminfp (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vminfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vminsw */ + +inline __vector signed int +vec_vminsw (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vminsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vminsw (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vminsw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vminsw (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vminsw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vminuw */ + +inline __vector unsigned int +vec_vminuw (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vminuw (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vminuw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vminsh */ + +inline __vector signed short +vec_vminsh (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vminsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vminsh (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vminsh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vminsh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vminsh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vminuh */ + +inline __vector unsigned short +vec_vminuh (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vminuh (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vminuh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vminsb */ + +inline __vector signed char +vec_vminsb (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vminsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vminsb (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vminsb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vminsb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vminsb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vminub */ + +inline __vector unsigned char +vec_vminub (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vminub (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vminub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_mladd */ + +inline __vector signed short +vec_mladd (__vector signed short a1, __vector signed short a2, __vector signed short a3) +{ + return (__vector signed short) __builtin_altivec_vmladduhm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed short) a3); +} + +inline __vector signed short +vec_mladd (__vector signed short a1, __vector unsigned short a2, __vector unsigned short a3) +{ + return (__vector signed short) __builtin_altivec_vmladduhm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed short) a3); +} + +inline __vector signed short +vec_mladd (__vector unsigned short a1, __vector signed short a2, __vector signed short a3) +{ + return (__vector signed short) __builtin_altivec_vmladduhm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed short) a3); +} + +inline __vector unsigned short +vec_mladd (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned short a3) +{ + return (__vector unsigned short) __builtin_altivec_vmladduhm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed short) a3); +} + +/* vec_mradds */ + +inline __vector signed short +vec_mradds (__vector signed short a1, __vector signed short a2, __vector signed short a3) +{ + return (__vector signed short) __builtin_altivec_vmhraddshs ((__vector signed short) a1, (__vector signed short) a2, (__vector signed short) a3); +} + +/* vec_msum */ + +inline __vector unsigned int +vec_msum (__vector unsigned char a1, __vector unsigned char a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vmsumubm ((__vector signed char) a1, (__vector signed char) a2, (__vector signed int) a3); +} + +inline __vector signed int +vec_msum (__vector signed char a1, __vector unsigned char a2, __vector signed int a3) +{ + return (__vector signed int) __builtin_altivec_vmsummbm ((__vector signed char) a1, (__vector signed char) a2, (__vector signed int) a3); +} + +inline __vector unsigned int +vec_msum (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vmsumuhm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +inline __vector signed int +vec_msum (__vector signed short a1, __vector signed short a2, __vector signed int a3) +{ + return (__vector signed int) __builtin_altivec_vmsumshm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +/* vec_vmsumshm */ + +inline __vector signed int +vec_vmsumshm (__vector signed short a1, __vector signed short a2, __vector signed int a3) +{ + return (__vector signed int) __builtin_altivec_vmsumshm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +/* vec_vmsumuhm */ + +inline __vector unsigned int +vec_vmsumuhm (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vmsumuhm ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +/* vec_vmsummbm */ + +inline __vector signed int +vec_vmsummbm (__vector signed char a1, __vector unsigned char a2, __vector signed int a3) +{ + return (__vector signed int) __builtin_altivec_vmsummbm ((__vector signed char) a1, (__vector signed char) a2, (__vector signed int) a3); +} + +/* vec_vmsumubm */ + +inline __vector unsigned int +vec_vmsumubm (__vector unsigned char a1, __vector unsigned char a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vmsumubm ((__vector signed char) a1, (__vector signed char) a2, (__vector signed int) a3); +} + +/* vec_msums */ + +inline __vector unsigned int +vec_msums (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vmsumuhs ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +inline __vector signed int +vec_msums (__vector signed short a1, __vector signed short a2, __vector signed int a3) +{ + return (__vector signed int) __builtin_altivec_vmsumshs ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +/* vec_vmsumshs */ + +inline __vector signed int +vec_vmsumshs (__vector signed short a1, __vector signed short a2, __vector signed int a3) +{ + return (__vector signed int) __builtin_altivec_vmsumshs ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +/* vec_vmsumuhs */ + +inline __vector unsigned int +vec_vmsumuhs (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vmsumuhs ((__vector signed short) a1, (__vector signed short) a2, (__vector signed int) a3); +} + +/* vec_mtvscr */ + +inline void +vec_mtvscr (__vector signed int a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector unsigned int a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector __bool int a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector signed short a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector unsigned short a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector __bool short a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector __pixel a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector signed char a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector unsigned char a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +inline void +vec_mtvscr (__vector __bool char a1) +{ + __builtin_altivec_mtvscr ((__vector signed int) a1); +} + +/* vec_mule */ + +inline __vector unsigned short +vec_mule (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vmuleub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_mule (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed short) __builtin_altivec_vmulesb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned int +vec_mule (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned int) __builtin_altivec_vmuleuh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_mule (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed int) __builtin_altivec_vmulesh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmulesh */ + +inline __vector signed int +vec_vmulesh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed int) __builtin_altivec_vmulesh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmuleuh */ + +inline __vector unsigned int +vec_vmuleuh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned int) __builtin_altivec_vmuleuh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmulesb */ + +inline __vector signed short +vec_vmulesb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed short) __builtin_altivec_vmuleub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vmuleub */ + +inline __vector unsigned short +vec_vmuleub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vmuleub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_mulo */ + +inline __vector unsigned short +vec_mulo (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vmuloub ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_mulo (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed short) __builtin_altivec_vmulosb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned int +vec_mulo (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned int) __builtin_altivec_vmulouh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_mulo (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed int) __builtin_altivec_vmulosh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmulosh */ + +inline __vector signed int +vec_vmulosh (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed int) __builtin_altivec_vmulosh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmulouh */ + +inline __vector unsigned int +vec_vmulouh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned int) __builtin_altivec_vmulouh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vmulosb */ + +inline __vector signed short +vec_vmulosb (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed short) __builtin_altivec_vmulosb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vmuloub */ + +inline __vector unsigned short +vec_vmuloub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vmuloub ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_nmsub */ + +inline __vector float +vec_nmsub (__vector float a1, __vector float a2, __vector float a3) +{ + return (__vector float) __builtin_altivec_vnmsubfp ((__vector float) a1, (__vector float) a2, (__vector float) a3); +} + +/* vec_nor */ + +inline __vector float +vec_nor (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_nor (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_nor (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_nor (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_nor (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_nor (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_nor (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_nor (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_nor (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_nor (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vnor ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_or */ + +inline __vector float +vec_or (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_or (__vector float a1, __vector __bool int a2) +{ + return (__vector float) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_or (__vector __bool int a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_or (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_or (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_or (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_or (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_or (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_or (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_or (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_or (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_or (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_or (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_or (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_or (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_or (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_or (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_or (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_or (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_or (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_or (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_or (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_or (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_or (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vor ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_pack */ + +inline __vector signed char +vec_pack (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed char) __builtin_altivec_vpkuhum ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned char +vec_pack (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkuhum ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector __bool char +vec_pack (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool char) __builtin_altivec_vpkuhum ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_pack (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed short) __builtin_altivec_vpkuwum ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_pack (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkuwum ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_pack (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool short) __builtin_altivec_vpkuwum ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkuwum */ + +inline __vector __bool short +vec_vpkuwum (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool short) __builtin_altivec_vpkuwum ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_vpkuwum (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed short) __builtin_altivec_vpkuwum ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_vpkuwum (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkuwum ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkuhum */ + +inline __vector __bool char +vec_vpkuhum (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool char) __builtin_altivec_vpkuhum ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed char +vec_vpkuhum (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed char) __builtin_altivec_vpkuhum ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned char +vec_vpkuhum (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkuhum ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_packpx */ + +inline __vector __pixel +vec_packpx (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector __pixel) __builtin_altivec_vpkpx ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_packs */ + +inline __vector unsigned char +vec_packs (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkuhus ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed char +vec_packs (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed char) __builtin_altivec_vpkshss ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_packs (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkuwus ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_packs (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed short) __builtin_altivec_vpkswss ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkswss */ + +inline __vector signed short +vec_vpkswss (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed short) __builtin_altivec_vpkswss ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkuwus */ + +inline __vector unsigned short +vec_vpkuwus (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkuwus ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkshss */ + +inline __vector signed char +vec_vpkshss (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed char) __builtin_altivec_vpkshss ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vpkuhus */ + +inline __vector unsigned char +vec_vpkuhus (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkuhus ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_packsu */ + +inline __vector unsigned char +vec_packsu (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkuhus ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned char +vec_packsu (__vector signed short a1, __vector signed short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkshus ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_packsu (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkuwus ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_packsu (__vector signed int a1, __vector signed int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkswus ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkswus */ + +inline __vector unsigned short +vec_vpkswus (__vector signed int a1, __vector signed int a2) +{ + return (__vector unsigned short) __builtin_altivec_vpkswus ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vpkshus */ + +inline __vector unsigned char +vec_vpkshus (__vector signed short a1, __vector signed short a2) +{ + return (__vector unsigned char) __builtin_altivec_vpkshus ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_perm */ + +inline __vector float +vec_perm (__vector float a1, __vector float a2, __vector unsigned char a3) +{ + return (__vector float) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector signed int +vec_perm (__vector signed int a1, __vector signed int a2, __vector unsigned char a3) +{ + return (__vector signed int) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector unsigned int +vec_perm (__vector unsigned int a1, __vector unsigned int a2, __vector unsigned char a3) +{ + return (__vector unsigned int) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector __bool int +vec_perm (__vector __bool int a1, __vector __bool int a2, __vector unsigned char a3) +{ + return (__vector __bool int) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector signed short +vec_perm (__vector signed short a1, __vector signed short a2, __vector unsigned char a3) +{ + return (__vector signed short) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector unsigned short +vec_perm (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned char a3) +{ + return (__vector unsigned short) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector __bool short +vec_perm (__vector __bool short a1, __vector __bool short a2, __vector unsigned char a3) +{ + return (__vector __bool short) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector __pixel +vec_perm (__vector __pixel a1, __vector __pixel a2, __vector unsigned char a3) +{ + return (__vector __pixel) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector signed char +vec_perm (__vector signed char a1, __vector signed char a2, __vector unsigned char a3) +{ + return (__vector signed char) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector unsigned char +vec_perm (__vector unsigned char a1, __vector unsigned char a2, __vector unsigned char a3) +{ + return (__vector unsigned char) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +inline __vector __bool char +vec_perm (__vector __bool char a1, __vector __bool char a2, __vector unsigned char a3) +{ + return (__vector __bool char) __builtin_altivec_vperm_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed char) a3); +} + +/* vec_re */ + +inline __vector float +vec_re (__vector float a1) +{ + return (__vector float) __builtin_altivec_vrefp ((__vector float) a1); +} + +/* vec_rl */ + +inline __vector signed char +vec_rl (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vrlb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_rl (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vrlb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_rl (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vrlh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_rl (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vrlh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_rl (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vrlw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_rl (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vrlw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vrlw */ + +inline __vector signed int +vec_vrlw (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vrlw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vrlw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vrlw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vrlh */ + +inline __vector signed short +vec_vrlh (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vrlh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vrlh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vrlh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vrlb */ + +inline __vector signed char +vec_vrlb (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vrlb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vrlb (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vrlb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_round */ + +inline __vector float +vec_round (__vector float a1) +{ + return (__vector float) __builtin_altivec_vrfin ((__vector float) a1); +} + +/* vec_rsqrte */ + +inline __vector float +vec_rsqrte (__vector float a1) +{ + return (__vector float) __builtin_altivec_vrsqrtefp ((__vector float) a1); +} + +/* vec_sel */ + +inline __vector float +vec_sel (__vector float a1, __vector float a2, __vector __bool int a3) +{ + return (__vector float) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector float +vec_sel (__vector float a1, __vector float a2, __vector unsigned int a3) +{ + return (__vector float) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector signed int +vec_sel (__vector signed int a1, __vector signed int a2, __vector __bool int a3) +{ + return (__vector signed int) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector signed int +vec_sel (__vector signed int a1, __vector signed int a2, __vector unsigned int a3) +{ + return (__vector signed int) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector unsigned int +vec_sel (__vector unsigned int a1, __vector unsigned int a2, __vector __bool int a3) +{ + return (__vector unsigned int) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector unsigned int +vec_sel (__vector unsigned int a1, __vector unsigned int a2, __vector unsigned int a3) +{ + return (__vector unsigned int) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector __bool int +vec_sel (__vector __bool int a1, __vector __bool int a2, __vector __bool int a3) +{ + return (__vector __bool int) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector __bool int +vec_sel (__vector __bool int a1, __vector __bool int a2, __vector unsigned int a3) +{ + return (__vector __bool int) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector signed short +vec_sel (__vector signed short a1, __vector signed short a2, __vector __bool short a3) +{ + return (__vector signed short) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector signed short +vec_sel (__vector signed short a1, __vector signed short a2, __vector unsigned short a3) +{ + return (__vector signed short) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector unsigned short +vec_sel (__vector unsigned short a1, __vector unsigned short a2, __vector __bool short a3) +{ + return (__vector unsigned short) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector unsigned short +vec_sel (__vector unsigned short a1, __vector unsigned short a2, __vector unsigned short a3) +{ + return (__vector unsigned short) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector __bool short +vec_sel (__vector __bool short a1, __vector __bool short a2, __vector __bool short a3) +{ + return (__vector __bool short) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector __bool short +vec_sel (__vector __bool short a1, __vector __bool short a2, __vector unsigned short a3) +{ + return (__vector __bool short) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector signed char +vec_sel (__vector signed char a1, __vector signed char a2, __vector __bool char a3) +{ + return (__vector signed char) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector signed char +vec_sel (__vector signed char a1, __vector signed char a2, __vector unsigned char a3) +{ + return (__vector signed char) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector unsigned char +vec_sel (__vector unsigned char a1, __vector unsigned char a2, __vector __bool char a3) +{ + return (__vector unsigned char) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector unsigned char +vec_sel (__vector unsigned char a1, __vector unsigned char a2, __vector unsigned char a3) +{ + return (__vector unsigned char) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector __bool char +vec_sel (__vector __bool char a1, __vector __bool char a2, __vector __bool char a3) +{ + return (__vector __bool char) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +inline __vector __bool char +vec_sel (__vector __bool char a1, __vector __bool char a2, __vector unsigned char a3) +{ + return (__vector __bool char) __builtin_altivec_vsel_4si ((__vector signed int) a1, (__vector signed int) a2, (__vector signed int) a3); +} + +/* vec_sl */ + +inline __vector signed char +vec_sl (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vslb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_sl (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vslb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_sl (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vslh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_sl (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vslh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_sl (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vslw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sl (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vslw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vslw */ + +inline __vector signed int +vec_vslw (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vslw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vslw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vslw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vslh */ + +inline __vector signed short +vec_vslh (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vslh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vslh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vslh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vslb */ + +inline __vector signed char +vec_vslb (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vslb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vslb (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vslb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_sld */ + +inline __vector float +vec_sld (__vector float a1, __vector float a2, const int a3) +{ + return (__vector float) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector signed int +vec_sld (__vector signed int a1, __vector signed int a2, const int a3) +{ + return (__vector signed int) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector unsigned int +vec_sld (__vector unsigned int a1, __vector unsigned int a2, const int a3) +{ + return (__vector unsigned int) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector __bool int +vec_sld (__vector __bool int a1, __vector __bool int a2, const int a3) +{ + return (__vector __bool int) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector signed short +vec_sld (__vector signed short a1, __vector signed short a2, const int a3) +{ + return (__vector signed short) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector unsigned short +vec_sld (__vector unsigned short a1, __vector unsigned short a2, const int a3) +{ + return (__vector unsigned short) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector __bool short +vec_sld (__vector __bool short a1, __vector __bool short a2, const int a3) +{ + return (__vector __bool short) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector __pixel +vec_sld (__vector __pixel a1, __vector __pixel a2, const int a3) +{ + return (__vector __pixel) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector signed char +vec_sld (__vector signed char a1, __vector signed char a2, const int a3) +{ + return (__vector signed char) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector unsigned char +vec_sld (__vector unsigned char a1, __vector unsigned char a2, const int a3) +{ + return (__vector unsigned char) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +inline __vector __bool char +vec_sld (__vector __bool char a1, __vector __bool char a2, const int a3) +{ + return (__vector __bool char) __builtin_altivec_vsldoi_4si ((__vector signed int) a1, (__vector signed int) a2, a3); +} + +/* vec_sll */ + +inline __vector signed int +vec_sll (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sll (__vector signed int a1, __vector unsigned short a2) +{ + return (__vector signed int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sll (__vector signed int a1, __vector unsigned char a2) +{ + return (__vector signed int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sll (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sll (__vector unsigned int a1, __vector unsigned short a2) +{ + return (__vector unsigned int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sll (__vector unsigned int a1, __vector unsigned char a2) +{ + return (__vector unsigned int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_sll (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_sll (__vector __bool int a1, __vector unsigned short a2) +{ + return (__vector __bool int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_sll (__vector __bool int a1, __vector unsigned char a2) +{ + return (__vector __bool int) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_sll (__vector signed short a1, __vector unsigned int a2) +{ + return (__vector signed short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_sll (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_sll (__vector signed short a1, __vector unsigned char a2) +{ + return (__vector signed short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_sll (__vector unsigned short a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_sll (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_sll (__vector unsigned short a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_sll (__vector __bool short a1, __vector unsigned int a2) +{ + return (__vector __bool short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_sll (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_sll (__vector __bool short a1, __vector unsigned char a2) +{ + return (__vector __bool short) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_sll (__vector __pixel a1, __vector unsigned int a2) +{ + return (__vector __pixel) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_sll (__vector __pixel a1, __vector unsigned short a2) +{ + return (__vector __pixel) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_sll (__vector __pixel a1, __vector unsigned char a2) +{ + return (__vector __pixel) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_sll (__vector signed char a1, __vector unsigned int a2) +{ + return (__vector signed char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_sll (__vector signed char a1, __vector unsigned short a2) +{ + return (__vector signed char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_sll (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_sll (__vector unsigned char a1, __vector unsigned int a2) +{ + return (__vector unsigned char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_sll (__vector unsigned char a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_sll (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_sll (__vector __bool char a1, __vector unsigned int a2) +{ + return (__vector __bool char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_sll (__vector __bool char a1, __vector unsigned short a2) +{ + return (__vector __bool char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_sll (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vsl ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_slo */ + +inline __vector float +vec_slo (__vector float a1, __vector signed char a2) +{ + return (__vector float) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_slo (__vector float a1, __vector unsigned char a2) +{ + return (__vector float) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_slo (__vector signed int a1, __vector signed char a2) +{ + return (__vector signed int) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_slo (__vector signed int a1, __vector unsigned char a2) +{ + return (__vector signed int) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_slo (__vector unsigned int a1, __vector signed char a2) +{ + return (__vector unsigned int) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_slo (__vector unsigned int a1, __vector unsigned char a2) +{ + return (__vector unsigned int) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_slo (__vector signed short a1, __vector signed char a2) +{ + return (__vector signed short) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_slo (__vector signed short a1, __vector unsigned char a2) +{ + return (__vector signed short) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_slo (__vector unsigned short a1, __vector signed char a2) +{ + return (__vector unsigned short) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_slo (__vector unsigned short a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_slo (__vector __pixel a1, __vector signed char a2) +{ + return (__vector __pixel) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_slo (__vector __pixel a1, __vector unsigned char a2) +{ + return (__vector __pixel) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_slo (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_slo (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_slo (__vector unsigned char a1, __vector signed char a2) +{ + return (__vector unsigned char) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_slo (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vslo ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_splat */ + +inline __vector signed char +vec_splat (__vector signed char a1, const int a2) +{ + return (__vector signed char) __builtin_altivec_vspltb ((__vector signed char) a1, a2); +} + +inline __vector unsigned char +vec_splat (__vector unsigned char a1, const int a2) +{ + return (__vector unsigned char) __builtin_altivec_vspltb ((__vector signed char) a1, a2); +} + +inline __vector __bool char +vec_splat (__vector __bool char a1, const int a2) +{ + return (__vector __bool char) __builtin_altivec_vspltb ((__vector signed char) a1, a2); +} + +inline __vector signed short +vec_splat (__vector signed short a1, const int a2) +{ + return (__vector signed short) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector unsigned short +vec_splat (__vector unsigned short a1, const int a2) +{ + return (__vector unsigned short) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector __bool short +vec_splat (__vector __bool short a1, const int a2) +{ + return (__vector __bool short) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector __pixel +vec_splat (__vector __pixel a1, const int a2) +{ + return (__vector __pixel) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector float +vec_splat (__vector float a1, const int a2) +{ + return (__vector float) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +inline __vector signed int +vec_splat (__vector signed int a1, const int a2) +{ + return (__vector signed int) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +inline __vector unsigned int +vec_splat (__vector unsigned int a1, const int a2) +{ + return (__vector unsigned int) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +inline __vector __bool int +vec_splat (__vector __bool int a1, const int a2) +{ + return (__vector __bool int) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +/* vec_vspltw */ + +inline __vector float +vec_vspltw (__vector float a1, const int a2) +{ + return (__vector float) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +inline __vector signed int +vec_vspltw (__vector signed int a1, const int a2) +{ + return (__vector signed int) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +inline __vector unsigned int +vec_vspltw (__vector unsigned int a1, const int a2) +{ + return (__vector unsigned int) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +inline __vector __bool int +vec_vspltw (__vector __bool int a1, const int a2) +{ + return (__vector __bool int) __builtin_altivec_vspltw ((__vector signed int) a1, a2); +} + +/* vec_vsplth */ + +inline __vector __bool short +vec_vsplth (__vector __bool short a1, const int a2) +{ + return (__vector __bool short) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector signed short +vec_vsplth (__vector signed short a1, const int a2) +{ + return (__vector signed short) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector unsigned short +vec_vsplth (__vector unsigned short a1, const int a2) +{ + return (__vector unsigned short) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +inline __vector __pixel +vec_vsplth (__vector __pixel a1, const int a2) +{ + return (__vector __pixel) __builtin_altivec_vsplth ((__vector signed short) a1, a2); +} + +/* vec_vspltb */ + +inline __vector signed char +vec_vspltb (__vector signed char a1, const int a2) +{ + return (__vector signed char) __builtin_altivec_vspltb ((__vector signed char) a1, a2); +} + +inline __vector unsigned char +vec_vspltb (__vector unsigned char a1, const int a2) +{ + return (__vector unsigned char) __builtin_altivec_vspltb ((__vector signed char) a1, a2); +} + +inline __vector __bool char +vec_vspltb (__vector __bool char a1, const int a2) +{ + return (__vector __bool char) __builtin_altivec_vspltb ((__vector signed char) a1, a2); +} + +/* vec_splat_s8 */ + +inline __vector signed char +vec_splat_s8 (const int a1) +{ + return (__vector signed char) __builtin_altivec_vspltisb (a1); +} + +/* vec_splat_s16 */ + +inline __vector signed short +vec_splat_s16 (const int a1) +{ + return (__vector signed short) __builtin_altivec_vspltish (a1); +} + +/* vec_splat_s32 */ + +inline __vector signed int +vec_splat_s32 (const int a1) +{ + return (__vector signed int) __builtin_altivec_vspltisw (a1); +} + +/* vec_splat_u8 */ + +inline __vector unsigned char +vec_splat_u8 (const int a1) +{ + return (__vector unsigned char) __builtin_altivec_vspltisb (a1); +} + +/* vec_splat_u16 */ + +inline __vector unsigned short +vec_splat_u16 (const int a1) +{ + return (__vector unsigned short) __builtin_altivec_vspltish (a1); +} + +/* vec_splat_u32 */ + +inline __vector unsigned int +vec_splat_u32 (const int a1) +{ + return (__vector unsigned int) __builtin_altivec_vspltisw (a1); +} + +/* vec_sr */ + +inline __vector signed char +vec_sr (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsrb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_sr (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsrb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_sr (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vsrh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_sr (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsrh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_sr (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vsrw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sr (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsrw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsrw */ + +inline __vector signed int +vec_vsrw (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vsrw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsrw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsrw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsrh */ + +inline __vector signed short +vec_vsrh (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vsrh ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsrh (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsrh ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vsrb */ + +inline __vector signed char +vec_vsrb (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsrb ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsrb (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsrb ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_sra */ + +inline __vector signed char +vec_sra (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsrab ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_sra (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsrab ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_sra (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vsrah ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_sra (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsrah ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_sra (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vsraw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sra (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsraw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsraw */ + +inline __vector signed int +vec_vsraw (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vsraw ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsraw (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsraw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsrah */ + +inline __vector signed short +vec_vsrah (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vsrah ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsrah (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsrah ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vsrab */ + +inline __vector signed char +vec_vsrab (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsrab ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsrab (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsrab ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_srl */ + +inline __vector signed int +vec_srl (__vector signed int a1, __vector unsigned int a2) +{ + return (__vector signed int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_srl (__vector signed int a1, __vector unsigned short a2) +{ + return (__vector signed int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_srl (__vector signed int a1, __vector unsigned char a2) +{ + return (__vector signed int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_srl (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_srl (__vector unsigned int a1, __vector unsigned short a2) +{ + return (__vector unsigned int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_srl (__vector unsigned int a1, __vector unsigned char a2) +{ + return (__vector unsigned int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_srl (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector __bool int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_srl (__vector __bool int a1, __vector unsigned short a2) +{ + return (__vector __bool int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_srl (__vector __bool int a1, __vector unsigned char a2) +{ + return (__vector __bool int) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_srl (__vector signed short a1, __vector unsigned int a2) +{ + return (__vector signed short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_srl (__vector signed short a1, __vector unsigned short a2) +{ + return (__vector signed short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_srl (__vector signed short a1, __vector unsigned char a2) +{ + return (__vector signed short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_srl (__vector unsigned short a1, __vector unsigned int a2) +{ + return (__vector unsigned short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_srl (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_srl (__vector unsigned short a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_srl (__vector __bool short a1, __vector unsigned int a2) +{ + return (__vector __bool short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_srl (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector __bool short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_srl (__vector __bool short a1, __vector unsigned char a2) +{ + return (__vector __bool short) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_srl (__vector __pixel a1, __vector unsigned int a2) +{ + return (__vector __pixel) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_srl (__vector __pixel a1, __vector unsigned short a2) +{ + return (__vector __pixel) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_srl (__vector __pixel a1, __vector unsigned char a2) +{ + return (__vector __pixel) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_srl (__vector signed char a1, __vector unsigned int a2) +{ + return (__vector signed char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_srl (__vector signed char a1, __vector unsigned short a2) +{ + return (__vector signed char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_srl (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_srl (__vector unsigned char a1, __vector unsigned int a2) +{ + return (__vector unsigned char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_srl (__vector unsigned char a1, __vector unsigned short a2) +{ + return (__vector unsigned char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_srl (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_srl (__vector __bool char a1, __vector unsigned int a2) +{ + return (__vector __bool char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_srl (__vector __bool char a1, __vector unsigned short a2) +{ + return (__vector __bool char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_srl (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector __bool char) __builtin_altivec_vsr ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_sro */ + +inline __vector float +vec_sro (__vector float a1, __vector signed char a2) +{ + return (__vector float) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_sro (__vector float a1, __vector unsigned char a2) +{ + return (__vector float) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sro (__vector signed int a1, __vector signed char a2) +{ + return (__vector signed int) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sro (__vector signed int a1, __vector unsigned char a2) +{ + return (__vector signed int) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sro (__vector unsigned int a1, __vector signed char a2) +{ + return (__vector unsigned int) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sro (__vector unsigned int a1, __vector unsigned char a2) +{ + return (__vector unsigned int) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_sro (__vector signed short a1, __vector signed char a2) +{ + return (__vector signed short) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_sro (__vector signed short a1, __vector unsigned char a2) +{ + return (__vector signed short) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_sro (__vector unsigned short a1, __vector signed char a2) +{ + return (__vector unsigned short) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_sro (__vector unsigned short a1, __vector unsigned char a2) +{ + return (__vector unsigned short) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_sro (__vector __pixel a1, __vector signed char a2) +{ + return (__vector __pixel) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __pixel +vec_sro (__vector __pixel a1, __vector unsigned char a2) +{ + return (__vector __pixel) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_sro (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_sro (__vector signed char a1, __vector unsigned char a2) +{ + return (__vector signed char) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_sro (__vector unsigned char a1, __vector signed char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_sro (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsro ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_st */ + +inline void +vec_st (__vector float a1, int a2, __vector float *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector float a1, int a2, float *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector signed int a1, int a2, __vector signed int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector signed int a1, int a2, int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector unsigned int a1, int a2, __vector unsigned int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector unsigned int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool int a1, int a2, __vector __bool int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool int a1, int a2, int *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector signed short a1, int a2, __vector signed short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector signed short a1, int a2, short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector unsigned short a1, int a2, __vector unsigned short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector unsigned short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool short a1, int a2, __vector __bool short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __pixel a1, int a2, __vector __pixel *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __pixel a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __pixel a1, int a2, short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool short a1, int a2, short *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector signed char a1, int a2, __vector signed char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector signed char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector unsigned char a1, int a2, __vector unsigned char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector unsigned char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool char a1, int a2, __vector __bool char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_st (__vector __bool char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvx ((__vector signed int) a1, a2, (void *) a3); +} + +/* vec_ste */ + +inline void +vec_ste (__vector signed char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector unsigned char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __bool char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __bool char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector signed short a1, int a2, short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector unsigned short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __bool short a1, int a2, short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __bool short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __pixel a1, int a2, short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __pixel a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector float a1, int a2, float *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector signed int a1, int a2, int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector unsigned int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __bool int a1, int a2, int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_ste (__vector __bool int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +/* vec_stvewx */ + +inline void +vec_stvewx (__vector float a1, int a2, float *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stvewx (__vector signed int a1, int a2, int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stvewx (__vector unsigned int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stvewx (__vector __bool int a1, int a2, int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stvewx (__vector __bool int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvewx ((__vector signed int) a1, a2, (void *) a3); +} + +/* vec_stvehx */ + +inline void +vec_stvehx (__vector signed short a1, int a2, short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_stvehx (__vector unsigned short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_stvehx (__vector __bool short a1, int a2, short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_stvehx (__vector __bool short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_stvehx (__vector __pixel a1, int a2, short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +inline void +vec_stvehx (__vector __pixel a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvehx ((__vector signed short) a1, a2, (void *) a3); +} + +/* vec_stvebx */ + +inline void +vec_stvebx (__vector signed char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_stvebx (__vector unsigned char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_stvebx (__vector __bool char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +inline void +vec_stvebx (__vector __bool char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvebx ((__vector signed char) a1, a2, (void *) a3); +} + +/* vec_stl */ + +inline void +vec_stl (__vector float a1, int a2, __vector float *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector float a1, int a2, float *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector signed int a1, int a2, __vector signed int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector signed int a1, int a2, int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector unsigned int a1, int a2, __vector unsigned int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector unsigned int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool int a1, int a2, __vector __bool int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool int a1, int a2, unsigned int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool int a1, int a2, int *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector signed short a1, int a2, __vector signed short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector signed short a1, int a2, short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector unsigned short a1, int a2, __vector unsigned short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector unsigned short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool short a1, int a2, __vector __bool short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool short a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool short a1, int a2, short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __pixel a1, int a2, __vector __pixel *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __pixel a1, int a2, unsigned short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __pixel a1, int a2, short *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector signed char a1, int a2, __vector signed char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector signed char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector unsigned char a1, int a2, __vector unsigned char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector unsigned char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool char a1, int a2, __vector __bool char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool char a1, int a2, unsigned char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +inline void +vec_stl (__vector __bool char a1, int a2, signed char *a3) +{ + __builtin_altivec_stvxl ((__vector signed int) a1, a2, (void *) a3); +} + +/* vec_sub */ + +inline __vector signed char +vec_sub (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_sub (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_sub (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_sub (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_sub (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_sub (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed short +vec_sub (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_sub (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_sub (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_sub (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_sub (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_sub (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed int +vec_sub (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sub (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sub (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sub (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sub (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_sub (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_sub (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vsubfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vsubfp */ + +inline __vector float +vec_vsubfp (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vsubfp ((__vector float) a1, (__vector float) a2); +} + +/* vec_vsubuwm */ + +inline __vector signed int +vec_vsubuwm (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vsubuwm (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vsubuwm (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsubuwm (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsubuwm (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsubuwm (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsubuhm */ + +inline __vector signed short +vec_vsubuhm (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vsubuhm (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vsubuhm (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsubuhm (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsubuhm (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsubuhm (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vsububm */ + +inline __vector signed char +vec_vsububm (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vsububm (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vsububm (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsububm (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsububm (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsububm (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_subc */ + +inline __vector unsigned int +vec_subc (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubcuw ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_subs */ + +inline __vector unsigned char +vec_subs (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_subs (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_subs (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_subs (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_subs (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_subs (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned short +vec_subs (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_subs (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_subs (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_subs (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_subs (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_subs (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned int +vec_subs (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_subs (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_subs (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_subs (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_subs (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_subs (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsubsws */ + +inline __vector signed int +vec_vsubsws (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vsubsws (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_vsubsws (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsubuws */ + +inline __vector unsigned int +vec_vsubuws (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsubuws (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_vsubuws (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_vsubshs */ + +inline __vector signed short +vec_vsubshs (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vsubshs (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector signed short +vec_vsubshs (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vsubuhs */ + +inline __vector unsigned short +vec_vsubuhs (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsubuhs (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) a1, (__vector signed short) a2); +} + +inline __vector unsigned short +vec_vsubuhs (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) a1, (__vector signed short) a2); +} + +/* vec_vsubsbs */ + +inline __vector signed char +vec_vsubsbs (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vsubsbs (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector signed char +vec_vsubsbs (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_vsububs */ + +inline __vector unsigned char +vec_vsububs (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsububs (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) a1, (__vector signed char) a2); +} + +inline __vector unsigned char +vec_vsububs (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) a1, (__vector signed char) a2); +} + +/* vec_sum4s */ + +inline __vector unsigned int +vec_sum4s (__vector unsigned char a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsum4ubs ((__vector signed char) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sum4s (__vector signed char a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsum4sbs ((__vector signed char) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_sum4s (__vector signed short a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsum4shs ((__vector signed short) a1, (__vector signed int) a2); +} + +/* vec_vsum4shs */ + +inline __vector signed int +vec_vsum4shs (__vector signed short a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsum4shs ((__vector signed short) a1, (__vector signed int) a2); +} + +/* vec_vsum4sbs */ + +inline __vector signed int +vec_vsum4sbs (__vector signed char a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsum4sbs ((__vector signed char) a1, (__vector signed int) a2); +} + +/* vec_vsum4ubs */ + +inline __vector unsigned int +vec_vsum4ubs (__vector unsigned char a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vsum4ubs ((__vector signed char) a1, (__vector signed int) a2); +} + +/* vec_sum2s */ + +inline __vector signed int +vec_sum2s (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsum2sws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_sums */ + +inline __vector signed int +vec_sums (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vsumsws ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_trunc */ + +inline __vector float +vec_trunc (__vector float a1) +{ + return (__vector float) __builtin_altivec_vrfiz ((__vector float) a1); +} + +/* vec_unpackh */ + +inline __vector signed short +vec_unpackh (__vector signed char a1) +{ + return (__vector signed short) __builtin_altivec_vupkhsb ((__vector signed char) a1); +} + +inline __vector __bool short +vec_unpackh (__vector __bool char a1) +{ + return (__vector __bool short) __builtin_altivec_vupkhsb ((__vector signed char) a1); +} + +inline __vector signed int +vec_unpackh (__vector signed short a1) +{ + return (__vector signed int) __builtin_altivec_vupkhsh ((__vector signed short) a1); +} + +inline __vector __bool int +vec_unpackh (__vector __bool short a1) +{ + return (__vector __bool int) __builtin_altivec_vupkhsh ((__vector signed short) a1); +} + +inline __vector unsigned int +vec_unpackh (__vector __pixel a1) +{ + return (__vector unsigned int) __builtin_altivec_vupkhpx ((__vector signed short) a1); +} + +/* vec_vupkhsh */ + +inline __vector __bool int +vec_vupkhsh (__vector __bool short a1) +{ + return (__vector __bool int) __builtin_altivec_vupkhsh ((__vector signed short) a1); +} + +inline __vector signed int +vec_vupkhsh (__vector signed short a1) +{ + return (__vector signed int) __builtin_altivec_vupkhsh ((__vector signed short) a1); +} + +/* vec_vupkhpx */ + +inline __vector unsigned int +vec_vupkhpx (__vector __pixel a1) +{ + return (__vector unsigned int) __builtin_altivec_vupkhpx ((__vector signed short) a1); +} + +/* vec_vupkhsb */ + +inline __vector __bool short +vec_vupkhsb (__vector __bool char a1) +{ + return (__vector __bool short) __builtin_altivec_vupkhsb ((__vector signed char) a1); +} + +inline __vector signed short +vec_vupkhsb (__vector signed char a1) +{ + return (__vector signed short) __builtin_altivec_vupkhsb ((__vector signed char) a1); +} + +/* vec_unpackl */ + +inline __vector signed short +vec_unpackl (__vector signed char a1) +{ + return (__vector signed short) __builtin_altivec_vupklsb ((__vector signed char) a1); +} + +inline __vector __bool short +vec_unpackl (__vector __bool char a1) +{ + return (__vector __bool short) __builtin_altivec_vupklsb ((__vector signed char) a1); +} + +inline __vector unsigned int +vec_unpackl (__vector __pixel a1) +{ + return (__vector unsigned int) __builtin_altivec_vupklpx ((__vector signed short) a1); +} + +inline __vector signed int +vec_unpackl (__vector signed short a1) +{ + return (__vector signed int) __builtin_altivec_vupklsh ((__vector signed short) a1); +} + +inline __vector __bool int +vec_unpackl (__vector __bool short a1) +{ + return (__vector __bool int) __builtin_altivec_vupklsh ((__vector signed short) a1); +} + +/* vec_vupklpx */ + +inline __vector unsigned int +vec_vupklpx (__vector __pixel a1) +{ + return (__vector unsigned int) __builtin_altivec_vupklpx ((__vector signed short) a1); +} + +/* vec_upklsh */ + +inline __vector __bool int +vec_vupklsh (__vector __bool short a1) +{ + return (__vector __bool int) __builtin_altivec_vupklsh ((__vector signed short) a1); +} + +inline __vector signed int +vec_vupklsh (__vector signed short a1) +{ + return (__vector signed int) __builtin_altivec_vupklsh ((__vector signed short) a1); +} + +/* vec_vupklsb */ + +inline __vector __bool short +vec_vupklsb (__vector __bool char a1) +{ + return (__vector __bool short) __builtin_altivec_vupklsb ((__vector signed char) a1); +} + +inline __vector signed short +vec_vupklsb (__vector signed char a1) +{ + return (__vector signed short) __builtin_altivec_vupklsb ((__vector signed char) a1); +} + +/* vec_xor */ + +inline __vector float +vec_xor (__vector float a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_xor (__vector float a1, __vector __bool int a2) +{ + return (__vector float) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector float +vec_xor (__vector __bool int a1, __vector float a2) +{ + return (__vector float) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool int +vec_xor (__vector __bool int a1, __vector __bool int a2) +{ + return (__vector __bool int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_xor (__vector __bool int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_xor (__vector signed int a1, __vector __bool int a2) +{ + return (__vector signed int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed int +vec_xor (__vector signed int a1, __vector signed int a2) +{ + return (__vector signed int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_xor (__vector __bool int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_xor (__vector unsigned int a1, __vector __bool int a2) +{ + return (__vector unsigned int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned int +vec_xor (__vector unsigned int a1, __vector unsigned int a2) +{ + return (__vector unsigned int) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool short +vec_xor (__vector __bool short a1, __vector __bool short a2) +{ + return (__vector __bool short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_xor (__vector __bool short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_xor (__vector signed short a1, __vector __bool short a2) +{ + return (__vector signed short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed short +vec_xor (__vector signed short a1, __vector signed short a2) +{ + return (__vector signed short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_xor (__vector __bool short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_xor (__vector unsigned short a1, __vector __bool short a2) +{ + return (__vector unsigned short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned short +vec_xor (__vector unsigned short a1, __vector unsigned short a2) +{ + return (__vector unsigned short) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_xor (__vector __bool char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector __bool char +vec_xor (__vector __bool char a1, __vector __bool char a2) +{ + return (__vector __bool char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_xor (__vector signed char a1, __vector __bool char a2) +{ + return (__vector signed char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector signed char +vec_xor (__vector signed char a1, __vector signed char a2) +{ + return (__vector signed char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_xor (__vector __bool char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_xor (__vector unsigned char a1, __vector __bool char a2) +{ + return (__vector unsigned char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +inline __vector unsigned char +vec_xor (__vector unsigned char a1, __vector unsigned char a2) +{ + return (__vector unsigned char) __builtin_altivec_vxor ((__vector signed int) a1, (__vector signed int) a2); +} + +/* vec_all_eq */ + +inline int +vec_all_eq (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, a1, (__vector signed char) a2); +} + +inline int +vec_all_eq (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, a1, a2); +} + +inline int +vec_all_eq (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_eq (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_eq (__vector __bool char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_eq (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_eq (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_eq (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector __bool short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector __pixel a1, __vector __pixel a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_eq (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector __bool int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_eq (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_LT, a1, a2); +} + +/* vec_all_ge */ + +inline int +vec_all_ge (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_ge (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_ge (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_ge (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_ge (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_ge (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_ge (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_ge (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_ge (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_ge (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_ge (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_ge (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_ge (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_ge (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_ge (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_ge (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_ge (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_ge (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_ge (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_LT, a1, a2); +} + +/* vec_all_gt */ + +inline int +vec_all_gt (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_gt (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_gt (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_gt (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_gt (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_gt (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_gt (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_gt (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_gt (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_gt (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_gt (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_gt (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_gt (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_gt (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_gt (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_gt (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_gt (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_gt (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_gt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_LT, a1, a2); +} + +/* vec_all_in */ + +inline int +vec_all_in (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpbfp_p (__CR6_EQ, a1, a2); +} + +/* vec_all_le */ + +inline int +vec_all_le (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_le (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_le (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_le (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_le (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_le (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_le (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_le (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_le (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_le (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_le (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_le (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_le (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_le (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_le (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_le (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_le (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_le (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_le (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_LT, a2, a1); +} + +/* vec_all_lt */ + +inline int +vec_all_lt (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_lt (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_lt (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_lt (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_lt (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_lt (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_all_lt (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_lt (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_lt (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_lt (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_lt (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_lt (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_all_lt (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_lt (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_lt (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_lt (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_lt (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_lt (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_all_lt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_LT, a2, a1); +} + +/* vec_all_nan */ + +inline int +vec_all_nan (__vector float a1) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_EQ, a1, a1); +} + +/* vec_all_ne */ + +inline int +vec_all_ne (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector __bool char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_all_ne (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector __bool short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector __pixel a1, __vector __pixel a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_all_ne (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector __bool int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_all_ne (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_EQ, a1, a2); +} + +/* vec_all_nge */ + +inline int +vec_all_nge (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_EQ, a1, a2); +} + +/* vec_all_ngt */ + +inline int +vec_all_ngt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_EQ, a1, a2); +} + +/* vec_all_nle */ + +inline int +vec_all_nle (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_EQ, a2, a1); +} + +/* vec_all_nlt */ + +inline int +vec_all_nlt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_EQ, a2, a1); +} + +/* vec_all_numeric */ + +inline int +vec_all_numeric (__vector float a1) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_LT, a1, a1); +} + +/* vec_any_eq */ + +inline int +vec_any_eq (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector __bool char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_eq (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector __bool short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector __pixel a1, __vector __pixel a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_eq (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector __bool int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_eq (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, a1, a2); +} + +/* vec_any_ge */ + +inline int +vec_any_ge (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_ge (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_ge (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_ge (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_ge (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_ge (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_ge (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_ge (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_ge (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_ge (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_ge (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_ge (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_ge (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_ge (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_ge (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_ge (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_ge (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_ge (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_ge (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_EQ_REV, a1, a2); +} + +/* vec_any_gt */ + +inline int +vec_any_gt (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_gt (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_gt (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_gt (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_gt (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_gt (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_gt (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_gt (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_gt (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_gt (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_gt (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_gt (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_gt (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_gt (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_gt (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_gt (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_gt (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_gt (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_gt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_EQ_REV, a1, a2); +} + +/* vec_any_le */ + +inline int +vec_any_le (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_le (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_le (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_le (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_le (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_le (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_le (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_le (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_le (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_le (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_le (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_le (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_le (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_le (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_le (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_le (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_le (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_le (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_le (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_EQ_REV, a2, a1); +} + +/* vec_any_lt */ + +inline int +vec_any_lt (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_lt (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_lt (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_lt (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_lt (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_lt (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) a2, (__vector signed char) a1); +} + +inline int +vec_any_lt (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_lt (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_lt (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_lt (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_lt (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_lt (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) a2, (__vector signed short) a1); +} + +inline int +vec_any_lt (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_lt (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_lt (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_lt (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_lt (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_lt (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) a2, (__vector signed int) a1); +} + +inline int +vec_any_lt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_EQ_REV, a2, a1); +} + +/* vec_any_nan */ + +inline int +vec_any_nan (__vector float a1) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, a1, a1); +} + +/* vec_any_ne */ + +inline int +vec_any_ne (__vector signed char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector signed char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector unsigned char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector unsigned char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector __bool char a1, __vector __bool char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector __bool char a1, __vector unsigned char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector __bool char a1, __vector signed char a2) +{ + return __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) a1, (__vector signed char) a2); +} + +inline int +vec_any_ne (__vector signed short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector signed short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector unsigned short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector unsigned short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector __bool short a1, __vector __bool short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector __bool short a1, __vector unsigned short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector __bool short a1, __vector signed short a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector __pixel a1, __vector __pixel a2) +{ + return __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) a1, (__vector signed short) a2); +} + +inline int +vec_any_ne (__vector signed int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector signed int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector unsigned int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector unsigned int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector __bool int a1, __vector __bool int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector __bool int a1, __vector unsigned int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector __bool int a1, __vector signed int a2) +{ + return __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) a1, (__vector signed int) a2); +} + +inline int +vec_any_ne (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, a1, a2); +} + +/* vec_any_nge */ + +inline int +vec_any_nge (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, a1, a2); +} + +/* vec_any_ngt */ + +inline int +vec_any_ngt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, a1, a2); +} + +/* vec_any_nle */ + +inline int +vec_any_nle (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, a2, a1); +} + +/* vec_any_nlt */ + +inline int +vec_any_nlt (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, a2, a1); +} + +/* vec_any_numeric */ + +inline int +vec_any_numeric (__vector float a1) +{ + return __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, a1, a1); +} + +/* vec_any_out */ + +inline int +vec_any_out (__vector float a1, __vector float a2) +{ + return __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2); +} + +} /* extern "C++" */ + +#else /* not C++ */ + +/* "... and so I think no man in a century will suffer as greatly as + you will." */ + +/* Helper macros. */ + +#define __un_args_eq(xtype, x) \ + __builtin_types_compatible_p (xtype, typeof (x)) + +#define __bin_args_eq(xtype, x, ytype, y) \ + (__builtin_types_compatible_p (xtype, typeof (x)) \ + && __builtin_types_compatible_p (ytype, typeof (y))) + +#define __tern_args_eq(xtype, x, ytype, y, ztype, z) \ + (__builtin_types_compatible_p (xtype, typeof (x)) \ + && __builtin_types_compatible_p (ytype, typeof (y)) \ + && __builtin_types_compatible_p (ztype, typeof (z))) + +#define __ch(x, y, z) __builtin_choose_expr (x, y, z) + +#define vec_step(t) \ + __ch (__builtin_types_compatible_p (typeof (t), __vector signed int), 4, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector unsigned int), 4, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector __bool int), 4, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector signed short), 8, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector unsigned short), 8, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector __bool short), 8, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector __pixel), 8, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector signed char), 16, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector unsigned char), 16, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector __bool char), 16, \ + __ch (__builtin_types_compatible_p (typeof (t), __vector float), 4, \ + __builtin_altivec_compiletime_error ("vec_step")))))))))))) + +#define vec_abs(a) \ + __ch (__un_args_eq (__vector signed char, (a)), \ + ((__vector signed char) __builtin_altivec_abs_v16qi ((__vector signed char) (a))), \ + __ch (__un_args_eq (__vector signed short, (a)), \ + ((__vector signed short) __builtin_altivec_abs_v8hi ((__vector signed short) (a))), \ + __ch (__un_args_eq (__vector signed int, (a)), \ + ((__vector signed int) __builtin_altivec_abs_v4si ((__vector signed int) (a))), \ + __ch (__un_args_eq (__vector float, (a)), \ + ((__vector float) __builtin_altivec_abs_v4sf ((__vector float) (a))), \ + __builtin_altivec_compiletime_error ("vec_abs"))))) + +#define vec_abss(a) \ + __ch (__un_args_eq (__vector signed char, (a)), \ + ((__vector signed char) __builtin_altivec_abss_v16qi ((__vector signed char) (a))), \ + __ch (__un_args_eq (__vector signed short, (a)), \ + ((__vector signed short) __builtin_altivec_abss_v8hi ((__vector signed short) (a))), \ + __ch (__un_args_eq (__vector signed int, (a)), \ + ((__vector signed int) __builtin_altivec_abss_v4si ((__vector signed int) (a))), \ + __builtin_altivec_compiletime_error ("vec_abss")))) + +#define vec_vaddubm(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vaddubm"))))))) + +#define vec_vadduhm(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vadduhm"))))))) + +#define vec_vadduwm(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vadduwm"))))))) + +#define vec_vaddfp(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vaddfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vaddfp")) + +#define vec_add(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vaddfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_add")))))))))))))))))))) + +#define vec_addc(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vaddcuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_addc")) + +#define vec_adds(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_adds"))))))))))))))))))) + +#define vec_vaddsws(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vaddsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vaddsws")))) + +#define vec_vadduws(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vadduws ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vadduws")))) + +#define vec_vaddshs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vaddshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vaddshs")))) + +#define vec_vadduhs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vadduhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vadduhs")))) + +#define vec_vaddsbs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vaddsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vaddsbs")))) + +#define vec_vaddubs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vaddubs ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vaddubs")))) + +#define vec_and(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector __bool int, (a2)), \ + ((__vector float) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vand ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_and"))))))))))))))))))))))))) + +#define vec_andc(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector __bool int, (a2)), \ + ((__vector float) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vandc ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_andc"))))))))))))))))))))))))) + +#define vec_avg(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vavgub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vavgsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vavguh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vavgsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vavguw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vavgsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_avg"))))))) + +#define vec_vavgsw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vavgsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vavgsw")) + +#define vec_vavguw(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vavguw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vavguw")) + +#define vec_vavgsh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vavgsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vavgsh")) + +#define vec_vavguh(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vavguh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vavguh")) + +#define vec_vavgsb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vavgsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vavgsb")) + +#define vec_vavgub(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vavgub ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vavgub")) + +#define vec_ceil(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vrfip ((__vector float) (a1))), \ + __builtin_altivec_compiletime_error ("vec_ceil")) + +#define vec_cmpb(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector signed int) __builtin_altivec_vcmpbfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_cmpb")) + +#define vec_cmpeq(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpeqfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_cmpeq")))))))) + +#define vec_vcmpeqfp(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpeqfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpeqfp")) + +#define vec_vcmpequw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpequw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpequw"))) + +#define vec_vcmpequh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpequh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpequh"))) + +#define vec_vcmpequb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpequb ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpequb"))) + +#define vec_cmpge(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgefp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_cmpge")) + +#define vec_cmpgt(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpgtub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpgtsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpgtuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpgtsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_cmpgt")))))))) + +#define vec_vcmpgtfp(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtfp")) + +#define vec_vcmpgtsw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtsw")) + +#define vec_vcmpgtuw(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtuw")) + +#define vec_vcmpgtsh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpgtsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtsh")) + +#define vec_vcmpgtuh(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpgtuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtuh")) + +#define vec_vcmpgtsb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpgtsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtsb")) + +#define vec_vcmpgtub(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpgtub ((__vector signed char) (a1), (__vector signed char) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcmpgtub")) + +#define vec_cmple(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgefp ((__vector float) (a2), (__vector float) (a1))), \ + __builtin_altivec_compiletime_error ("vec_cmple")) + +#define vec_cmplt(a2, a1) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpgtub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vcmpgtsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpgtuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vcmpgtsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector __bool int) __builtin_altivec_vcmpgtfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_cmplt")))))))) + +#define vec_ctf(a1, a2) \ +__ch (__un_args_eq (__vector unsigned int, (a1)), \ + ((__vector float) __builtin_altivec_vcfux ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector signed int, (a1)), \ + ((__vector float) __builtin_altivec_vcfsx ((__vector signed int) (a1), (const int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_ctf"))) + +#define vec_vcfsx(a1, a2) \ +__ch (__un_args_eq (__vector signed int, (a1)), \ + ((__vector float) __builtin_altivec_vcfsx ((__vector signed int) (a1), (const int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcfsx")) + +#define vec_vcfux(a1, a2) \ +__ch (__un_args_eq (__vector unsigned int, (a1)), \ + ((__vector float) __builtin_altivec_vcfux ((__vector signed int) (a1), (const int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_vcfux")) + +#define vec_cts(a1, a2) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector signed int) __builtin_altivec_vctsxs ((__vector float) (a1), (const int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_cts")) + +#define vec_ctu(a1, a2) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vctuxs ((__vector float) (a1), (const int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_ctu")) + +#define vec_dss(a1) __builtin_altivec_dss ((const int) (a1)); + +#define vec_dssall() __builtin_altivec_dssall () + +#define vec_dst(a1, a2, a3) \ +__ch (__un_args_eq (const __vector unsigned char, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed char, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool char, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned short, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed short, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool short, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __pixel, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned int, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed int, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool int, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector float, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned char, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const signed char, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned short, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const short, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned int, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const int, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned long, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const long, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const float, *(a1)), \ + __builtin_altivec_dst ((void *) (a1), (a2), (a3)), \ + __builtin_altivec_compiletime_error ("vec_dst"))))))))))))))))))))) + +#define vec_dstst(a1, a2, a3) \ +__ch (__un_args_eq (const __vector unsigned char, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed char, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool char, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned short, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed short, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool short, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __pixel, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned int, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed int, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool int, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector float, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned char, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const signed char, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned short, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const short, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned int, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const int, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned long, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const long, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const float, *(a1)), \ + __builtin_altivec_dstst ((void *) (a1), (a2), (a3)), \ + __builtin_altivec_compiletime_error ("vec_dstst"))))))))))))))))))))) + +#define vec_dststt(a1, a2, a3) \ +__ch (__un_args_eq (const __vector unsigned char, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed char, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool char, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned short, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed short, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool short, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __pixel, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned int, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed int, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool int, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector float, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned char, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const signed char, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned short, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const short, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned int, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const int, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned long, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const long, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const float, *(a1)), \ + __builtin_altivec_dststt ((void *) (a1), (a2), (a3)), \ + __builtin_altivec_compiletime_error ("vec_dststt"))))))))))))))))))))) + +#define vec_dstt(a1, a2, a3) \ +__ch (__un_args_eq (const __vector unsigned char, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed char, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool char, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned short, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed short, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool short, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __pixel, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector unsigned int, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector signed int, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector __bool int, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const __vector float, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned char, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const signed char, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned short, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const short, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned int, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const int, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const unsigned long, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const long, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ +__ch (__un_args_eq (const float, *(a1)), \ + __builtin_altivec_dstt ((void *) (a1), (a2), (a3)), \ + __builtin_altivec_compiletime_error ("vec_dstt"))))))))))))))))))))) + +#define vec_expte(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vexptefp ((__vector float) (a1))), \ + __builtin_altivec_compiletime_error ("vec_expte")) + +#define vec_floor(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vrfim ((__vector float) (a1))), \ + __builtin_altivec_compiletime_error ("vec_floor")) + +#define vec_ld(a, b) \ +__ch (__un_args_eq (const __vector unsigned char, *(b)), \ + ((__vector unsigned char) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const unsigned char, *(b)), \ + ((__vector unsigned char) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector signed char, *(b)), \ + ((__vector signed char) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const signed char, *(b)), \ + ((__vector signed char) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector __bool char, *(b)), \ + ((__vector __bool char) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector unsigned short, *(b)), \ + ((__vector unsigned short) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const unsigned short, *(b)), \ + ((__vector unsigned short) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector signed short, *(b)), \ + ((__vector signed short) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const short, *(b)), \ + ((__vector signed short) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector __bool short, *(b)), \ + ((__vector __bool short) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector __pixel, *(b)), \ + ((__vector __pixel) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector unsigned int, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const unsigned int, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const unsigned long, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector signed int, *(b)), \ + ((__vector signed int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const int, *(b)), \ + ((__vector signed int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const long, *(b)), \ + ((__vector signed int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector __bool int, *(b)), \ + ((__vector __bool int) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const __vector float, *(b)), \ + ((__vector float) __builtin_altivec_lvx ((a), (b))), \ +__ch (__un_args_eq (const float, *(b)), \ + ((__vector float) __builtin_altivec_lvx ((a), (b))), \ +__builtin_altivec_compiletime_error ("vec_ld"))))))))))))))))))))) + +#define vec_lde(a, b) \ +__ch (__un_args_eq (const unsigned char, *(b)), \ + ((__vector unsigned char) __builtin_altivec_lvebx ((a), (b))), \ +__ch (__un_args_eq (const signed char, *(b)), \ + ((__vector signed char) __builtin_altivec_lvebx ((a), (b))), \ +__ch (__un_args_eq (const unsigned short, *(b)), \ + ((__vector unsigned short) __builtin_altivec_lvehx ((a), (b))), \ +__ch (__un_args_eq (const short, *(b)), \ + ((__vector signed short) __builtin_altivec_lvehx ((a), (b))), \ +__ch (__un_args_eq (const unsigned long, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (const long, *(b)), \ + ((__vector signed int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (const unsigned int, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (const int, *(b)), \ + ((__vector signed int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (const float, *(b)), \ + ((__vector float) __builtin_altivec_lvewx ((a), (b))), \ +__builtin_altivec_compiletime_error ("vec_lde")))))))))) + +#define vec_lvewx(a, b) \ +__ch (__un_args_eq (unsigned int, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (signed int, *(b)), \ + ((__vector signed int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (unsigned long, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (signed long, *(b)), \ + ((__vector signed int) __builtin_altivec_lvewx ((a), (b))), \ +__ch (__un_args_eq (float, *(b)), \ + ((__vector float) __builtin_altivec_lvewx ((a), (b))), \ +__builtin_altivec_compiletime_error ("vec_lvewx")))))) + +#define vec_lvehx(a, b) \ +__ch (__un_args_eq (unsigned short, *(b)), \ + ((__vector unsigned short) __builtin_altivec_lvehx ((a), (b))), \ +__ch (__un_args_eq (signed short, *(b)), \ + ((__vector signed short) __builtin_altivec_lvehx ((a), (b))), \ +__builtin_altivec_compiletime_error ("vec_lvehx"))) + +#define vec_lvebx(a, b) \ +__ch (__un_args_eq (unsigned char, *(b)), \ + ((__vector unsigned char) __builtin_altivec_lvebx ((a), (b))), \ +__ch (__un_args_eq (signed char, *(b)), \ + ((__vector signed char) __builtin_altivec_lvebx ((a), (b))), \ +__builtin_altivec_compiletime_error ("vec_lvebx"))) + +#define vec_ldl(a, b) \ +__ch (__un_args_eq (const __vector unsigned char, *(b)), \ + ((__vector unsigned char) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const unsigned char, *(b)), \ + ((__vector unsigned char) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector signed char, *(b)), \ + ((__vector signed char) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const signed char, *(b)), \ + ((__vector signed char) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector __bool char, *(b)), \ + ((__vector __bool char) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector unsigned short, *(b)), \ + ((__vector unsigned short) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const unsigned short, *(b)), \ + ((__vector unsigned short) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector signed short, *(b)), \ + ((__vector signed short) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const short, *(b)), \ + ((__vector signed short) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector __bool short, *(b)), \ + ((__vector __bool short) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector __pixel, *(b)), \ + ((__vector __pixel) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector unsigned int, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const unsigned int, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const unsigned long, *(b)), \ + ((__vector unsigned int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector signed int, *(b)), \ + ((__vector signed int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const int, *(b)), \ + ((__vector signed int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const long, *(b)), \ + ((__vector signed int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector __bool int, *(b)), \ + ((__vector __bool int) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const __vector float, *(b)), \ + ((__vector float) __builtin_altivec_lvxl ((a), (b))), \ +__ch (__un_args_eq (const float, *(b)), \ + ((__vector float) __builtin_altivec_lvxl ((a), (b))), \ +__builtin_altivec_compiletime_error ("vec_ldl"))))))))))))))))))))) + +#define vec_loge(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vlogefp ((__vector float) (a1))), \ + __builtin_altivec_compiletime_error ("vec_loge")) + +#define vec_lvsl(a1, a2) \ +__ch (__un_args_eq (const volatile unsigned char, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed char, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile unsigned short, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed short, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile unsigned int, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed int, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile unsigned long, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed long, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile float, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsl ((a1), (void *) (a2))), \ +__builtin_altivec_compiletime_error ("vec_lvsl")))))))))) + +#define vec_lvsr(a1, a2) \ +__ch (__un_args_eq (const volatile unsigned char, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed char, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile unsigned short, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed short, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile unsigned int, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed int, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile unsigned long, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile signed long, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__ch (__un_args_eq (const volatile float, *(a2)), \ + ((__vector unsigned char) __builtin_altivec_lvsr ((a1), (void *) (a2))), \ +__builtin_altivec_compiletime_error ("vec_lvsr")))))))))) + +#define vec_madd(a1, a2, a3) \ +__ch (__tern_args_eq (__vector float, (a1), __vector float, (a2), __vector float, (a3)), \ + ((__vector float) __builtin_altivec_vmaddfp ((a1), (a2), (a3))), \ +__builtin_altivec_compiletime_error ("vec_madd")) + +#define vec_madds(a1, a2, a3) \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed short, (a3)), \ + ((__vector signed short) __builtin_altivec_vmhaddshs ((a1), (a2), (a3))), \ +__builtin_altivec_compiletime_error ("vec_madds")) + +#define vec_max(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vmaxfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_max")))))))))))))))))))) + +#define vec_vmaxfp(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vmaxfp ((__vector float) (a1), (__vector float) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxfp")) + +#define vec_vmaxsw(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmaxsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxsw")))) + +#define vec_vmaxuw(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmaxuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxuw")))) + +#define vec_vmaxsh(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmaxsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxsh")))) + +#define vec_vmaxuh(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmaxuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxuh")))) + +#define vec_vmaxsb(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmaxsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxsb")))) + +#define vec_vmaxub(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmaxub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmaxub")))) + +#define vec_mergeh(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmrghb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmrghb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vmrghb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + ((__vector __pixel) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_mergeh")))))))))))) + +#define vec_vmrghw(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmrghw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmrghw"))))) + +#define vec_vmrghh(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + ((__vector __pixel) __builtin_altivec_vmrghh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmrghh"))))) + +#define vec_vmrghb(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vmrghb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmrghb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmrghb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmrghb")))) + +#define vec_mergel(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmrglb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmrglb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vmrglb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + ((__vector __pixel) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_mergel")))))))))))) + +#define vec_vmrglw(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vmrglw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmrglw"))))) + +#define vec_vmrglh(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + ((__vector __pixel) __builtin_altivec_vmrglh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmrglh"))))) + +#define vec_vmrglb(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vmrglb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vmrglb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vmrglb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmrglb")))) + +#define vec_mfvscr() (((__vector unsigned short) __builtin_altivec_mfvscr ())) + +#define vec_min(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vminsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vminsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vminsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vminsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vminsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vminsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vminsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vminsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vminsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vminfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_min")))))))))))))))))))) + +#define vec_vminfp(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vminfp ((__vector float) (a1), (__vector float) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vminfp")) + +#define vec_vminsw(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vminsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vminsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vminsw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vminsw")))) + +#define vec_vminuw(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vminuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vminuw")))) + +#define vec_vminsh(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vminsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vminsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vminsh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vminsh")))) + +#define vec_vminuh(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vminuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vminuh")))) + +#define vec_vminsb(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vminsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vminsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vminsb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_minsb")))) + +#define vec_vminub(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vminub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vminub")))) + +#define vec_mladd(a1, a2, a3) \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed short, (a3)), \ + ((__vector signed short) __builtin_altivec_vmladduhm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed short) (a3))), \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector unsigned short, (a2), __vector unsigned short, (a3)), \ + ((__vector signed short) __builtin_altivec_vmladduhm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed short) (a3))), \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector signed short, (a2), __vector signed short, (a3)), \ + ((__vector signed short) __builtin_altivec_vmladduhm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed short) (a3))), \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned short, (a3)), \ + ((__vector unsigned short) __builtin_altivec_vmladduhm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed short) (a3))), \ + __builtin_altivec_compiletime_error ("vec_mladd"))))) + +#define vec_mradds(a1, a2, a3) \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed short, (a3)), \ + ((__vector signed short) __builtin_altivec_vmhraddshs ((a1), (a2), (a3))), \ +__builtin_altivec_compiletime_error ("vec_mradds")) + +#define vec_msum(a1, a2, a3) \ +__ch (__tern_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vmsumubm ((__vector signed char) (a1), (__vector signed char) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed char, (a1), __vector unsigned char, (a2), __vector signed int, (a3)), \ + ((__vector signed int) __builtin_altivec_vmsummbm ((__vector signed char) (a1), (__vector signed char) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vmsumuhm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed int, (a3)), \ + ((__vector signed int) __builtin_altivec_vmsumshm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ + __builtin_altivec_compiletime_error ("vec_msum"))))) + +#define vec_vmsumshm(a1, a2, a3) \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed int, (a3)), \ + ((__vector signed int) __builtin_altivec_vmsumshm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ +__builtin_altivec_compiletime_error ("vec_vmsumshm")) + +#define vec_vmsumuhm(a1, a2, a3) \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vmsumuhm ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ +__builtin_altivec_compiletime_error ("vec_vmsumuhm")) + +#define vec_vmsummbm(a1, a2, a3) \ +__ch (__tern_args_eq (__vector signed char, (a1), __vector unsigned char, (a2), __vector signed int, (a3)), \ + ((__vector signed int) __builtin_altivec_vmsummbm ((__vector signed char) (a1), (__vector signed char) (a2), (__vector signed int) (a3))), \ +__builtin_altivec_compiletime_error ("vec_vmsummbm")) + +#define vec_vmsumubm(a1, a2, a3) \ +__ch (__tern_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vmsumubm ((__vector signed char) (a1), (__vector signed char) (a2), (__vector signed int) (a3))), \ +__builtin_altivec_compiletime_error ("vec_vmsummbm")) + +#define vec_msums(a1, a2, a3) \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vmsumuhs ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed int, (a3)), \ + ((__vector signed int) __builtin_altivec_vmsumshs ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ + __builtin_altivec_compiletime_error ("vec_msums"))) + +#define vec_vmsumshs(a1, a2, a3) \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector signed int, (a3)), \ + ((__vector signed int) __builtin_altivec_vmsumshs ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ +__builtin_altivec_compiletime_error ("vec_vmsumshs")) + +#define vec_vmsumuhs(a1, a2, a3) \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vmsumuhs ((__vector signed short) (a1), (__vector signed short) (a2), (__vector signed int) (a3))), \ +__builtin_altivec_compiletime_error ("vec_vmsumuhs")) + +#define vec_mtvscr(a1) \ +__ch (__un_args_eq (__vector signed int, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector unsigned int, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector __bool int, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector unsigned short, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector unsigned char, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + __builtin_altivec_mtvscr ((__vector signed int) (a1)), \ + __builtin_altivec_compiletime_error ("vec_mtvscr"))))))))))) + +#define vec_mule(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmuleub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed short) __builtin_altivec_vmulesb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmuleuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed int) __builtin_altivec_vmulesh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_mule"))))) + +#define vec_vmulesh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed int) __builtin_altivec_vmulesh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmulesh")) + +#define vec_vmuleuh(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmuleuh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmuleuh")) + +#define vec_vmulesb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed short) __builtin_altivec_vmulesb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmulesb")) + +#define vec_vmuleub(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmuleub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmuleub")) + +#define vec_mulo(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmuloub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed short) __builtin_altivec_vmulosb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmulouh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed int) __builtin_altivec_vmulosh ((__vector signed short) (a1), (__vector signed short) (a2))), \ + __builtin_altivec_compiletime_error ("vec_mulo"))))) + +#define vec_vmulosh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed int) __builtin_altivec_vmulosh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmulosh")) + +#define vec_vmulouh(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vmulouh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmulouh")) + +#define vec_vmulosb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed short) __builtin_altivec_vmulosb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmulosb")) + +#define vec_vmuloub(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vmuloub ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vmuloub")) + +#define vec_nmsub(a1, a2, a3) \ +__ch (__tern_args_eq (__vector float, (a1), __vector float, (a2), __vector float, (a3)), \ + ((__vector float) __builtin_altivec_vnmsubfp ((__vector float) (a1), (__vector float) (a2), (__vector float) (a3))), \ + __builtin_altivec_compiletime_error ("vec_nmsub")) + +#define vec_nor(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vnor ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_nor"))))))))))) + +#define vec_or(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector __bool int, (a2)), \ + ((__vector float) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vor ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_or"))))))))))))))))))))))))) + +#define vec_pack(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed char) __builtin_altivec_vpkuhum ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkuhum ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool char) __builtin_altivec_vpkuhum ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed short) __builtin_altivec_vpkuwum ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkuwum ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool short) __builtin_altivec_vpkuwum ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_pack"))))))) + +#define vec_vpkuwum(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool short) __builtin_altivec_vpkuwum ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed short) __builtin_altivec_vpkuwum ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkuwum ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkuwum")))) + +#define vec_vpkuhum(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool char) __builtin_altivec_vpkuhum ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed char) __builtin_altivec_vpkuhum ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkuhum ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkuhum")))) + +#define vec_packpx(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector __pixel) __builtin_altivec_vpkpx ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_packpx")) + +#define vec_packs(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkuhus ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed char) __builtin_altivec_vpkshss ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkuwus ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed short) __builtin_altivec_vpkswss ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_packs"))))) + +#define vec_vpkswss(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed short) __builtin_altivec_vpkswss ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkswss")) + +#define vec_vpkuwus(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkuwus ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkuwus")) + +#define vec_vpkshss(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed char) __builtin_altivec_vpkshss ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkshss")) + +#define vec_vpkuhus(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkuhus ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkuhus")) + +#define vec_packsu(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkuhus ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkshus ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkuwus ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkswus ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_packsu"))))) + +#define vec_vpkswus(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vpkswus ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkswus")) + +#define vec_vpkshus(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vpkshus ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vpkshus")) + +#define vec_perm(a1, a2, a3) \ +__ch (__tern_args_eq (__vector float, (a1), __vector float, (a2), __vector unsigned char, (a3)), \ + ((__vector float) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector signed int, (a1), __vector signed int, (a2), __vector unsigned char, (a3)), \ + ((__vector signed int) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2), __vector unsigned char, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector __bool int, (a1), __vector __bool int, (a2), __vector unsigned char, (a3)), \ + ((__vector __bool int) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector unsigned char, (a3)), \ + ((__vector signed short) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned char, (a3)), \ + ((__vector unsigned short) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector __bool short, (a1), __vector __bool short, (a2), __vector unsigned char, (a3)), \ + ((__vector __bool short) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector __pixel, (a1), __vector __pixel, (a2), __vector unsigned char, (a3)), \ + ((__vector __pixel) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector signed char, (a1), __vector signed char, (a2), __vector unsigned char, (a3)), \ + ((__vector signed char) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2), __vector unsigned char, (a3)), \ + ((__vector unsigned char) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ +__ch (__tern_args_eq (__vector __bool char, (a1), __vector __bool char, (a2), __vector unsigned char, (a3)), \ + ((__vector __bool char) __builtin_altivec_vperm_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed char) (a3))), \ + __builtin_altivec_compiletime_error ("vec_perm")))))))))))) + +#define vec_re(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vrefp ((__vector float) (a1))), \ +__builtin_altivec_compiletime_error ("vec_re")) + +#define vec_rl(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vrlb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vrlb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vrlh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vrlh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vrlw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vrlw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_rl"))))))) + +#define vec_vrlw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vrlw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vrlw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vrlw"))) + +#define vec_vrlh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vrlh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vrlh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vrlh"))) + +#define vec_vrlb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vrlb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vrlb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vrlb"))) + +#define vec_round(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vrfin ((__vector float) (a1))), \ +__builtin_altivec_compiletime_error ("vec_round")) + +#define vec_rsqrte(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vrsqrtefp ((__vector float) (a1))), \ +__builtin_altivec_compiletime_error ("vec_rsqrte")) + +#define vec_sel(a1, a2, a3) \ +__ch (__tern_args_eq (__vector float, (a1), __vector float, (a2), __vector __bool int, (a3)), \ + ((__vector float) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector float, (a1), __vector float, (a2), __vector unsigned int, (a3)), \ + ((__vector float) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector __bool int, (a1), __vector __bool int, (a2), __vector __bool int, (a3)), \ + ((__vector __bool int) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector __bool int, (a1), __vector __bool int, (a2), __vector unsigned int, (a3)), \ + ((__vector __bool int) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed int, (a1), __vector signed int, (a2), __vector __bool int, (a3)), \ + ((__vector signed int) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed int, (a1), __vector signed int, (a2), __vector unsigned int, (a3)), \ + ((__vector signed int) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2), __vector __bool int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2), __vector unsigned int, (a3)), \ + ((__vector unsigned int) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector __bool short, (a1), __vector __bool short, (a2), __vector __bool short, (a3)), \ + ((__vector __bool short) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector __bool short, (a1), __vector __bool short, (a2), __vector unsigned short, (a3)), \ + ((__vector __bool short) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector __bool short, (a3)), \ + ((__vector signed short) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed short, (a1), __vector signed short, (a2), __vector unsigned short, (a3)), \ + ((__vector signed short) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector __bool short, (a3)), \ + ((__vector unsigned short) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2), __vector unsigned short, (a3)), \ + ((__vector unsigned short) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector __bool char, (a1), __vector __bool char, (a2), __vector __bool char, (a3)), \ + ((__vector __bool char) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector __bool char, (a1), __vector __bool char, (a2), __vector unsigned char, (a3)), \ + ((__vector __bool char) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed char, (a1), __vector signed char, (a2), __vector __bool char, (a3)), \ + ((__vector signed char) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector signed char, (a1), __vector signed char, (a2), __vector unsigned char, (a3)), \ + ((__vector signed char) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2), __vector __bool char, (a3)), \ + ((__vector unsigned char) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ +__ch (__tern_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2), __vector unsigned char, (a3)), \ + ((__vector unsigned char) __builtin_altivec_vsel_4si ((__vector signed int) (a1), (__vector signed int) (a2), (__vector signed int) (a3))), \ + __builtin_altivec_compiletime_error ("vec_sel"))))))))))))))))))))) + +#define vec_sl(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vslb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vslb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vslh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vslh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vslw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vslw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sl"))))))) + +#define vec_vslw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vslw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vslw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vslw"))) + +#define vec_vslh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vslh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vslh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vslh"))) + +#define vec_vslb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vslb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vslb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vslb"))) + +#define vec_sld(a1, a2, a3) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsldoi_4si ((__vector signed int) (a1), (__vector signed int) (a2), (const int) (a3))), \ + __builtin_altivec_compiletime_error ("vec_sld")))))))))))) + +#define vec_sll(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned short, (a2)), \ + ((__vector signed int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned char, (a2)), \ + ((__vector signed int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned int, (a2)), \ + ((__vector signed short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned char, (a2)), \ + ((__vector signed short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned int, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned short, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned char, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned int, (a2)), \ + ((__vector signed char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned short, (a2)), \ + ((__vector signed char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsl ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sll"))))))))))))))))))))))))))))))) + +#define vec_slo(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector signed char, (a2)), \ + ((__vector float) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector unsigned char, (a2)), \ + ((__vector float) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed char, (a2)), \ + ((__vector signed int) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned char, (a2)), \ + ((__vector signed int) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector signed char, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed char, (a2)), \ + ((__vector signed short) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned char, (a2)), \ + ((__vector signed short) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector signed char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector signed char, (a2)), \ + ((__vector __pixel) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned char, (a2)), \ + ((__vector __pixel) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector signed char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vslo ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_slo"))))))))))))))))) + +#define vec_splat(a1, a2) \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + ((__vector signed char) __builtin_altivec_vspltb ((__vector signed char) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector unsigned char, (a1)), \ + ((__vector unsigned char) __builtin_altivec_vspltb ((__vector signed char) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + ((__vector __bool char) __builtin_altivec_vspltb ((__vector signed char) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + ((__vector signed short) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector unsigned short, (a1)), \ + ((__vector unsigned short) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + ((__vector __bool short) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + ((__vector __pixel) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector signed int, (a1)), \ + ((__vector signed int) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector unsigned int, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector __bool int, (a1)), \ + ((__vector __bool int) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_splat")))))))))))) + +#define vec_vspltw(a1, a2) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector __bool int, (a1)), \ + ((__vector __bool int) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector signed int, (a1)), \ + ((__vector signed int) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector unsigned int, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vspltw ((__vector signed int) (a1), (const int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vspltw"))))) + +#define vec_vsplth(a1, a2) \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + ((__vector __bool short) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + ((__vector signed short) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector unsigned short, (a1)), \ + ((__vector unsigned short) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + ((__vector __pixel) __builtin_altivec_vsplth ((__vector signed short) (a1), (const int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsplth"))))) + +#define vec_vspltb(a1, a2) \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + ((__vector __bool char) __builtin_altivec_vspltb ((__vector signed char) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + ((__vector signed char) __builtin_altivec_vspltb ((__vector signed char) (a1), (const int) (a2))), \ +__ch (__un_args_eq (__vector unsigned char, (a1)), \ + ((__vector unsigned char) __builtin_altivec_vspltb ((__vector signed char) (a1), (const int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vspltb")))) + +#define vec_splat_s8(a1) ((__vector signed char) __builtin_altivec_vspltisb (a1)) + +#define vec_splat_s16(a1) ((__vector signed short) __builtin_altivec_vspltish (a1)) + +#define vec_splat_s32(a1) ((__vector signed int) __builtin_altivec_vspltisw (a1)) + +#define vec_splat_u8(a1) ((__vector unsigned char) __builtin_altivec_vspltisb (a1)) + +#define vec_splat_u16(a1) ((__vector unsigned short) __builtin_altivec_vspltish (a1)) + +#define vec_splat_u32(a1) ((__vector unsigned int) __builtin_altivec_vspltisw (a1)) + +#define vec_sr(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsrb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsrb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsrh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsrh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsrw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsrw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sr"))))))) + +#define vec_vsrw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsrw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsrw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsrw"))) + +#define vec_vsrh(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsrh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsrh ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsrh"))) + +#define vec_vsrb(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsrb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsrb ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsrb"))) + +#define vec_sra(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsrab ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsrab ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsrah ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsrah ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsraw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsraw ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sra"))))))) + +#define vec_vsraw(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsraw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsraw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsraw"))) + +#define vec_vsrah(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsrah ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsrah ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsrah"))) + +#define vec_vsrab(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsrab ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsrab ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsrab"))) + +#define vec_srl(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned short, (a2)), \ + ((__vector signed int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned char, (a2)), \ + ((__vector signed int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool int) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned int, (a2)), \ + ((__vector signed short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned char, (a2)), \ + ((__vector signed short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool short) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned int, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned short, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned char, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned int, (a2)), \ + ((__vector signed char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned short, (a2)), \ + ((__vector signed char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned int, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned short, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vsr ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_srl"))))))))))))))))))))))))))))))) + +#define vec_sro(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector signed char, (a2)), \ + ((__vector float) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector unsigned char, (a2)), \ + ((__vector float) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed char, (a2)), \ + ((__vector signed int) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector unsigned char, (a2)), \ + ((__vector signed int) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector signed char, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed char, (a2)), \ + ((__vector signed short) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector unsigned char, (a2)), \ + ((__vector signed short) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector signed char, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector unsigned char, (a2)), \ + ((__vector __pixel) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector signed char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector unsigned char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector signed char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsro ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sro"))))))))))))))))) + +#define vec_st(a1, a2, a3) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), unsigned char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed char, (a1), signed char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), unsigned char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), signed char, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), unsigned short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed short, (a1), short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), unsigned short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), unsigned short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), short, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), unsigned int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed int, (a1), int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), unsigned int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), int, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector float, (a1), float, *(a3)), \ + __builtin_altivec_stvx ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__builtin_altivec_compiletime_error ("vec_st"))))))))))))))))))))))))))) + +#define vec_stl(a1, a2, a3) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), unsigned char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed char, (a1), signed char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), unsigned char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), signed char, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), unsigned short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed short, (a1), short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), unsigned short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), unsigned short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), short, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), unsigned int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector signed int, (a1), int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), unsigned int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), int, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__ch (__bin_args_eq (__vector float, (a1), float, *(a3)), \ + __builtin_altivec_stvxl ((__vector signed int) (a1), (a2), (void *) (a3)), \ +__builtin_altivec_compiletime_error ("vec_stl"))))))))))))))))))))))))))) + +#define vec_ste(a, b, c) \ +__ch (__bin_args_eq (__vector unsigned char, (a), unsigned char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector signed char, (a), signed char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __bool char, (a), unsigned char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __bool char, (a), signed char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector unsigned short, (a), unsigned short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector signed short, (a), short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __bool short, (a), unsigned short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __bool short, (a), short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __pixel, (a), unsigned short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __pixel, (a), short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector unsigned int, (a), unsigned int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector signed int, (a), int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __bool int, (a), unsigned int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector __bool int, (a), int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (void *) (c)), \ +__ch (__bin_args_eq (__vector float, (a), float, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (void *) (c)), \ + __builtin_altivec_compiletime_error ("vec_ste")))))))))))))))) + +#define vec_stvewx(a, b, c) \ +__ch (__bin_args_eq (__vector unsigned int, (a), unsigned int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector signed int, (a), int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __bool int, (a), unsigned int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __bool int, (a), int, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector float, (a), float, *(c)), \ + __builtin_altivec_stvewx ((__vector signed int) (a), (b), (c)), \ +__builtin_altivec_compiletime_error ("vec_stvewx")))))) + +#define vec_stvehx(a, b, c) \ +__ch (__bin_args_eq (__vector unsigned short, (a), unsigned short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector signed short, (a), short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __bool short, (a), unsigned short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __bool short, (a), short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __pixel, (a), unsigned short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __pixel, (a), short, *(c)), \ + __builtin_altivec_stvehx ((__vector signed short) (a), (b), (c)), \ +__builtin_altivec_compiletime_error ("vec_stvehx"))))))) + +#define vec_stvebx(a, b, c) \ +__ch (__bin_args_eq (__vector unsigned char, (a), unsigned char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector signed char, (a), signed char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __bool char, (a), unsigned char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (c)), \ +__ch (__bin_args_eq (__vector __bool char, (a), signed char, *(c)), \ + __builtin_altivec_stvebx ((__vector signed char) (a), (b), (c)), \ +__builtin_altivec_compiletime_error ("vec_stvebx"))))) + +#define vec_sub(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vsubfp ((__vector float) (a1), (__vector float) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sub")))))))))))))))))))) + +#define vec_vsubfp(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vsubfp ((__vector float) (a1), (__vector float) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubfp")) + +#define vec_vsubuwm(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuwm ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubuwm"))))))) + +#define vec_vsubuhm(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhm ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubuhm"))))))) + +#define vec_vsububm(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububm ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsububm"))))))) + +#define vec_subc(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubcuw ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_subc")) + +#define vec_subs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_subs"))))))))))))))))))) + +#define vec_vsubsws(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsubsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubsws")))) + +#define vec_vsubuws(a1, a2) \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsubuws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubuws")))) + +#define vec_vsubshs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vsubshs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubshs")))) + +#define vec_vsubuhs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vsubuhs ((__vector signed short) (a1), (__vector signed short) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubuhs")))) + +#define vec_vsubsbs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vsubsbs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsubsbs")))) + +#define vec_vsububs(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vsububs ((__vector signed char) (a1), (__vector signed char) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsububs")))) + +#define vec_sum4s(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsum4ubs ((__vector signed char) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsum4sbs ((__vector signed char) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsum4shs ((__vector signed short) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_sum4s")))) + +#define vec_vsum4shs(a1, a2) \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsum4shs ((__vector signed short) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsum4shs")) + +#define vec_vsum4sbs(a1, a2) \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsum4sbs ((__vector signed char) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsum4sbs")) + +#define vec_vsum4ubs(a1, a2) \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vsum4ubs ((__vector signed char) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_vsum4ubs")) + +#define vec_sum2s(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsum2sws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_sum2s")) + +#define vec_sums(a1, a2) \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vsumsws ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__builtin_altivec_compiletime_error ("vec_sums")) + +#define vec_trunc(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + ((__vector float) __builtin_altivec_vrfiz ((__vector float) (a1))), \ +__builtin_altivec_compiletime_error ("vec_trunc")) + +#define vec_unpackh(a1) \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + ((__vector signed short) __builtin_altivec_vupkhsb ((__vector signed char) (a1))), \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + ((__vector __bool short) __builtin_altivec_vupkhsb ((__vector signed char) (a1))), \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vupkhpx ((__vector signed short) (a1))), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + ((__vector signed int) __builtin_altivec_vupkhsh ((__vector signed short) (a1))), \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + ((__vector __bool int) __builtin_altivec_vupkhsh ((__vector signed short) (a1))), \ + __builtin_altivec_compiletime_error ("vec_unpackh")))))) + +#define vec_vupkhsh(a1) \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + ((__vector __bool int) __builtin_altivec_vupkhsh ((__vector signed short) (a1))), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + ((__vector signed int) __builtin_altivec_vupkhsh ((__vector signed short) (a1))), \ +__builtin_altivec_compiletime_error ("vec_vupkhsh"))) + +#define vec_vupkhpx(a1) \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vupkhpx ((__vector signed short) (a1))), \ +__builtin_altivec_compiletime_error ("vec_vupkhpx")) + +#define vec_vupkhsb(a1) \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + ((__vector __bool short) __builtin_altivec_vupkhsb ((__vector signed char) (a1))), \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + ((__vector signed short) __builtin_altivec_vupkhsb ((__vector signed char) (a1))), \ +__builtin_altivec_compiletime_error ("vec_vupkhsb"))) + +#define vec_unpackl(a1) \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + ((__vector signed short) __builtin_altivec_vupklsb ((__vector signed char) (a1))), \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + ((__vector __bool short) __builtin_altivec_vupklsb ((__vector signed char) (a1))), \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vupklpx ((__vector signed short) (a1))), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + ((__vector signed int) __builtin_altivec_vupklsh ((__vector signed short) (a1))), \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + ((__vector __bool int) __builtin_altivec_vupklsh ((__vector signed short) (a1))), \ + __builtin_altivec_compiletime_error ("vec_unpackl")))))) + +#define vec_vupklsh(a1) \ +__ch (__un_args_eq (__vector __bool short, (a1)), \ + ((__vector __bool int) __builtin_altivec_vupklsh ((__vector signed short) (a1))), \ +__ch (__un_args_eq (__vector signed short, (a1)), \ + ((__vector signed int) __builtin_altivec_vupklsh ((__vector signed short) (a1))), \ +__builtin_altivec_compiletime_error ("vec_vupklsh"))) + +#define vec_vupklpx(a1) \ +__ch (__un_args_eq (__vector __pixel, (a1)), \ + ((__vector unsigned int) __builtin_altivec_vupklpx ((__vector signed short) (a1))), \ +__builtin_altivec_compiletime_error ("vec_vupklpx")) + +#define vec_vupklsb(a1) \ +__ch (__un_args_eq (__vector __bool char, (a1)), \ + ((__vector __bool short) __builtin_altivec_vupklsb ((__vector signed char) (a1))), \ +__ch (__un_args_eq (__vector signed char, (a1)), \ + ((__vector signed short) __builtin_altivec_vupklsb ((__vector signed char) (a1))), \ +__builtin_altivec_compiletime_error ("vec_vupklsb"))) + +#define vec_xor(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector float, (a1), __vector __bool int, (a2)), \ + ((__vector float) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector float, (a2)), \ + ((__vector float) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + ((__vector __bool int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + ((__vector signed int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + ((__vector signed int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + ((__vector unsigned int) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + ((__vector __bool short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + ((__vector signed short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + ((__vector signed short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + ((__vector unsigned short) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + ((__vector __bool char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + ((__vector signed char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + ((__vector signed char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + ((__vector unsigned char) __builtin_altivec_vxor ((__vector signed int) (a1), (__vector signed int) (a2))), \ + __builtin_altivec_compiletime_error ("vec_xor"))))))))))))))))))))))))) + +/* Predicates. */ + +#define vec_all_eq(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_LT, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_eq")))))))))))))))))))))))) + +#define vec_all_ge(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_LT, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_ge")))))))))))))))))))) + +#define vec_all_gt(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_LT, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_gt")))))))))))))))))))) + +#define vec_all_in(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_in")) + +#define vec_all_le(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_LT, (__vector float) (a2), (__vector float) (a1)), \ + __builtin_altivec_compiletime_error ("vec_all_le")))))))))))))))))))) + +#define vec_all_lt(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_LT, (__vector float) (a2), (__vector float) (a1)), \ + __builtin_altivec_compiletime_error ("vec_all_lt")))))))))))))))))))) + +#define vec_all_nan(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_EQ, (a1), (a1)), \ + __builtin_altivec_compiletime_error ("vec_all_nan")) + +#define vec_all_ne(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_EQ, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_ne")))))))))))))))))))))))) + +#define vec_all_nge(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_EQ, (a1), (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_nge")) + +#define vec_all_ngt(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a1), (a2)), \ + __builtin_altivec_compiletime_error ("vec_all_ngt")) + +#define vec_all_nle(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_EQ, (a2), (a1)), \ + __builtin_altivec_compiletime_error ("vec_all_nle")) + +#define vec_all_nlt(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a2), (a1)), \ + __builtin_altivec_compiletime_error ("vec_all_nlt")) + +#define vec_all_numeric(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_LT, (a1), (a1)), \ + __builtin_altivec_compiletime_error ("vec_all_numeric")) + +#define vec_any_eq(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_eq")))))))))))))))))))))))) + +#define vec_any_ge(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_EQ_REV, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_ge")))))))))))))))))))) + +#define vec_any_gt(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_EQ_REV, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_gt")))))))))))))))))))) + +#define vec_any_le(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_EQ_REV, (__vector float) (a2), (__vector float) (a1)), \ + __builtin_altivec_compiletime_error ("vec_any_le")))))))))))))))))))) + +#define vec_any_lt(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpgtub_p (__CR6_EQ_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpgtsb_p (__CR6_EQ_REV, (__vector signed char) (a2), (__vector signed char) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpgtuh_p (__CR6_EQ_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpgtsh_p (__CR6_EQ_REV, (__vector signed short) (a2), (__vector signed short) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpgtuw_p (__CR6_EQ_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpgtsw_p (__CR6_EQ_REV, (__vector signed int) (a2), (__vector signed int) (a1)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_EQ_REV, (__vector float) (a2), (__vector float) (a1)), \ + __builtin_altivec_compiletime_error ("vec_any_lt")))))))))))))))))))) + +#define vec_any_nan(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, (a1), (a1)), \ + __builtin_altivec_compiletime_error ("vec_any_nan")) + +#define vec_any_ne(a1, a2) \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector signed char, (a1), __vector signed char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector unsigned char, (a1), __vector unsigned char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool char, (a1), __vector __bool char, (a2)), \ + __builtin_altivec_vcmpequb_p (__CR6_LT_REV, (__vector signed char) (a1), (__vector signed char) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector signed short, (a1), __vector signed short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector unsigned short, (a1), __vector unsigned short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool short, (a1), __vector __bool short, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __pixel, (a1), __vector __pixel, (a2)), \ + __builtin_altivec_vcmpequh_p (__CR6_LT_REV, (__vector signed short) (a1), (__vector signed short) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector signed int, (a1), __vector signed int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector unsigned int, (a1), __vector unsigned int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector __bool int, (a1), __vector __bool int, (a2)), \ + __builtin_altivec_vcmpequw_p (__CR6_LT_REV, (__vector signed int) (a1), (__vector signed int) (a2)), \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_LT_REV, (__vector float) (a1), (__vector float) (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_ne")))))))))))))))))))))))) + +#define vec_any_nge(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, (a1), (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_nge")) + +#define vec_any_ngt(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, (a1), (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_ngt")) + +#define vec_any_nle(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgefp_p (__CR6_LT_REV, (a2), (a1)), \ + __builtin_altivec_compiletime_error ("vec_any_nle")) + +#define vec_any_nlt(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpgtfp_p (__CR6_LT_REV, (a2), (a1)), \ + __builtin_altivec_compiletime_error ("vec_any_nlt")) + +#define vec_any_numeric(a1) \ +__ch (__un_args_eq (__vector float, (a1)), \ + __builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, (a1), (a1)), \ + __builtin_altivec_compiletime_error ("vec_any_numeric")) + +#define vec_any_out(a1, a2) \ +__ch (__bin_args_eq (__vector float, (a1), __vector float, (a2)), \ + __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2)), \ + __builtin_altivec_compiletime_error ("vec_any_out")) + + +#endif /* __cplusplus */ + +#endif /* _ALTIVEC_H */ diff --git a/reactos/tools/ppc-build/core-headers/cxxabi.h b/reactos/tools/ppc-build/core-headers/cxxabi.h new file mode 100644 index 00000000000..35535491035 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/cxxabi.h @@ -0,0 +1,528 @@ +// new abi support -*- C++ -*- + +// Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Nathan Sidwell, Codesourcery LLC, + +/* This file declares the new abi entry points into the runtime. It is not + normally necessary for user programs to include this header, or use the + entry points directly. However, this header is available should that be + needed. + + Some of the entry points are intended for both C and C++, thus this header + is includable from both C and C++. Though the C++ specific parts are not + available in C, naturally enough. */ + +#ifndef _CXXABI_H +#define _CXXABI_H 1 + +#include + +#ifdef __cplusplus +namespace __cxxabiv1 +{ + extern "C" + { +#endif + + // Allocate array. + void* + __cxa_vec_new(size_t __element_count, size_t __element_size, + size_t __padding_size, void (*__constructor) (void*), + void (*__destructor) (void*)); + + void* + __cxa_vec_new2(size_t __element_count, size_t __element_size, + size_t __padding_size, void (*__constructor) (void*), + void (*__destructor) (void*), void *(*__alloc) (size_t), + void (*__dealloc) (void*)); + + void* + __cxa_vec_new3(size_t __element_count, size_t __element_size, + size_t __padding_size, void (*__constructor) (void*), + void (*__destructor) (void*), void *(*__alloc) (size_t), + void (*__dealloc) (void*, size_t)); + + // Construct array. + void + __cxa_vec_ctor(void* __array_address, size_t __element_count, + size_t __element_size, void (*__constructor) (void*), + void (*__destructor) (void*)); + + void + __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count, + size_t element_size, void (*constructor) (void*, void*), + void (*destructor) (void*)); + + // Destruct array. + void + __cxa_vec_dtor(void* __array_address, size_t __element_count, + size_t __element_size, void (*__destructor) (void*)); + + void + __cxa_vec_cleanup(void* __array_address, size_t __element_count, + size_t __element_size, void (*__destructor) (void*)); + + // Destruct and release array. + void + __cxa_vec_delete(void* __array_address, size_t __element_size, + size_t __padding_size, void (*__destructor) (void*)); + + void + __cxa_vec_delete2(void* __array_address, size_t __element_size, + size_t __padding_size, void (*__destructor) (void*), + void (*__dealloc) (void*)); + + void + __cxa_vec_delete3(void* __array_address, size_t __element_size, + size_t __padding_size, void (*__destructor) (void*), + void (*__dealloc) (void*, size_t)); + + // The ABI requires a 64-bit type. + __extension__ typedef int __guard __attribute__((mode (__DI__))); + + int + __cxa_guard_acquire(__guard*); + + void + __cxa_guard_release(__guard*); + + void + __cxa_guard_abort(__guard*); + + // Pure virtual functions. + void + __cxa_pure_virtual(void); + + // Exception handling. + void + __cxa_bad_cast(); + + void + __cxa_bad_typeid(); + + // DSO destruction. + int + __cxa_atexit(void (*)(void*), void*, void*); + + int + __cxa_finalize(void*); + + // Demangling routines. + char* + __cxa_demangle(const char* __mangled_name, char* __output_buffer, + size_t* __length, int* __status); +#ifdef __cplusplus + } +} // namespace __cxxabiv1 +#endif + +#ifdef __cplusplus + +#include + +namespace __cxxabiv1 +{ + // Type information for int, float etc. + class __fundamental_type_info : public std::type_info + { + public: + explicit + __fundamental_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__fundamental_type_info(); + }; + + // Type information for array objects. + class __array_type_info : public std::type_info + { + public: + explicit + __array_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__array_type_info(); + }; + + // Type information for functions (both member and non-member). + class __function_type_info : public std::type_info + { + public: + explicit + __function_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__function_type_info(); + + protected: + // Implementation defined member function. + virtual bool + __is_function_p() const; + }; + + // Type information for enumerations. + class __enum_type_info : public std::type_info + { + public: + explicit + __enum_type_info(const char* __n) : std::type_info(__n) { } + + virtual + ~__enum_type_info(); + }; + + // Common type information for simple pointers and pointers to member. + class __pbase_type_info : public std::type_info + { + public: + unsigned int __flags; // Qualification of the target object. + const std::type_info* __pointee; // Type of pointed to object. + + explicit + __pbase_type_info(const char* __n, int __quals, + const std::type_info* __type) + : std::type_info(__n), __flags(__quals), __pointee(__type) + { } + + virtual + ~__pbase_type_info(); + + // Implementation defined type. + enum __masks + { + __const_mask = 0x1, + __volatile_mask = 0x2, + __restrict_mask = 0x4, + __incomplete_mask = 0x8, + __incomplete_class_mask = 0x10 + }; + + protected: + __pbase_type_info(const __pbase_type_info&); + + __pbase_type_info& + operator=(const __pbase_type_info&); + + // Implementation defined member functions. + virtual bool + __do_catch(const std::type_info* __thr_type, void** __thr_obj, + unsigned int __outer) const; + + inline virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + // Type information for simple pointers. + class __pointer_type_info : public __pbase_type_info + { + public: + explicit + __pointer_type_info(const char* __n, int __quals, + const std::type_info* __type) + : __pbase_type_info (__n, __quals, __type) { } + + + virtual + ~__pointer_type_info(); + + protected: + // Implementation defined member functions. + virtual bool + __is_pointer_p() const; + + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + class __class_type_info; + + // Type information for a pointer to member variable. + class __pointer_to_member_type_info : public __pbase_type_info + { + public: + __class_type_info* __context; // Class of the member. + + explicit + __pointer_to_member_type_info(const char* __n, int __quals, + const std::type_info* __type, + __class_type_info* __klass) + : __pbase_type_info(__n, __quals, __type), __context(__klass) { } + + virtual + ~__pointer_to_member_type_info(); + + protected: + __pointer_to_member_type_info(const __pointer_to_member_type_info&); + + __pointer_to_member_type_info& + operator=(const __pointer_to_member_type_info&); + + // Implementation defined member function. + virtual bool + __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + }; + + // Helper class for __vmi_class_type. + class __base_class_type_info + { + public: + const __class_type_info* __base_type; // Base class type. + long __offset_flags; // Offset and info. + + enum __offset_flags_masks + { + __virtual_mask = 0x1, + __public_mask = 0x2, + __hwm_bit = 2, + __offset_shift = 8 // Bits to shift offset. + }; + + // Implementation defined member functions. + bool + __is_virtual_p() const + { return __offset_flags & __virtual_mask; } + + bool + __is_public_p() const + { return __offset_flags & __public_mask; } + + ptrdiff_t + __offset() const + { + // This shift, being of a signed type, is implementation + // defined. GCC implements such shifts as arithmetic, which is + // what we want. + return static_cast(__offset_flags) >> __offset_shift; + } + }; + + // Type information for a class. + class __class_type_info : public std::type_info + { + public: + explicit + __class_type_info (const char *__n) : type_info(__n) { } + + virtual + ~__class_type_info (); + + // Implementation defined types. + // The type sub_kind tells us about how a base object is contained + // within a derived object. We often do this lazily, hence the + // UNKNOWN value. At other times we may use NOT_CONTAINED to mean + // not publicly contained. + enum __sub_kind + { + // We have no idea. + __unknown = 0, + + // Not contained within us (in some circumstances this might + // mean not contained publicly) + __not_contained, + + // Contained ambiguously. + __contained_ambig, + + // Via a virtual path. + __contained_virtual_mask = __base_class_type_info::__virtual_mask, + + // Via a public path. + __contained_public_mask = __base_class_type_info::__public_mask, + + // Contained within us. + __contained_mask = 1 << __base_class_type_info::__hwm_bit, + + __contained_private = __contained_mask, + __contained_public = __contained_mask | __contained_public_mask + }; + + struct __upcast_result; + struct __dyncast_result; + + protected: + // Implementation defined member functions. + virtual bool + __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const; + + virtual bool + __do_catch(const type_info* __thr_type, void** __thr_obj, + unsigned __outer) const; + + public: + // Helper for upcast. See if DST is us, or one of our bases. + // Return false if not found, true if found. + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + + // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly + // within OBJ_PTR. OBJ_PTR points to a base object of our type, + // which is the destination type. SRC2DST indicates how SRC + // objects might be contained within this type. If SRC_PTR is one + // of our SRC_TYPE bases, indicate the virtuality. Returns + // not_contained for non containment or private containment. + inline __sub_kind + __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + // Helper for dynamic cast. ACCESS_PATH gives the access from the + // most derived object to this base. DST_TYPE indicates the + // desired type we want. OBJ_PTR points to a base of our type + // within the complete object. SRC_TYPE indicates the static type + // started from and SRC_PTR points to that base within the most + // derived object. Fill in RESULT with what we find. Return true + // if we have located an ambiguous match. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE + // bases are inherited by the type started from -- which is not + // necessarily the current type. The current type will be a base + // of the destination type. OBJ_PTR points to the current base. + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + }; + + // Type information for a class with a single non-virtual base. + class __si_class_type_info : public __class_type_info + { + public: + const __class_type_info* __base_type; + + explicit + __si_class_type_info(const char *__n, const __class_type_info *__base) + : __class_type_info(__n), __base_type(__base) { } + + virtual + ~__si_class_type_info(); + + protected: + __si_class_type_info(const __si_class_type_info&); + + __si_class_type_info& + operator=(const __si_class_type_info&); + + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __sub_ptr) const; + + virtual bool + __do_upcast(const __class_type_info*__dst, const void*__obj, + __upcast_result& __restrict __result) const; + }; + + // Type information for a class with multiple and/or virtual bases. + class __vmi_class_type_info : public __class_type_info + { + public: + unsigned int __flags; // Details about the class hierarchy. + unsigned int __base_count; // Dumber of direct bases. + + // The array of bases uses the trailing array struct hack so this + // class is not constructable with a normal constructor. It is + // internally generated by the compiler. + __base_class_type_info __base_info[1]; // Array of bases. + + explicit + __vmi_class_type_info(const char* __n, int ___flags) + : __class_type_info(__n), __flags(___flags), __base_count(0) { } + + virtual + ~__vmi_class_type_info(); + + // Implementation defined types. + enum __flags_masks + { + __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base. + __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance. + __flags_unknown_mask = 0x10 + }; + + protected: + // Implementation defined member functions. + virtual bool + __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path, + const __class_type_info* __dst_type, const void* __obj_ptr, + const __class_type_info* __src_type, const void* __src_ptr, + __dyncast_result& __result) const; + + virtual __sub_kind + __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, + const __class_type_info* __src_type, + const void* __src_ptr) const; + + virtual bool + __do_upcast(const __class_type_info* __dst, const void* __obj, + __upcast_result& __restrict __result) const; + }; + + // Dynamic cast runtime. + // src2dst has the following possible values + // >-1: src_type is a unique public non-virtual base of dst_type + // dst_ptr + src2dst == src_ptr + // -1: unspecified relationship + // -2: src_type is not a public base of dst_type + // -3: src_type is a multiple public non-virtual base of dst_type + extern "C" void* + __dynamic_cast(const void* __src_ptr, // Starting object. + const __class_type_info* __src_type, // Static type of object. + const __class_type_info* __dst_type, // Desired target type. + ptrdiff_t __src2dst); // How src and dst are related. + + + // Returns the type_info for the currently handled exception [15.3/8], or + // null if there is none. + extern "C" std::type_info* + __cxa_current_exception_type(); +} // namespace __cxxabiv1 + +// User programs should use the alias `abi'. +namespace abi = __cxxabiv1; + +#endif // __cplusplus + +#endif // __CXXABI_H diff --git a/reactos/tools/ppc-build/core-headers/float.h b/reactos/tools/ppc-build/core-headers/float.h new file mode 100644 index 00000000000..75fcd5422d9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/float.h @@ -0,0 +1,162 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 5.2.4.2.2 Characteristics of floating types + */ + +#ifndef _FLOAT_H___ +#define _FLOAT_H___ + +/* Radix of exponent representation, b. */ +#undef FLT_RADIX +#define FLT_RADIX __FLT_RADIX__ + +/* Number of base-FLT_RADIX digits in the significand, p. */ +#undef FLT_MANT_DIG +#undef DBL_MANT_DIG +#undef LDBL_MANT_DIG +#define FLT_MANT_DIG __FLT_MANT_DIG__ +#define DBL_MANT_DIG __DBL_MANT_DIG__ +#define LDBL_MANT_DIG __LDBL_MANT_DIG__ + +/* Number of decimal digits, q, such that any floating-point number with q + decimal digits can be rounded into a floating-point number with p radix b + digits and back again without change to the q decimal digits, + + p * log10(b) if b is a power of 10 + floor((p - 1) * log10(b)) otherwise +*/ +#undef FLT_DIG +#undef DBL_DIG +#undef LDBL_DIG +#define FLT_DIG __FLT_DIG__ +#define DBL_DIG __DBL_DIG__ +#define LDBL_DIG __LDBL_DIG__ + +/* Minimum int x such that FLT_RADIX**(x-1) is a normalized float, emin */ +#undef FLT_MIN_EXP +#undef DBL_MIN_EXP +#undef LDBL_MIN_EXP +#define FLT_MIN_EXP __FLT_MIN_EXP__ +#define DBL_MIN_EXP __DBL_MIN_EXP__ +#define LDBL_MIN_EXP __LDBL_MIN_EXP__ + +/* Minimum negative integer such that 10 raised to that power is in the + range of normalized floating-point numbers, + + ceil(log10(b) * (emin - 1)) +*/ +#undef FLT_MIN_10_EXP +#undef DBL_MIN_10_EXP +#undef LDBL_MIN_10_EXP +#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ +#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ +#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ + +/* Maximum int x such that FLT_RADIX**(x-1) is a representable float, emax. */ +#undef FLT_MAX_EXP +#undef DBL_MAX_EXP +#undef LDBL_MAX_EXP +#define FLT_MAX_EXP __FLT_MAX_EXP__ +#define DBL_MAX_EXP __DBL_MAX_EXP__ +#define LDBL_MAX_EXP __LDBL_MAX_EXP__ + +/* Maximum integer such that 10 raised to that power is in the range of + representable finite floating-point numbers, + + floor(log10((1 - b**-p) * b**emax)) +*/ +#undef FLT_MAX_10_EXP +#undef DBL_MAX_10_EXP +#undef LDBL_MAX_10_EXP +#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ +#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ +#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ + +/* Maximum representable finite floating-point number, + + (1 - b**-p) * b**emax +*/ +#undef FLT_MAX +#undef DBL_MAX +#undef LDBL_MAX +#define FLT_MAX __FLT_MAX__ +#define DBL_MAX __DBL_MAX__ +#define LDBL_MAX __LDBL_MAX__ + +/* The difference between 1 and the least value greater than 1 that is + representable in the given floating point type, b**1-p. */ +#undef FLT_EPSILON +#undef DBL_EPSILON +#undef LDBL_EPSILON +#define FLT_EPSILON __FLT_EPSILON__ +#define DBL_EPSILON __DBL_EPSILON__ +#define LDBL_EPSILON __LDBL_EPSILON__ + +/* Minimum normalized positive floating-point number, b**(emin - 1). */ +#undef FLT_MIN +#undef DBL_MIN +#undef LDBL_MIN +#define FLT_MIN __FLT_MIN__ +#define DBL_MIN __DBL_MIN__ +#define LDBL_MIN __LDBL_MIN__ + +/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown. */ +/* ??? This is supposed to change with calls to fesetround in . */ +#undef FLT_ROUNDS +#define FLT_ROUNDS 1 + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +/* The floating-point expression evaluation method. + -1 indeterminate + 0 evaluate all operations and constants just to the range and + precision of the type + 1 evaluate operations and constants of type float and double + to the range and precision of the double type, evaluate + long double operations and constants to the range and + precision of the long double type + 2 evaluate all operations and constants to the range and + precision of the long double type + + ??? This ought to change with the setting of the fp control word; + the value provided by the compiler assumes the widest setting. */ +#undef FLT_EVAL_METHOD +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ + +/* Number of decimal digits, n, such that any floating-point number in the + widest supported floating type with pmax radix b digits can be rounded + to a floating-point number with n decimal digits and back again without + change to the value, + + pmax * log10(b) if b is a power of 10 + ceil(1 + pmax * log10(b)) otherwise +*/ +#undef DECIMAL_DIG +#define DECIMAL_DIG __DECIMAL_DIG__ + +#endif /* C99 */ +#endif /* _FLOAT_H___ */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/algorithm b/reactos/tools/ppc-build/core-headers/g++-v3/algorithm new file mode 100644 index 00000000000..40e6246ce7f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/algorithm @@ -0,0 +1,71 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file algorithm + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_ALGORITHM +#define _GLIBCXX_ALGORITHM 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +#endif /* _GLIBCXX_ALGORITHM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/algo.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/algo.h new file mode 100644 index 00000000000..6f248356cf8 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/algo.h @@ -0,0 +1,149 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALGO_H +#define _BACKWARD_ALGO_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "tempbuf.h" +#include "iterator.h" +#include +#include +#include +#include + +// Names from +using std::for_each; +using std::find; +using std::find_if; +using std::adjacent_find; +using std::count; +using std::count_if; +using std::search; +using std::search_n; +using std::swap_ranges; +using std::transform; +using std::replace; +using std::replace_if; +using std::replace_copy; +using std::replace_copy_if; +using std::generate; +using std::generate_n; +using std::remove; +using std::remove_if; +using std::remove_copy; +using std::remove_copy_if; +using std::unique; +using std::unique_copy; +using std::reverse; +using std::reverse_copy; +using std::rotate; +using std::rotate_copy; +using std::random_shuffle; +using std::partition; +using std::stable_partition; +using std::sort; +using std::stable_sort; +using std::partial_sort; +using std::partial_sort_copy; +using std::nth_element; +using std::lower_bound; +using std::upper_bound; +using std::equal_range; +using std::binary_search; +using std::merge; +using std::inplace_merge; +using std::includes; +using std::set_union; +using std::set_intersection; +using std::set_difference; +using std::set_symmetric_difference; +using std::min_element; +using std::max_element; +using std::next_permutation; +using std::prev_permutation; +using std::find_first_of; +using std::find_end; + +// Names from stl_heap.h +using std::push_heap; +using std::pop_heap; +using std::make_heap; +using std::sort_heap; + +// Names from stl_numeric.h +using std::accumulate; +using std::inner_product; +using std::partial_sum; +using std::adjacent_difference; + +// Names from ext/algorithm +using __gnu_cxx::random_sample; +using __gnu_cxx::random_sample_n; +using __gnu_cxx::is_sorted; +using __gnu_cxx::is_heap; +using __gnu_cxx::count; // Extension returning void +using __gnu_cxx::count_if; // Extension returning void + +// Names from ext/numeric +using __gnu_cxx::power; +using __gnu_cxx::iota; + +#endif /* _BACKWARD_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/algobase.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/algobase.h new file mode 100644 index 00000000000..86028a0d05c --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/algobase.h @@ -0,0 +1,95 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALGOBASE_H +#define _BACKWARD_ALGOBASE_H 1 + +#include "backward_warning.h" +#include "pair.h" +#include "iterator.h" +#include +#include +#include +#include + +// Names from stl_algobase.h +using std::iter_swap; +using std::swap; +using std::min; +using std::max; +using std::copy; +using std::copy_backward; +using std::fill; +using std::fill_n; +using std::mismatch; +using std::equal; +using std::lexicographical_compare; + +// Names from stl_uninitialized.h +using std::uninitialized_copy; +using std::uninitialized_fill; +using std::uninitialized_fill_n; + +// Names from ext/algorithm +using __gnu_cxx::copy_n; +using __gnu_cxx::lexicographical_compare_3way; + +// Names from ext/memory +using __gnu_cxx::uninitialized_copy_n; + +#endif /* _BACKWARD_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/alloc.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/alloc.h new file mode 100644 index 00000000000..d3c3c738b95 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/alloc.h @@ -0,0 +1,52 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ALLOC_H +#define _BACKWARD_ALLOC_H 1 + +#include "backward_warning.h" +#include +#include + +using std::allocator; + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/backward_warning.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/backward_warning.h new file mode 100644 index 00000000000..9e1377793ea --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/backward_warning.h @@ -0,0 +1,39 @@ +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_BACKWARD_WARNING_H +#define _BACKWARD_BACKWARD_WARNING_H 1 + +#ifdef __DEPRECATED +#warning This file includes at least one deprecated or antiquated header. \ +Please consider using one of the 32 headers found in section 17.4.1.2 of the \ +C++ standard. Examples include substituting the header for the \ +header for C++ includes, or instead of the deprecated header \ +. To disable this warning use -Wno-deprecated. +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/bvector.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/bvector.h new file mode 100644 index 00000000000..92457926788 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/bvector.h @@ -0,0 +1,68 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_BVECTOR_H +#define _BACKWARD_BVECTOR_H 1 + +#include "backward_warning.h" +#include + +typedef std::vector > bit_vector; + +#endif /* _BACKWARD_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/complex.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/complex.h new file mode 100644 index 00000000000..dfc67140655 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/complex.h @@ -0,0 +1,43 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_COMPLEX_H +#define _BACKWARD_COMPLEX_H 1 + +#include "backward_warning.h" +#include + +using std::complex; +typedef complex float_complex; +typedef complex double_complex; +typedef complex long_double_complex; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/defalloc.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/defalloc.h new file mode 100644 index 00000000000..76ea52abc9e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/defalloc.h @@ -0,0 +1,117 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +// Inclusion of this file is DEPRECATED. This is the original HP +// default allocator. It is provided only for backward compatibility. +// This file WILL BE REMOVED in a future release. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header . + +#ifndef _BACKWARD_DEFALLOC_H +#define _BACKWARD_DEFALLOC_H 1 + +#include "backward_warning.h" +#include "new.h" +#include +#include +#include +#include "iostream.h" +#include "algobase.h" + + +template +inline _Tp* allocate(ptrdiff_t __size, _Tp*) { + set_new_handler(0); + _Tp* __tmp = (_Tp*)(::operator new((size_t)(__size * sizeof(_Tp)))); + if (__tmp == 0) { + cerr << "out of memory" << endl; + exit(1); + } + return __tmp; +} + + +template +inline void deallocate(_Tp* __buffer) { + ::operator delete(__buffer); +} + +template +class allocator { +public: + typedef _Tp value_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + pointer allocate(size_type __n) { + return ::allocate((difference_type)__n, (pointer)0); + } + void deallocate(pointer __p) { ::deallocate(__p); } + pointer address(reference __x) { return (pointer)&__x; } + const_pointer const_address(const_reference __x) { + return (const_pointer)&__x; + } + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(_Tp))); + } + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(_Tp))); + } +}; + +class allocator { +public: + typedef void* pointer; +}; + + + +#endif /* _BACKWARD_DEFALLOC_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/deque.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/deque.h new file mode 100644 index 00000000000..36c7479ef09 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/deque.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_DEQUE_H +#define _BACKWARD_DEQUE_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include + +using std::deque; + +#endif /* _BACKWARD_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/fstream.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/fstream.h new file mode 100644 index 00000000000..6dfd514c2f3 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/fstream.h @@ -0,0 +1,52 @@ +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_FSTREAM_H +#define _BACKWARD_FSTREAM_H 1 + +#include "backward_warning.h" +#include + +using std::filebuf; +using std::ifstream; +using std::ofstream; +using std::fstream; +using std::streampos; + +#ifdef _GLIBCXX_USE_WCHAR_T +using std::wfilebuf; +using std::wifstream; +using std::wofstream; +using std::wfstream; +using std::wstreampos; +#endif + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/function.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/function.h new file mode 100644 index 00000000000..9fc8719c07a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/function.h @@ -0,0 +1,130 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_FUNCTION_H +#define _BACKWARD_FUNCTION_H 1 + +#include "backward_warning.h" +#include +#include +#include +#include + +// Names from stl_function.h +using std::unary_function; +using std::binary_function; +using std::plus; +using std::minus; +using std::multiplies; +using std::divides; +using std::modulus; +using std::negate; +using std::equal_to; +using std::not_equal_to; +using std::greater; +using std::less; +using std::greater_equal; +using std::less_equal; +using std::logical_and; +using std::logical_or; +using std::logical_not; +using std::unary_negate; +using std::binary_negate; +using std::not1; +using std::not2; +using std::binder1st; +using std::binder2nd; +using std::bind1st; +using std::bind2nd; +using std::pointer_to_unary_function; +using std::pointer_to_binary_function; +using std::ptr_fun; +using std::mem_fun_t; +using std::const_mem_fun_t; +using std::mem_fun_ref_t; +using std::const_mem_fun_ref_t; +using std::mem_fun1_t; +using std::const_mem_fun1_t; +using std::mem_fun1_ref_t; +using std::const_mem_fun1_ref_t; +using std::mem_fun; +using std::mem_fun_ref; + +// Names from ext/functional +using __gnu_cxx::identity_element; +using __gnu_cxx::unary_compose; +using __gnu_cxx::binary_compose; +using __gnu_cxx::compose1; +using __gnu_cxx::compose2; +using __gnu_cxx::identity; +using __gnu_cxx::select1st; +using __gnu_cxx::select2nd; +using __gnu_cxx::project1st; +using __gnu_cxx::project2nd; +using __gnu_cxx::constant_void_fun; +using __gnu_cxx::constant_unary_fun; +using __gnu_cxx::constant_binary_fun; +using __gnu_cxx::constant0; +using __gnu_cxx::constant1; +using __gnu_cxx::constant2; +using __gnu_cxx::subtractive_rng; +using __gnu_cxx::mem_fun1; +using __gnu_cxx::mem_fun1_ref; + +#endif /* _BACKWARD_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_map.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_map.h new file mode 100644 index 00000000000..bc9c1482c8a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_map.h @@ -0,0 +1,72 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_HASH_MAP_H +#define _BACKWARD_HASH_MAP_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; +using __gnu_cxx::hash_map; +using __gnu_cxx::hash_multimap; + +#endif /* _BACKWARD_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_set.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_set.h new file mode 100644 index 00000000000..89307de0402 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/hash_set.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_HASH_SET_H +#define _BACKWARD_HASH_SET_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; +using __gnu_cxx::hash_set; +using __gnu_cxx::hash_multiset; + +#endif /* _BACKWARD_HASH_SET_H */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/hashtable.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/hashtable.h new file mode 100644 index 00000000000..abedd55b001 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/hashtable.h @@ -0,0 +1,76 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef _BACKWARD_HASHTABLE_H +#define _BACKWARD_HASHTABLE_H 1 + +#include "backward_warning.h" +#include +#include "algo.h" +#include "alloc.h" +#include "vector.h" + +using __gnu_cxx::hash; +using __gnu_cxx::hashtable; + +#endif /* _BACKWARD_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/heap.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/heap.h new file mode 100644 index 00000000000..2f19545d0d7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/heap.h @@ -0,0 +1,71 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_HEAP_H +#define _BACKWARD_HEAP_H 1 + +#include "backward_warning.h" +#include +#include + +using std::push_heap; +using std::pop_heap; +using std::make_heap; +using std::sort_heap; + +#endif /* _BACKWARD_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/iomanip.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/iomanip.h new file mode 100644 index 00000000000..160dbebcdbf --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/iomanip.h @@ -0,0 +1,70 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_IOMANIP_H +#define _BACKWARD_IOMANIP_H 1 + +#include "backward_warning.h" +#include "iostream.h" +#include + +// These are from as per [27.4]. +using std::boolalpha; +using std::noboolalpha; +using std::showbase; +using std::noshowbase; +using std::showpoint; +using std::noshowpoint; +using std::showpos; +using std::noshowpos; +using std::skipws; +using std::noskipws; +using std::uppercase; +using std::nouppercase; +using std::internal; +using std::left; +using std::right; +using std::dec; +using std::hex; +using std::oct; +using std::fixed; +using std::scientific; + +// These are from as per [27.6]. Manipulators from +// and (e.g., endl) are made available via . +using std::resetiosflags; +using std::setiosflags; +using std::setbase; +using std::setfill; +using std::setprecision; +using std::setw; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/iostream.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/iostream.h new file mode 100644 index 00000000000..5a5ccea62b7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/iostream.h @@ -0,0 +1,60 @@ +// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_IOSTREAM_H +#define _BACKWARD_IOSTREAM_H 1 + +#include "backward_warning.h" +#include + +using std::iostream; +using std::ostream; +using std::istream; +using std::ios; +using std::streambuf; + +using std::cout; +using std::cin; +using std::cerr; +using std::clog; +#ifdef _GLIBCXX_USE_WCHAR_T +using std::wcout; +using std::wcin; +using std::wcerr; +using std::wclog; +#endif + +using std::ws; +using std::endl; +using std::ends; +using std::flush; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/istream.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/istream.h new file mode 100644 index 00000000000..707b575a5bd --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/istream.h @@ -0,0 +1,43 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_ISTREAM_H +#define _BACKWARD_ISTREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif + +// Local Variables: +// mode:C++ +// End: + + + + + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/iterator.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/iterator.h new file mode 100644 index 00000000000..8316a83d698 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/iterator.h @@ -0,0 +1,191 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ITERATOR_H +#define _BACKWARD_ITERATOR_H 1 + +#include "backward_warning.h" +#include "function.h" +#include +#include "iostream.h" +#include + +#include +#include + +#include // For 3-parameter distance extension + +// Names from stl_iterator.h +using std::input_iterator_tag; +using std::output_iterator_tag; +using std::forward_iterator_tag; +using std::bidirectional_iterator_tag; +using std::random_access_iterator_tag; + +#if 0 +using std::iterator; +#endif + +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (They have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. +template + struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template + struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +template + struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +template + struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + +using std::iterator_traits; + +template + inline typename iterator_traits<_Iter>::iterator_category + iterator_category(const _Iter& __i) + { return __iterator_category(__i); } + +template + inline typename iterator_traits<_Iter>::difference_type* + distance_type(const _Iter&) + { return static_cast::difference_type*>(0); } + +template + inline typename iterator_traits<_Iter>::value_type* + value_type(const _Iter& __i) + { return static_cast::value_type*>(0); } + +using std::distance; +using __gnu_cxx::distance; // 3-parameter extension +using std::advance; + +using std::insert_iterator; +using std::front_insert_iterator; +using std::back_insert_iterator; +using std::inserter; +using std::front_inserter; +using std::back_inserter; + +using std::reverse_iterator; + +using std::istream_iterator; +using std::ostream_iterator; + +// Names from stl_construct.h +template + inline void + construct(_T1* __p, const _T2& __value) + { std::_Construct(__p, __value); } + +template + inline void + construct(_T1* __p) + { std::_Construct(__p); } + +template + inline void + destroy(_Tp* __pointer) + { std::_Destroy(__pointer); } + +template + inline void + destroy(_ForwardIterator __first, _ForwardIterator __last) + { std::_Destroy(__first, __last); } + + +// Names from stl_raw_storage_iter.h +using std::raw_storage_iterator; + +#endif /* _BACKWARD_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/list.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/list.h new file mode 100644 index 00000000000..00c11a6987d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/list.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_LIST_H +#define _BACKWARD_LIST_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include + +using std::list; + +#endif /* _BACKWARD_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/map.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/map.h new file mode 100644 index 00000000000..56d5c69973b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/map.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MAP_H +#define _BACKWARD_MAP_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::map; + +#endif /* _BACKWARD_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/multimap.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/multimap.h new file mode 100644 index 00000000000..aba42f7217f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/multimap.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MULTIMAP_H +#define _BACKWARD_MULTIMAP_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::multimap; + +#endif /* _BACKWARD_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/multiset.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/multiset.h new file mode 100644 index 00000000000..7ec0c9476c9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/multiset.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_MULTISET_H +#define _BACKWARD_MULTISET_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::multiset; + +#endif /* _BACKWARD_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/new.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/new.h new file mode 100644 index 00000000000..00a4819a0bb --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/new.h @@ -0,0 +1,42 @@ +// -*- C++ -*- forwarding header. +// Copyright (C) 2000 Free Software Foundation + +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_NEW_H +#define _BACKWARD_NEW_H 1 + +#include "backward_warning.h" +#include + +using std::bad_alloc; +using std::nothrow_t; +using std::nothrow; +using std::new_handler; +using std::set_new_handler; + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/ostream.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/ostream.h new file mode 100644 index 00000000000..a72de09d9eb --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/ostream.h @@ -0,0 +1,38 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_OSTREAM_H +#define _BACKWARD_OSTREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/pair.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/pair.h new file mode 100644 index 00000000000..cbb3bc7ed6d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/pair.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_PAIR_H +#define _BACKWARD_PAIR_H 1 + +#include "backward_warning.h" +#include +#include + +using std::pair; +using std::make_pair; + +#endif /* _BACKWARD_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/queue.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/queue.h new file mode 100644 index 00000000000..a3e2ff3af09 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/queue.h @@ -0,0 +1,41 @@ +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_QUEUE_H +#define _BACKWARD_QUEUE_H 1 + +#include "backward_warning.h" +#include + +using std::queue; +using std::priority_queue; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/rope.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/rope.h new file mode 100644 index 00000000000..fc6715aa750 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/rope.h @@ -0,0 +1,60 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_ROPE_H +#define _BACKWARD_ROPE_H 1 + +#include "backward_warning.h" +#include "hashtable.h" +#include + +using __gnu_cxx::char_producer; +using __gnu_cxx::sequence_buffer; +using __gnu_cxx::rope; +using __gnu_cxx::crope; +using __gnu_cxx::wrope; + +#endif /* _BACKWARD_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/set.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/set.h new file mode 100644 index 00000000000..6a8320ba42f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/set.h @@ -0,0 +1,69 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_SET_H +#define _BACKWARD_SET_H 1 + +#include "backward_warning.h" +#include "tree.h" +#include + +using std::set; + +#endif /* _BACKWARD_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/slist.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/slist.h new file mode 100644 index 00000000000..63db065fe35 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/slist.h @@ -0,0 +1,56 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_SLIST_H +#define _BACKWARD_SLIST_H 1 + +#include "backward_warning.h" +#include + +using __gnu_cxx::slist; + +#endif /* _BACKWARD_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/stack.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/stack.h new file mode 100644 index 00000000000..0ff53a43572 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/stack.h @@ -0,0 +1,72 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_STACK_H +#define _BACKWARD_STACK_H 1 + +#include "backward_warning.h" +#include "vector.h" +#include "deque.h" +#include "heap.h" +#include "queue.h" +#include + +using std::stack; + +#endif /* _BACKWARD_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/stream.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/stream.h new file mode 100644 index 00000000000..5540c7eebd1 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/stream.h @@ -0,0 +1,38 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_STREAM_H +#define _BACKWARD_STREAM_H 1 + +#include "backward_warning.h" +#include "iostream.h" + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/streambuf.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/streambuf.h new file mode 100644 index 00000000000..fc9825ef0a3 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/streambuf.h @@ -0,0 +1,40 @@ +// Copyright (C) 2000 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BACKWARD_STREAMBUF_H +#define _BACKWARD_STREAMBUF_H 1 + +#include "backward_warning.h" +#include + +using std::streambuf; + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/strstream b/reactos/tools/ppc-build/core-headers/g++-v3/backward/strstream new file mode 100644 index 00000000000..a5b95c5e4e9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/strstream @@ -0,0 +1,179 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +// WARNING: The classes defined in this header are DEPRECATED. This +// header is defined in section D.7.1 of the C++ standard, and it +// MAY BE REMOVED in a future standard revision. You should use the +// header instead. + +#ifndef __SGI_STL_STRSTREAM +#define __SGI_STL_STRSTREAM + +#include "backward_warning.h" +#include +#include +#include +#include +#include + +namespace std +{ + // Class strstreambuf, a streambuf class that manages an array of char. + // Note that this class is not a template. + class strstreambuf : public basic_streambuf > + { + public: + // Types. + typedef char_traits _Traits; + typedef basic_streambuf _Base; + + public: + // Constructor, destructor + explicit strstreambuf(streamsize __initial_capacity = 0); + strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); + + strstreambuf(char* __get, streamsize __n, char* __put = 0); + strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0); + strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0); + + strstreambuf(const char* __get, streamsize __n); + strstreambuf(const signed char* __get, streamsize __n); + strstreambuf(const unsigned char* __get, streamsize __n); + + virtual ~strstreambuf(); + + public: + void freeze(bool = true); + char* str(); + int pcount() const; + + protected: + virtual int_type overflow(int_type __c = _Traits::eof()); + virtual int_type pbackfail(int_type __c = _Traits::eof()); + virtual int_type underflow(); + virtual _Base* setbuf(char* __buf, streamsize __n); + virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir, + ios_base::openmode __mode + = ios_base::in | ios_base::out); + virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode + = ios_base::in | ios_base::out); + + private: + strstreambuf& + operator=(const strstreambuf&); + + strstreambuf(const strstreambuf&); + + // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. + char* _M_alloc(size_t); + void _M_free(char*); + + // Helper function used in constructors. + void _M_setup(char* __get, char* __put, streamsize __n); + + private: + // Data members. + void* (*_M_alloc_fun)(size_t); + void (*_M_free_fun)(void*); + + bool _M_dynamic : 1; + bool _M_frozen : 1; + bool _M_constant : 1; + }; + + // Class istrstream, an istream that manages a strstreambuf. + class istrstream : public basic_istream + { + public: + explicit istrstream(char*); + explicit istrstream(const char*); + istrstream(char* , streamsize); + istrstream(const char*, streamsize); + virtual ~istrstream(); + + strstreambuf* rdbuf() const; + char* str(); + + private: + strstreambuf _M_buf; + }; + + // Class ostrstream + class ostrstream : public basic_ostream + { + public: + ostrstream(); + ostrstream(char*, int, ios_base::openmode = ios_base::out); + virtual ~ostrstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + char* str(); + int pcount() const; + + private: + strstreambuf _M_buf; + }; + + // Class strstream + class strstream : public basic_iostream + { + public: + typedef char char_type; + typedef char_traits::int_type int_type; + typedef char_traits::pos_type pos_type; + typedef char_traits::off_type off_type; + + strstream(); + strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out); + virtual ~strstream(); + + strstreambuf* rdbuf() const; + void freeze(bool = true); + int pcount() const; + char* str(); + + private: + strstreambuf _M_buf; + }; +} // namespace std +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/tempbuf.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/tempbuf.h new file mode 100644 index 00000000000..06de2bd39d4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/tempbuf.h @@ -0,0 +1,78 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_TEMPBUF_H +#define _BACKWARD_TEMPBUF_H 1 + +#include "backward_warning.h" +#include "pair.h" +#include "iterator.h" +#include +#include +#include +#include +#include +#include +#include + +using std::get_temporary_buffer; +using std::return_temporary_buffer; +using __gnu_cxx::temporary_buffer; + +#endif /* _BACKWARD_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/tree.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/tree.h new file mode 100644 index 00000000000..fcfcbf48dc4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/tree.h @@ -0,0 +1,55 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef _BACKWARD_TREE +#define _BACKWARD_TREE 1 + +#include "backward_warning.h" +#include + +using __gnu_cxx::rb_tree; + +#endif +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/backward/vector.h b/reactos/tools/ppc-build/core-headers/g++-v3/backward/vector.h new file mode 100644 index 00000000000..ba9b704c1dc --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/backward/vector.h @@ -0,0 +1,70 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _BACKWARD_VECTOR_H +#define _BACKWARD_VECTOR_H 1 + +#include "backward_warning.h" +#include "algobase.h" +#include "alloc.h" +#include + +using std::vector; + +#endif /* _BACKWARD_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/allocator.h new file mode 100644 index 00000000000..c23b544060e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/allocator.h @@ -0,0 +1,134 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file allocator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H 1 + +// Define the base class to std::allocator. +#include + +#pragma GCC visibility push(default) + +namespace std +{ + template + class allocator; + + template<> + class allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + }; + + /** + * @brief The "standard" allocator, as per [20.4]. + * + * (See @link Allocators allocators info @endlink for more.) + */ + template + class allocator: public ___glibcxx_base_allocator<_Tp> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + + allocator() throw() { } + + allocator(const allocator& a) throw() + : ___glibcxx_base_allocator<_Tp>(a) { } + + template + allocator(const allocator<_Tp1>&) throw() { } + + ~allocator() throw() { } + + // Inherit everything else. + }; + + template + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } + + template + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class allocator; + extern template class allocator; +#endif + + // Undefine. +#undef ___glibcxx_base_allocator +} // namespace std + +#pragma GCC visibility pop + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/atomicity.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/atomicity.h new file mode 100644 index 00000000000..d2620b08e5d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/atomicity.h @@ -0,0 +1,46 @@ +// Low-level functions for atomic operations -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#include + +namespace __gnu_cxx +{ + _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add(volatile _Atomic_word* __mem, int __val); + + void + __attribute__ ((__unused__)) + __atomic_add(volatile _Atomic_word* __mem, int __val); +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.h new file mode 100644 index 00000000000..7ffe40ef166 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.h @@ -0,0 +1,467 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file basic_ios.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_IOS_H +#define _BASIC_IOS_H 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +namespace std +{ + // 27.4.5 Template class basic_ios + /** + * @brief Virtual base class for all stream classes. + * + * Most of the member functions called dispatched on stream objects + * (e.g., @c std::cout.foo(bar);) are consolidated in this class. + */ + template + class basic_ios : public ios_base + { + public: + //@{ + /** + * These are standard types. They permit a standardized way of + * referring to names of (or names dependant on) the template + * parameters, which are specific to the implementation. + */ + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + //@} + + //@{ + /** + * @if maint + * These are non-standard types. + * @endif + */ + typedef ctype<_CharT> __ctype_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + //@} + + // Data members: + protected: + basic_ostream<_CharT, _Traits>* _M_tie; + mutable char_type _M_fill; + mutable bool _M_fill_init; + basic_streambuf<_CharT, _Traits>* _M_streambuf; + + // Cached use_facet, which is based on the current locale info. + const __ctype_type* _M_ctype; + // For ostream. + const __num_put_type* _M_num_put; + // For istream. + const __num_get_type* _M_num_get; + + public: + //@{ + /** + * @brief The quick-and-easy status check. + * + * This allows you to write constructs such as + * "if (!a_stream) ..." and "while (a_stream) ..." + */ + operator void*() const + { return this->fail() ? 0 : const_cast(this); } + + bool + operator!() const + { return this->fail(); } + //@} + + /** + * @brief Returns the error state of the stream buffer. + * @return A bit pattern (well, isn't everything?) + * + * See std::ios_base::iostate for the possible bit values. Most + * users will call one of the interpreting wrappers, e.g., good(). + */ + iostate + rdstate() const + { return _M_streambuf_state; } + + /** + * @brief [Re]sets the error state. + * @param state The new state flag(s) to set. + * + * See std::ios_base::iostate for the possible bit values. Most + * users will not need to pass an argument. + */ + void + clear(iostate __state = goodbit); + + /** + * @brief Sets additional flags in the error state. + * @param state The additional state flag(s) to set. + * + * See std::ios_base::iostate for the possible bit values. + */ + void + setstate(iostate __state) + { this->clear(this->rdstate() | __state); } + + // Flip the internal state on for the proper state bits, then re + // throws the propagated exception if bit also set in + // exceptions(). + void + _M_setstate(iostate __state) + { + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + _M_streambuf_state |= __state; + if (this->exceptions() & __state) + __throw_exception_again; + } + + /** + * @brief Fast error checking. + * @return True if no error flags are set. + * + * A wrapper around rdstate. + */ + bool + good() const + { return this->rdstate() == 0; } + + /** + * @brief Fast error checking. + * @return True if the eofbit is set. + * + * Note that other iostate flags may also be set. + */ + bool + eof() const + { return (this->rdstate() & eofbit) != 0; } + + /** + * @brief Fast error checking. + * @return True if either the badbit or the failbit is set. + * + * Checking the badbit in fail() is historical practice. + * Note that other iostate flags may also be set. + */ + bool + fail() const + { return (this->rdstate() & (badbit | failbit)) != 0; } + + /** + * @brief Fast error checking. + * @return True if the badbit is set. + * + * Note that other iostate flags may also be set. + */ + bool + bad() const + { return (this->rdstate() & badbit) != 0; } + + /** + * @brief Throwing exceptions on errors. + * @return The current exceptions mask. + * + * This changes nothing in the stream. See the one-argument version + * of exceptions(iostate) for the meaning of the return value. + */ + iostate + exceptions() const + { return _M_exception; } + + /** + * @brief Throwing exceptions on errors. + * @param except The new exceptions mask. + * + * By default, error flags are set silently. You can set an + * exceptions mask for each stream; if a bit in the mask becomes set + * in the error flags, then an exception of type + * std::ios_base::failure is thrown. + * + * If the error flage is already set when the exceptions mask is + * added, the exception is immediately thrown. Try running the + * following under GCC 3.1 or later: + * @code + * #include + * #include + * #include + * + * int main() + * { + * std::set_terminate (__gnu_cxx::__verbose_terminate_handler); + * + * std::ifstream f ("/etc/motd"); + * + * std::cerr << "Setting badbit\n"; + * f.setstate (std::ios_base::badbit); + * + * std::cerr << "Setting exception mask\n"; + * f.exceptions (std::ios_base::badbit); + * } + * @endcode + */ + void + exceptions(iostate __except) + { + _M_exception = __except; + this->clear(_M_streambuf_state); + } + + // Constructor/destructor: + /** + * @brief Constructor performs initialization. + * + * The parameter is passed by derived streams. + */ + explicit + basic_ios(basic_streambuf<_CharT, _Traits>* __sb) + : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), + _M_ctype(0), _M_num_put(0), _M_num_get(0) + { this->init(__sb); } + + /** + * @brief Empty. + * + * The destructor does nothing. More specifically, it does not + * destroy the streambuf held by rdbuf(). + */ + virtual + ~basic_ios() { } + + // Members: + /** + * @brief Fetches the current @e tied stream. + * @return A pointer to the tied stream, or NULL if the stream is + * not tied. + * + * A stream may be @e tied (or synchronized) to a second output + * stream. When this stream performs any I/O, the tied stream is + * first flushed. For example, @c std::cin is tied to @c std::cout. + */ + basic_ostream<_CharT, _Traits>* + tie() const + { return _M_tie; } + + /** + * @brief Ties this stream to an output stream. + * @param tiestr The output stream. + * @return The previously tied output stream, or NULL if the stream + * was not tied. + * + * This sets up a new tie; see tie() for more. + */ + basic_ostream<_CharT, _Traits>* + tie(basic_ostream<_CharT, _Traits>* __tiestr) + { + basic_ostream<_CharT, _Traits>* __old = _M_tie; + _M_tie = __tiestr; + return __old; + } + + /** + * @brief Accessing the underlying buffer. + * @return The current stream buffer. + * + * This does not change the state of the stream. + */ + basic_streambuf<_CharT, _Traits>* + rdbuf() const + { return _M_streambuf; } + + /** + * @brief Changing the underlying buffer. + * @param sb The new stream buffer. + * @return The previous stream buffer. + * + * Associates a new buffer with the current stream, and clears the + * error state. + * + * Due to historical accidents which the LWG refuses to correct, the + * I/O library suffers from a design error: this function is hidden + * in derived classes by overrides of the zero-argument @c rdbuf(), + * which is non-virtual for hysterical raisins. As a result, you + * must use explicit qualifications to access this function via any + * derived class. For example: + * + * @code + * std::fstream foo; // or some other derived type + * std::streambuf* p = .....; + * + * foo.ios::rdbuf(p); // ios == basic_ios + * @endcode + */ + basic_streambuf<_CharT, _Traits>* + rdbuf(basic_streambuf<_CharT, _Traits>* __sb); + + /** + * @brief Copies fields of __rhs into this. + * @param __rhs The source values for the copies. + * @return Reference to this object. + * + * All fields of __rhs are copied into this object except that rdbuf() + * and rdstate() remain unchanged. All values in the pword and iword + * arrays are copied. Before copying, each callback is invoked with + * erase_event. After copying, each (new) callback is invoked with + * copyfmt_event. The final step is to copy exceptions(). + */ + basic_ios& + copyfmt(const basic_ios& __rhs); + + /** + * @brief Retreives the "empty" character. + * @return The current fill character. + * + * It defaults to a space (' ') in the current locale. + */ + char_type + fill() const + { + if (!_M_fill_init) + { + _M_fill = this->widen(' '); + _M_fill_init = true; + } + return _M_fill; + } + + /** + * @brief Sets a new "empty" character. + * @param ch The new character. + * @return The previous fill character. + * + * The fill character is used to fill out space when P+ characters + * have been requested (e.g., via setw), Q characters are actually + * used, and Qfill(); + _M_fill = __ch; + return __old; + } + + // Locales: + /** + * @brief Moves to a new locale. + * @param loc The new locale. + * @return The previous locale. + * + * Calls @c ios_base::imbue(loc), and if a stream buffer is associated + * with this stream, calls that buffer's @c pubimbue(loc). + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + locale + imbue(const locale& __loc); + + /** + * @brief Squeezes characters. + * @param c The character to narrow. + * @param dfault The character to narrow. + * @return The narrowed character. + * + * Maps a character of @c char_type to a character of @c char, + * if possible. + * + * Returns the result of + * @code + * std::use_facet >(getloc()).narrow(c,dfault) + * @endcode + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + char + narrow(char_type __c, char __dfault) const; + + /** + * @brief Widens characters. + * @param c The character to widen. + * @return The widened character. + * + * Maps a character of @c char to a character of @c char_type. + * + * Returns the result of + * @code + * std::use_facet >(getloc()).widen(c) + * @endcode + * + * Additional l10n notes are at + * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html + */ + char_type + widen(char __c) const; + + protected: + // 27.4.5.1 basic_ios constructors + /** + * @brief Empty. + * + * The default constructor does nothing and is not normally + * accessible to users. + */ + basic_ios() + : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), + _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) + { } + + /** + * @brief All setup is performed here. + * + * This is called from the public constructor. It is not virtual and + * cannot be redefined. + */ + void + init(basic_streambuf<_CharT, _Traits>* __sb); + + void + _M_cache_locale(const locale& __loc); + }; +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +#include +#endif + +#endif /* _BASIC_IOS_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.tcc new file mode 100644 index 00000000000..fcb4b02493f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_ios.tcc @@ -0,0 +1,200 @@ +// basic_ios member functions -*- C++ -*- + +// Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BASIC_IOS_TCC +#define _BASIC_IOS_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + void + basic_ios<_CharT, _Traits>::clear(iostate __state) + { + if (this->rdbuf()) + _M_streambuf_state = __state; + else + _M_streambuf_state = __state | badbit; + if (this->exceptions() & this->rdstate()) + __throw_ios_failure(__N("basic_ios::clear")); + } + + template + basic_streambuf<_CharT, _Traits>* + basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) + { + basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; + _M_streambuf = __sb; + this->clear(); + return __old; + } + + template + basic_ios<_CharT, _Traits>& + basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 292. effects of a.copyfmt (a) + if (this != &__rhs) + { + // Per 27.1.1, do not call imbue, yet must trash all caches + // associated with imbue() + + // Alloc any new word array first, so if it fails we have "rollback". + _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? + _M_local_word : new _Words[__rhs._M_word_size]; + + // Bump refs before doing callbacks, for safety. + _Callback_list* __cb = __rhs._M_callbacks; + if (__cb) + __cb->_M_add_reference(); + _M_call_callbacks(erase_event); + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_dispose_callbacks(); + + // NB: Don't want any added during above. + _M_callbacks = __cb; + for (int __i = 0; __i < __rhs._M_word_size; ++__i) + __words[__i] = __rhs._M_word[__i]; + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_word = __words; + _M_word_size = __rhs._M_word_size; + + this->flags(__rhs.flags()); + this->width(__rhs.width()); + this->precision(__rhs.precision()); + this->tie(__rhs.tie()); + this->fill(__rhs.fill()); + _M_ios_locale = __rhs.getloc(); + _M_cache_locale(_M_ios_locale); + + _M_call_callbacks(copyfmt_event); + + // The next is required to be the last assignment. + this->exceptions(__rhs.exceptions()); + } + return *this; + } + + template + char + basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const + { return __check_facet(_M_ctype).narrow(__c, __dfault); } + + template + _CharT + basic_ios<_CharT, _Traits>::widen(char __c) const + { return __check_facet(_M_ctype).widen(__c); } + + // Locales: + template + locale + basic_ios<_CharT, _Traits>::imbue(const locale& __loc) + { + locale __old(this->getloc()); + ios_base::imbue(__loc); + _M_cache_locale(__loc); + if (this->rdbuf() != 0) + this->rdbuf()->pubimbue(__loc); + return __old; + } + + template + void + basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) + { + // NB: This may be called more than once on the same object. + ios_base::_M_init(); + + // Cache locale data and specific facets used by iostreams. + _M_cache_locale(_M_ios_locale); + + // NB: The 27.4.4.1 Postconditions Table specifies requirements + // after basic_ios::init() has been called. As part of this, + // fill() must return widen(' ') any time after init() has been + // called, which needs an imbued ctype facet of char_type to + // return without throwing an exception. Unfortunately, + // ctype is not necessarily a required facet, so + // streams with char_type != [char, wchar_t] will not have it by + // default. Because of this, the correct value for _M_fill is + // constructed on the first call of fill(). That way, + // unformatted input and output with non-required basic_ios + // instantiations is possible even without imbuing the expected + // ctype facet. + _M_fill = _CharT(); + _M_fill_init = false; + + _M_tie = 0; + _M_exception = goodbit; + _M_streambuf = __sb; + _M_streambuf_state = __sb ? goodbit : badbit; + } + + template + void + basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) + { + if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) + _M_ctype = &use_facet<__ctype_type>(__loc); + else + _M_ctype = 0; + + if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) + _M_num_put = &use_facet<__num_put_type>(__loc); + else + _M_num_put = 0; + + if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) + _M_num_get = &use_facet<__num_get_type>(__loc); + else + _M_num_get = 0; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_ios; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_ios; +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.h new file mode 100644 index 00000000000..3d33265d9e0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.h @@ -0,0 +1,2369 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file basic_string.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_STRING_H +#define _BASIC_STRING_H 1 + +#pragma GCC system_header + +#include +#include + +#pragma GCC visibility push(default) + +namespace std +{ + /** + * @class basic_string basic_string.h + * @brief Managing sequences of characters and character-like objects. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence. Of the + * optional sequence requirements, only + * @c push_back, @c at, and array access are supported. + * + * @doctodo + * + * + * @if maint + * Documentation? What's that? + * Nathan Myers . + * + * A string looks like this: + * + * @code + * [_Rep] + * _M_length + * [basic_string] _M_capacity + * _M_dataplus _M_refcount + * _M_p ----------------> unnamed array of char_type + * @endcode + * + * Where the _M_p points to the first character in the string, and + * you cast it to a pointer-to-_Rep and subtract 1 to get a + * pointer to the header. + * + * This approach has the enormous advantage that a string object + * requires only one allocation. All the ugliness is confined + * within a single pair of inline functions, which each compile to + * a single "add" instruction: _Rep::_M_data(), and + * string::_M_rep(); and the allocation function which gets a + * block of raw bytes and with room enough and constructs a _Rep + * object at the front. + * + * The reason you want _M_data pointing to the character array and + * not the _Rep is so that the debugger can see the string + * contents. (Probably we should add a non-inline member to get + * the _Rep for the debugger to use, so users can check the actual + * string length.) + * + * Note that the _Rep object is a POD so that you can have a + * static "empty string" _Rep object already "constructed" before + * static constructors have run. The reference-count encoding is + * chosen so that a 0 indicates one reference, so you never try to + * destroy the empty-string _Rep object. + * + * All but the last paragraph is considered pretty conventional + * for a C++ string implementation. + * @endif + */ + // 21.3 Template class basic_string + template + class basic_string + { + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + private: + // _Rep: string representation + // Invariants: + // 1. String really contains _M_length + 1 characters: due to 21.3.4 + // must be kept null-terminated. + // 2. _M_capacity >= _M_length + // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). + // 3. _M_refcount has three states: + // -1: leaked, one reference, no ref-copies allowed, non-const. + // 0: one reference, non-const. + // n>0: n + 1 references, operations require a lock, const. + // 4. All fields==0 is an empty string, given the extra storage + // beyond-the-end for a null terminator; thus, the shared + // empty string representation needs no constructor. + + struct _Rep_base + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + }; + + struct _Rep : _Rep_base + { + // Types: + typedef typename _Alloc::template rebind::other _Raw_bytes_alloc; + + // (Public) Data members: + + // The maximum number of individual char_type elements of an + // individual string is determined by _S_max_size. This is the + // value that will be returned by max_size(). (Whereas npos + // is the maximum number of bytes the allocator can allocate.) + // If one was to divvy up the theoretical largest size string, + // with a terminating character and m _CharT elements, it'd + // look like this: + // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) + // Solving for m: + // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 + // In addition, this implementation quarters this amount. + static const size_type _S_max_size; + static const _CharT _S_terminal; + + // The following storage is init'd to 0 by the linker, resulting + // (carefully) in an empty string with one reference. + static size_type _S_empty_rep_storage[]; + + static _Rep& + _S_empty_rep() + { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } + + bool + _M_is_leaked() const + { return this->_M_refcount < 0; } + + bool + _M_is_shared() const + { return this->_M_refcount > 0; } + + void + _M_set_leaked() + { this->_M_refcount = -1; } + + void + _M_set_sharable() + { this->_M_refcount = 0; } + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*>(this + 1); } + + _CharT* + _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) + { + return (!_M_is_leaked() && __alloc1 == __alloc2) + ? _M_refcopy() : _M_clone(__alloc1); + } + + // Create & Destroy + static _Rep* + _S_create(size_type, size_type, const _Alloc&); + + void + _M_dispose(const _Alloc& __a) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0) + _M_destroy(__a); + } // XXX MT + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_refcopy() throw() + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + __gnu_cxx::__atomic_add(&this->_M_refcount, 1); + return _M_refdata(); + } // XXX MT + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + }; + + // Use empty-base optimization: http://www.cantrip.org/emptyopt.html + struct _Alloc_hider : _Alloc + { + _Alloc_hider(_CharT* __dat, const _Alloc& __a) + : _Alloc(__a), _M_p(__dat) { } + + _CharT* _M_p; // The actual data. + }; + + public: + // Data Members (public): + // NB: This is an unsigned type, and thus represents the maximum + // size that the allocator can hold. + /// @var + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast(-1); + + private: + // Data Members (private): + mutable _Alloc_hider _M_dataplus; + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + _CharT* + _M_data(_CharT* __p) + { return (_M_dataplus._M_p = __p); } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } + + // For the internal use we have functions similar to `begin'/`end' + // but they do not call _M_leak. + iterator + _M_ibegin() const { return iterator(_M_data()); } + + iterator + _M_iend() const { return iterator(_M_data() + this->size()); } + + void + _M_leak() // for use in begin() & non-const op[] + { + if (!_M_rep()->_M_is_leaked()) + _M_leak_hard(); + } + + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + __throw_out_of_range(__N(__s)); + return __pos; + } + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { traits_type::copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { traits_type::copy(__p, __k1, __k2 - __k1); } + + void + _M_mutate(size_type __pos, size_type __len1, size_type __len2); + + void + _M_leak_hard(); + + static _Rep& + _S_empty_rep() + { return _Rep::_S_empty_rep(); } + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + inline + basic_string(); + + /** + * @brief Construct an empty string using allocator a. + */ + explicit + basic_string(const _Alloc& __a); + + // NB: per LWG issue 42, semantics different from IS: + /** + * @brief Construct string with copy of value of @a str. + * @param str Source string. + */ + basic_string(const basic_string& __str); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy (default remainder). + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy. + * @param a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a); + + /** + * @brief Construct string initialized by a character array. + * @param s Source character array. + * @param n Number of characters to copy. + * @param a Allocator to use (default is default allocator). + * + * NB: s must have at least n characters, '\0' has no special + * meaning. + */ + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as copy of a C string. + * @param s Source C string. + * @param a Allocator to use (default is default allocator). + */ + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as multiple characters. + * @param n Number of characters. + * @param c Character to use. + * @param a Allocator to use (default is default allocator). + */ + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); + + /** + * @brief Construct string as copy of a range. + * @param beg Start of range. + * @param end End of range. + * @param a Allocator to use (default is default allocator). + */ + template + basic_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()); + + /** + * @brief Destroy the string instance. + */ + ~basic_string() + { _M_rep()->_M_dispose(this->get_allocator()); } + + /** + * @brief Assign the value of @a str to this string. + * @param str Source string. + */ + basic_string& + operator=(const basic_string& __str) + { + this->assign(__str); + return *this; + } + + /** + * @brief Copy contents of @a s into this string. + * @param s Source null-terminated string. + */ + basic_string& + operator=(const _CharT* __s) + { + this->assign(__s); + return *this; + } + + /** + * @brief Set value to string of length 1. + * @param c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + basic_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. Unshares the string. + */ + iterator + begin() + { + _M_leak(); + return iterator(_M_data()); + } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const + { return const_iterator(_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. Unshares the string. + */ + iterator + end() + { + _M_leak(); + return iterator(_M_data() + this->size()); + } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const + { return const_iterator(_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. Unshares the string. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. Unshares the string. + */ + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const { return _M_rep()->_M_length; } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const { return _M_rep()->_M_length; } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const { return _Rep::_S_max_size; } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * @param c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are set to @a c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) { this->resize(__n, _CharT()); } + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const { return _M_rep()->_M_capacity; } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param n Number of characters required. + * @throw std::length_error If @a n exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0); + + /** + * Erases the string, making it empty. + */ + void + clear() { _M_mutate(0, this->size(), 0); } + + /** + * Returns true if the %string is empty. Equivalent to *this == "". + */ + bool + empty() const { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) Unshares the string. + */ + reference + operator[](size_type __pos) + { + _GLIBCXX_DEBUG_ASSERT(__pos < size()); + _M_leak(); + return _M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("basic_string::at")); + return _M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. Success results in + * unsharing the string. + */ + reference + at(size_type __n) + { + if (__n >= size()) + __throw_out_of_range(__N("basic_string::at")); + _M_leak(); + return _M_data()[__n]; + } + + // Modifiers: + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const basic_string& __str) { return this->append(__str); } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const _CharT* __s) { return this->append(__s); } + + /** + * @brief Append a character. + * @param s The character to append. + * @return Reference to this string. + */ + basic_string& + operator+=(_CharT __c) { return this->append(size_type(1), __c); } + + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + basic_string& + append(const basic_string& __str); + + /** + * @brief Append a substring. + * @param str The string to append. + * @param pos Index of the first character of str to append. + * @param n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function appends @a n characters from @a str starting at @a pos + * to this string. If @a n is is larger than the number of available + * characters in @a str, the remainder of @a str is appended. + */ + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n); + + /** + * @brief Append a C substring. + * @param s The C string to append. + * @param n The number of characters to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s, size_type __n); + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->append(__s, traits_type::length(__s)); + } + + /** + * @brief Append multiple characters. + * @param n The number of characters to append. + * @param c The character to use. + * @return Reference to this string. + * + * Appends n copies of c to this string. + */ + basic_string& + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + + /** + * @brief Append a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [first,last) to this string. + */ + template + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + /** + * @brief Append a single character. + * @param c Character to append. + */ + void + push_back(_CharT __c) + { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); } + + /** + * @brief Set value to contents of another string. + * @param str Source string to use. + * @return Reference to this string. + */ + basic_string& + assign(const basic_string& __str); + + /** + * @brief Set value to a substring of a string. + * @param str The string to use. + * @param pos Index of the first character of str. + * @param n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a str consisting + * of @a n characters at @a pos. If @a n is is larger than the number + * of available characters in @a str, the remainder of @a str is used. + */ + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { return this->assign(__str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param s The C string to use. + * @param n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a n + * characters of @a s. If @a n is is larger than the number of + * available characters in @a s, the remainder of @a s is used. + */ + basic_string& + assign(const _CharT* __s, size_type __n); + + /** + * @brief Set value to contents of a C string. + * @param s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a s. + * The data is copied, so there is no dependence on @a s once the + * function returns. + */ + basic_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->assign(__s, traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param n Length of the resulting string. + * @param c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a n copies of + * character @a c. + */ + basic_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [first,last). + */ + template + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + + /** + * @brief Insert multiple characters. + * @param p Iterator referencing location in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a n copies of character @a c starting at the position + * referenced by iterator @a p. If adding characters causes the length + * to exceed max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } + + /** + * @brief Insert a range of characters. + * @param p Iterator referencing location in string to insert at. + * @param beg Start of range. + * @param end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters causes + * the length to exceed max_size(), length_error is thrown. The value + * of the string doesn't change if an error is thrown. + */ + template + void insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } + + /** + * @brief Insert value of a string. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a str starting at @a pos1. If adding characters + * causes the length to exceed max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str) + { return this->insert(__pos1, __str, size_type(0), __str.size()); } + + /** + * @brief Insert a substring. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @param pos2 Start of characters in str to insert. + * @param n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a n character of @a str beginning with + * @a pos2. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a pos1 is beyond the end of + * this string or @a pos2 is beyond the end of @a str, out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { return this->insert(__pos1, __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @param n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n); + + /** + * @brief Insert a C string. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->insert(__pos, __s, traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param pos Index in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts @a n copies of character @a c starting at index @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos > length(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param p Iterator referencing position in string to insert at. + * @param c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a c at position referenced by @a p. If adding + * character causes the length to exceed max_size(), length_error is + * thrown. If @a p is beyond end of string, out_of_range is thrown. + * The value of the string doesn't change if an error is thrown. + */ + iterator + insert(iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + _M_rep()->_M_set_leaked(); + return this->_M_ibegin() + __pos; + } + + /** + * @brief Remove characters. + * @param pos Index of first character to remove (default 0). + * @param n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a n characters from this string starting at @a pos. The + * length of the string is reduced by @a n. If there are < @a n + * characters to remove, the remainder of the string is truncated. If + * @a p is beyond end of string, out_of_range is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { return _M_replace_safe(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n), NULL, size_type(0)); } + + /** + * @brief Remove one character. + * @param position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); + const size_type __pos = __position - _M_ibegin(); + _M_replace_safe(__pos, size_type(1), NULL, size_type(0)); + _M_rep()->_M_set_leaked(); + return _M_ibegin() + __pos; + } + + /** + * @brief Remove a range of characters. + * @param first Iterator referencing the first character to remove. + * @param last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __first, iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + const size_type __pos = __first - _M_ibegin(); + _M_replace_safe(__pos, __last - __first, NULL, size_type(0)); + _M_rep()->_M_set_leaked(); + return _M_ibegin() + __pos; + } + + /** + * @brief Replace characters with value from another string. + * @param pos Index of first character to replace. + * @param n Number of characters to be replaced. + * @param str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos+n) from this string. + * In place, the value of @a str is inserted. If @a pos is beyond end + * of string, out_of_range is thrown. If the length of the result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param pos1 Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str String to insert. + * @param pos2 Index of first character of str to use. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size() or @a pos2 > + * str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos1,pos1 + n) from this + * string. In place, the value of @a str is inserted. If @a pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } + + /** + * @brief Replace characters with value of a C substring. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str C string to insert. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n2 characters of @a str are inserted, or all + * of @a str if @a n2 is too large. If @a pos is beyond end of string, + * out_of_range is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2); + + /** + * @brief Replace characters with value of a C string. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n characters of @a str are inserted. If @a + * pos is beyond end of string, out_of_range is thrown. If the length + * of result exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param n2 Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, @a n2 copies of @a c are inserted. If @a pos is beyond + * end of string, out_of_range is thrown. If the length of result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the value of + * @a str is inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @param n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the first @a + * n characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the + * characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param n Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, @a n copies + * of @a c are inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param k1 Iterator referencing start of range to insert. + * @param k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, characters + * in the range [k1,k2) are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + basic_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + basic_string& + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + private: + template + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, __true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + + template + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type); + + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N("basic_string::_M_replace_aux")); + _M_mutate(__pos1, __n1, __n2); + if (__n2 == 1) + _M_data()[__pos1] = __c; + else if (__n2) + traits_type::assign(_M_data() + __pos1, __n2, __c); + return *this; + } + + basic_string& + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2) + { + _M_mutate(__pos1, __n1, __n2); + if (__n2 == 1) + _M_data()[__pos1] = *__s; + else if (__n2) + traits_type::copy(_M_data() + __pos1, __s, __n2); + return *this; + } + + // _S_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIter is an integral type + template + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + template + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __true_type) + { return _S_construct(static_cast(__beg), + static_cast(__end), __a); } + + template + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) + { + typedef typename _Is_integer<_InIterator>::_Integral _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template + static _CharT* + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, + forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: + + /** + * @brief Copy substring into C string. + * @param s C string to copy value into. + * @param n Number of characters to copy. + * @param pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If pos > size(). + * + * Copies up to @a n characters starting at @a pos into the C string @a + * s. If @a pos is greater than size(), out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param s String to swap with. + * + * Exchanges the contents of this string with that of @a s in constant + * time. + */ + void + swap(basic_string& __s); + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const { return _M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const { return _M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const { return _M_dataplus; } + + /** + * @brief Find position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search from. + * @param n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the first @a n characters + * in @a s within this string. If found, returns the index where it + * begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param str String to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param s C string to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a string. + * @param str String to locate. + * @param pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const basic_string& __str, size_type __pos = npos) const + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search back from. + * @param n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the first @a n + * characters in @a s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param s C string to locate. + * @param pos Index of character to start search at (default 0). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Find position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for the character @a c within + * this string. If found, returns the index where it was found. If + * not found, returns npos. + * + * Note: equivalent to find(c, pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @param n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + * + * Note: equivalent to rfind(c, pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in the first @a n characters of @a s within this string. If found, + * returns the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a s within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character other than @a c + * within this string. If found, returns the index where it was found. + * If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a str within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in the first @a n characters of @a s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character other than + * @a c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Get a substring. + * @param pos Index of first character (default 0). + * @param n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If pos > size(). + * + * Construct and return a new string using the @a n characters starting + * at @a pos. If the string is too short, use the remainder of the + * characters. If @a pos is beyond the end of the string, out_of_range + * is thrown. + */ + basic_string + substr(size_type __pos = 0, size_type __n = npos) const + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } + + /** + * @brief Compare to a string. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a str, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a str. Determines the effective length rlen of the strings to + * compare as the smallest of size() and str.size(). The function + * then compares the two strings by calling traits::compare(data(), + * str.data(),rlen). If the result of the comparison is nonzero returns + * it, otherwise the shorter one is ordered first. + */ + int + compare(const basic_string& __str) const + { + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + /** + * @brief Compare substring to a string. + * @param pos Index of first character of substring. + * @param n Number of characters in substring. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a str, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a str. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and @a str.size(). The function then compares the two + * strings by calling traits::compare(substring.data(),str.data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param str String to compare against. + * @param pos2 Index of first character of substring of str. + * @param n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form the substring of @a str from the @a n2 characters + * starting at @a pos2. Returns an integer < 0 if this substring is + * ordered before the substring of @a str, 0 if their values are + * equivalent, or > 0 if this substring is ordered after the substring + * of @a str. Determines the effective length rlen of the strings + * to compare as the smallest of the lengths of the substrings. The + * function then compares the two strings by calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param pos Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a s, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a s. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and the length of a string constructed from @a s. The + * function then compares the two string by calling + * traits::compare(substring.data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character array. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s character array to compare against. + * @param n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form a string from the first @a n2 characters of @a s. + * Returns an integer < 0 if this substring is ordered before the string + * from @a s, 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a s. Determines the effective + * length rlen of the strings to compare as the smallest of the length + * of the substring and @a n2. The function then compares the two + * strings by calling traits::compare(substring.data(),s,rlen). If the + * result of the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\0' has no special + * meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; + + template + inline basic_string<_CharT, _Traits, _Alloc>:: + basic_string() +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } +#else + : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } +#endif + + // operator+ + /** + * @brief Concatenate two strings. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + /** + * @brief Concatenate C string and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + /** + * @brief Concatenate character and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template + basic_string<_CharT,_Traits,_Alloc> + operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + + /** + * @brief Concatenate string and C string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { + basic_string<_CharT, _Traits, _Alloc> __str(__lhs); + __str.append(__rhs); + return __str; + } + + /** + * @brief Concatenate string and character. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template + inline basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str(__lhs); + __str.append(__size_type(1), __rhs); + return __str; + } + + // operator == + /** + * @brief Test equivalence of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Test equivalence of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. + */ + template + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + /** + * @brief Test equivalence of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template + inline bool + operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } + + // operator != + /** + * @brief Test difference of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. + */ + template + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template + inline bool + operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) != 0; } + + // operator < + /** + * @brief Test if string precedes string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if string precedes C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template + inline bool + operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if C string precedes string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) > 0; } + + // operator > + /** + * @brief Test if string follows string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if string follows C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template + inline bool + operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if C string follows string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) < 0; } + + // operator <= + /** + * @brief Test if string doesn't follow string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if string doesn't follow C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template + inline bool + operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if C string doesn't follow string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) >= 0; } + + // operator >= + /** + * @brief Test if string doesn't precede string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if string doesn't precede C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template + inline bool + operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if C string doesn't precede string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { return __rhs.compare(__lhs) <= 0; } + + /** + * @brief Swap contents of two strings. + * @param lhs First string. + * @param rhs Second string. + * + * Exchanges the contents of @a lhs and @a rhs in constant time. + */ + template + inline void + swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, + basic_string<_CharT, _Traits, _Alloc>& __rhs) + { __lhs.swap(__rhs); } + + /** + * @brief Read stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until whitespace is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. + */ + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); + + /** + * @brief Write string to a stream. + * @param os Output stream. + * @param str String to write out. + * @return Reference to the output stream. + * + * Output characters of @a str into os following the same rules as for + * writing a C string. + */ + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Alloc>& __str); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @param delim Character marking end of line. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until @a delim is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. If @a + * delim was encountered, it is extracted but not stored into @a str. + */ + template + basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from is into @a str until '\n' is found, the end of + * the stream is encountered, or str.max_size() is reached. If is.width() + * is non-zero, that is the limit on the number of characters stored into + * @a str. Any previous contents of @a str are erased. If end of line was + * encountered, it is extracted but not stored into @a str. + */ + template + inline basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + basic_string<_CharT, _Traits, _Alloc>& __str); +} // namespace std + +#pragma GCC visibility pop + +#endif /* _BASIC_STRING_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.tcc new file mode 100644 index 00000000000..fc9011187ba --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/basic_string.tcc @@ -0,0 +1,975 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +// This file is included by . It is not meant to be included +// separately. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. + +#ifndef _BASIC_STRING_TCC +#define _BASIC_STRING_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template + inline bool + __is_null_pointer(_Type) + { return false; } + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; + + template + const _CharT + basic_string<_CharT, _Traits, _Alloc>:: + _Rep::_S_terminal = _CharT(); + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) + // at static init time (before static ctors are run). + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ + (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / + sizeof(size_type)]; + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + input_iterator_tag) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // Avoid reallocation for common case. + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + traits_type::copy(__r->_M_refdata(), __buf, __len); + try + { + while (__beg != __end) + { + if (__len == __r->_M_capacity) + { + // Allocate more space. + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + traits_type::copy(__another->_M_refdata(), + __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + } + __r->_M_refdata()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_length = __len; + __r->_M_refdata()[__len] = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); + } + + template + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + forward_iterator_tag) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // NB: Not required, but considered best practice. + if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0)) + __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); + + const size_type __dnew = static_cast(std::distance(__beg, + __end)); + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try + { _S_copy_chars(__r->_M_refdata(), __beg, __end); } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_length = __dnew; + __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); + } + + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refdata(); +#endif + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + traits_type::assign(__r->_M_refdata(), __n, __c); + + __r->_M_length = __n; + __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr + return __r->_M_refdata(); + } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), + __str.get_allocator()), + __str.get_allocator()) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _Alloc& __a) + : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, size_type __n) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()), _Alloc()) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a), __a) + { } + + // TBD: DPG annotate + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) + { } + + // TBD: DPG annotate + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const _CharT* __s, const _Alloc& __a) + : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : + __s + npos, __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(_S_construct(__n, __c, __a), __a) + { } + + // TBD: DPG annotate + template + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) + : _M_dataplus(_S_construct(__beg, __end, __a), __a) + { } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + // XXX MT + const allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + if (__n > this->max_size()) + __throw_length_error(__N("basic_string::assign")); + if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)) + return _M_replace_safe(size_type(0), this->size(), __s, __n); + else + { + // Work in-place + const size_type __pos = __s - _M_data(); + if (__pos >= __n) + traits_type::copy(_M_data(), __s, __n); + else if (__pos) + traits_type::move(_M_data(), __s, __n); + _M_rep()->_M_set_sharable(); + _M_rep()->_M_length = __n; + _M_data()[__n] = _Rep::_S_terminal; // grr. + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check(__pos, "basic_string::insert"); + if (this->max_size() - this->size() < __n) + __throw_length_error(__N("basic_string::insert")); + if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)) + return _M_replace_safe(__pos, size_type(0), __s, __n); + else + { + // Work in-place. If _M_mutate reallocates the string, __s + // does not point anymore to valid data, therefore we save its + // offset, then we restore it. + const size_type __off = __s - _M_data(); + _M_mutate(__pos, 0, __n); + __s = _M_data() + __off; + _CharT* __p = _M_data() + __pos; + if (__s + __n <= __p) + traits_type::copy(__p, __s, __n); + else if (__s >= __p) + traits_type::copy(__p, __s + __n, __n); + else + { + const size_type __nleft = __p - __s; + traits_type::copy(__p, __s, __nleft); + traits_type::copy(__p + __nleft, __p + __n, __n - __nleft); + } + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::replace"); + __n1 = _M_limit(__pos, __n1); + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N("basic_string::replace")); + bool __left; + if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)) + return _M_replace_safe(__pos, __n1, __s, __n2); + else if ((__left = __s + __n2 <= _M_data() + __pos) + || _M_data() + __pos + __n1 <= __s) + { + // Work in-place: non-overlapping case. + const size_type __off = __s - _M_data(); + _M_mutate(__pos, __n1, __n2); + if (__left) + traits_type::copy(_M_data() + __pos, + _M_data() + __off, __n2); + else + traits_type::copy(_M_data() + __pos, + _M_data() + __off + __n2 - __n1, __n2); + return *this; + } + else + { + // Todo: overlapping case. + const basic_string __tmp(__s, __n2); + return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); + } + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (this == &_S_empty_rep()) + return; +#endif + const size_type __size = sizeof(_Rep_base) + + (this->_M_capacity + 1) * sizeof(_CharT); + _Raw_bytes_alloc(__a).deallocate(reinterpret_cast(this), __size); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard() + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (_M_rep() == &_S_empty_rep()) + return; +#endif + if (_M_rep()->_M_is_shared()) + _M_mutate(0, 0, 0); + _M_rep()->_M_set_leaked(); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, size_type __len2) + { + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + const size_type __how_much = __old_size - __pos - __len1; + + if (__new_size > capacity() || _M_rep()->_M_is_shared()) + { + // Must reallocate. + const allocator_type __a = get_allocator(); + _Rep* __r = _Rep::_S_create(__new_size, capacity(), __a); + + if (__pos) + traits_type::copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + traits_type::copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_rep()->_M_dispose(__a); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __len1 != __len2) + { + // Work in-place + traits_type::move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + } + _M_rep()->_M_set_sharable(); + _M_rep()->_M_length = __new_size; + _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res) + { + if (__res != this->capacity() || _M_rep()->_M_is_shared()) + { + if (__res > this->max_size()) + __throw_length_error(__N("basic_string::reserve")); + // Make sure we don't shrink below the current size + if (__res < this->size()) + __res = this->size(); + const allocator_type __a = get_allocator(); + _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + } + + template + void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s) + { + if (_M_rep()->_M_is_leaked()) + _M_rep()->_M_set_sharable(); + if (__s._M_rep()->_M_is_leaked()) + __s._M_rep()->_M_set_sharable(); + if (this->get_allocator() == __s.get_allocator()) + { + _CharT* __tmp = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp); + } + // The code below can usually be optimized away. + else + { + const basic_string __tmp1(_M_ibegin(), _M_iend(), + __s.get_allocator()); + const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), + this->get_allocator()); + *this = __tmp2; + __s = __tmp1; + } + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::_Rep* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > _S_max_size) + __throw_length_error(__N("basic_string::_S_create")); + + // The standard places no restriction on allocating more memory + // than is strictly needed within this layer at the moment or as + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an + // application attempts to allocate memory in a stepwise fashion + // growing each allocation size by only 1 char. Additionally, + // it makes little sense to allocate less linear memory than the + // natural blocking size of the malloc implementation. + // Unfortunately, we would need a somewhat low-level calculation + // with tuned parameters to get this perfect for any particular + // malloc implementation. Fortunately, generalizations about + // common features seen among implementations seems to suffice. + + // __pagesize need not match the actual VM page size for good + // results in practice, thus we pick a common value on the low + // side. __malloc_header_size is an estimate of the amount of + // overhead per memory allocation (in practice seen N * sizeof + // (void*) where N is 0, 2 or 4). According to folklore, + // picking this value on the high side is better than + // low-balling it (especially when this algorithm is used with + // malloc implementations that allocate memory blocks rounded up + // to a size which is a power of 2). + const size_type __pagesize = 4096; // must be 2^i * __subpagesize + const size_type __subpagesize = 128; // should be >> __malloc_header_size + const size_type __malloc_header_size = 4 * sizeof (void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + // It's active for allocations requiring an amount of memory above + // system pagesize. This is consistent with the requirements of the + // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html + + // The biggest string which fits in a memory page + const size_type __page_capacity = ((__pagesize - __malloc_header_size + - sizeof(_Rep) - sizeof(_CharT)) + / sizeof(_CharT)); + + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity + && __capacity > __page_capacity) + __capacity = 2 * __old_capacity; + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure. + // Whew. Seemingly so needy, yet so elemental. + size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize) + { + const size_type __extra = __pagesize - __adj_size % __pagesize; + __capacity += __extra / sizeof(_CharT); + // Never allocate a string bigger than _S_max_size. + if (__capacity > _S_max_size) + __capacity = _S_max_size; + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + } + else if (__size > __subpagesize) + { + const size_type __extra = __subpagesize - __adj_size % __subpagesize; + __capacity += __extra / sizeof(_CharT); + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + } + + // NB: Might throw, but no worries about a leak, mate: _Rep() + // does not throw. + void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); + _Rep *__p = new (__place) _Rep; + __p->_M_capacity = __capacity; + __p->_M_set_sharable(); // One reference. + __p->_M_length = 0; + return __p; + } + + template + _CharT* + basic_string<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + // Requested capacity of the clone. + const size_type __requested_cap = this->_M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, + __alloc); + if (this->_M_length) + traits_type::copy(__r->_M_refdata(), _M_refdata(), + this->_M_length); + + __r->_M_length = this->_M_length; + __r->_M_refdata()[this->_M_length] = _Rep::_S_terminal; + return __r->_M_refdata(); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c) + { + if (__n > max_size()) + __throw_length_error(__N("basic_string::resize")); + const size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->erase(__n); + // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) + } + + template + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type) + { + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + if (this->max_size() - (this->size() - __n1) < __s.size()) + __throw_length_error(__N("basic_string::_M_replace_dispatch")); + return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str) + { + // Iff appending itself, string needs to pre-reserve the + // correct size so that _M_mutate does not clobber the + // pointer __str._M_data() formed here. + const size_type __size = __str.size(); + const size_type __len = __size + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return _M_replace_safe(this->size(), size_type(0), __str._M_data(), + __str.size()); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + // Iff appending itself, string needs to pre-reserve the + // correct size so that _M_mutate does not clobber the + // pointer __str._M_data() formed here. + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + const size_type __len = __n + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return _M_replace_safe(this->size(), size_type(0), __str._M_data() + + __pos, __n); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + const size_type __len = __n + this->size(); + if (__len > this->capacity()) + this->reserve(__len); + return _M_replace_safe(this->size(), size_type(0), __s, __n); + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(const _CharT* __lhs, + const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + __glibcxx_requires_string(__lhs); + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __len); + __str.append(__rhs); + return __str; + } + + template + basic_string<_CharT, _Traits, _Alloc> + operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + { + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + __string_type __str; + const __size_type __len = __rhs.size(); + __str.reserve(__len + 1); + __str.append(__size_type(1), __lhs); + __str.append(__rhs); + return __str; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + traits_type::copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + const _CharT* __data = _M_data(); + for (; __pos + __n <= __size; ++__pos) + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find(_CharT __c, size_type __pos) const + { + const size_type __size = this->size(); + size_type __ret = npos; + if (__pos < __size) + { + const _CharT* __data = _M_data(); + const size_type __n = __size - __pos; + const _CharT* __p = traits_type::find(__data + __pos, __n, __c); + if (__p) + __ret = __p - __data; + } + return __ret; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(size_type(__size - __n), __pos); + const _CharT* __data = _M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(_M_data()[__size], __c)) + return __size; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, _M_data()[__pos])) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(_M_data()[__pos], __c)) + return __pos; + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__s, __n, _M_data()[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n, const basic_string& __str) const + { + _M_check(__pos, "basic_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); + int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); + if (!__r) + __r = __n - __osize; + return __r; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { + _M_check(__pos1, "basic_string::compare"); + __str._M_check(__pos2, "basic_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + template + int + basic_string<_CharT, _Traits, _Alloc>:: + compare(const _CharT* __s) const + { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); + int __r = traits_type::compare(_M_data(), __s, __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + template + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s) const + { + __glibcxx_requires_string(__s); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __osize; + return __r; + } + + template + int + basic_string <_CharT, _Traits, _Alloc>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_string; + extern template + basic_istream& + operator>>(basic_istream&, string&); + extern template + basic_ostream& + operator<<(basic_ostream&, const string&); + extern template + basic_istream& + getline(basic_istream&, string&, char); + extern template + basic_istream& + getline(basic_istream&, string&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_string; + extern template + basic_istream& + operator>>(basic_istream&, wstring&); + extern template + basic_ostream& + operator<<(basic_ostream&, const wstring&); + extern template + basic_istream& + getline(basic_istream&, wstring&, wchar_t); + extern template + basic_istream& + getline(basic_istream&, wstring&); +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/boost_concept_check.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/boost_concept_check.h new file mode 100644 index 00000000000..ff154f73a49 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/boost_concept_check.h @@ -0,0 +1,932 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// + +// GCC Note: based on version 1.12.0 of the Boost library. + +/** @file boost_concept_check.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BOOST_CONCEPT_CHECK_H +#define _BOOST_CONCEPT_CHECK_H 1 + +#pragma GCC system_header + +#include // for ptrdiff_t, used next +#include // for traits and tags +#include // for pair<> + +namespace __gnu_cxx +{ + +#define _IsUnused __attribute__ ((__unused__)) + +// When the C-C code is in use, we would like this function to do as little +// as possible at runtime, use as few resources as possible, and hopefully +// be elided out of existence... hmmm. +template +inline void __function_requires() +{ + void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; +} + +// No definition: if this is referenced, there's a problem with +// the instantiating type not being one of the required integer types. +// Unfortunately, this results in a link-time error, not a compile-time error. +void __error_type_must_be_an_integer_type(); +void __error_type_must_be_an_unsigned_integer_type(); +void __error_type_must_be_a_signed_integer_type(); + +// ??? Should the "concept_checking*" structs begin with more than _ ? +#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ + typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ + template <_func##_type_var##_concept _Tp1> \ + struct _concept_checking##_type_var##_concept { }; \ + typedef _concept_checking##_type_var##_concept< \ + &_ns::_concept <_type_var>::__constraints> \ + _concept_checking_typedef##_type_var##_concept + +#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ + template <_func##_type_var1##_type_var2##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_concept< \ + &_ns::_concept <_type_var1,_type_var2>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_concept + +#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ + template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ + &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept + +#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ + typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ + template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ + struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ + typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ + &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ + _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept + + +template +struct _Aux_require_same { }; + +template +struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; + + template + struct _SameTypeConcept + { + void __constraints() { + typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; + } + }; + + template + struct _IntegerConcept { + void __constraints() { + __error_type_must_be_an_integer_type(); + } + }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints(){} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept { void __constraints() {} }; + template <> struct _IntegerConcept + { void __constraints() {} }; + + template + struct _SignedIntegerConcept { + void __constraints() { + __error_type_must_be_a_signed_integer_type(); + } + }; + template <> struct _SignedIntegerConcept { void __constraints() {} }; + template <> struct _SignedIntegerConcept { void __constraints() {} }; + template <> struct _SignedIntegerConcept { void __constraints() {} }; + template <> struct _SignedIntegerConcept { void __constraints(){}}; + + template + struct _UnsignedIntegerConcept { + void __constraints() { + __error_type_must_be_an_unsigned_integer_type(); + } + }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + template <> struct _UnsignedIntegerConcept + { void __constraints() {} }; + + //=========================================================================== + // Basic Concepts + + template + struct _DefaultConstructibleConcept + { + void __constraints() { + _Tp __a _IsUnused; // require default constructor + } + }; + + template + struct _AssignableConcept + { + void __constraints() { + __a = __a; // require assignment operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __b) { + __a = __b; // const required for argument to assignment + } + _Tp __a; + // possibly should be "Tp* a;" and then dereference "a" in constraint + // functions? present way would require a default ctor, i think... + }; + + template + struct _CopyConstructibleConcept + { + void __constraints() { + _Tp __a(__b); // require copy constructor + _Tp* __ptr _IsUnused = &__a; // require address of operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __a) { + _Tp __c _IsUnused(__a); // require const copy constructor + const _Tp* __ptr _IsUnused = &__a; // require const address of operator + } + _Tp __b; + }; + + // The SGI STL version of Assignable requires copy constructor and operator= + template + struct _SGIAssignableConcept + { + void __constraints() { + _Tp __b _IsUnused(__a); + __a = __a; // require assignment operator + __const_constraints(__a); + } + void __const_constraints(const _Tp& __b) { + _Tp __c _IsUnused(__b); + __a = __b; // const required for argument to assignment + } + _Tp __a; + }; + + template + struct _ConvertibleConcept + { + void __constraints() { + _To __y _IsUnused = __x; + } + _From __x; + }; + + // The C++ standard requirements for many concepts talk about return + // types that must be "convertible to bool". The problem with this + // requirement is that it leaves the door open for evil proxies that + // define things like operator|| with strange return types. Two + // possible solutions are: + // 1) require the return type to be exactly bool + // 2) stay with convertible to bool, and also + // specify stuff about all the logical operators. + // For now we just test for convertible to bool. + template + void __aux_require_boolean_expr(const _Tp& __t) { + bool __x _IsUnused = __t; + } + +// FIXME + template + struct _EqualityComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a == __b); + } + _Tp __a, __b; + }; + + template + struct _LessThanComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a < __b); + } + _Tp __a, __b; + }; + + // This is equivalent to SGI STL's LessThanComparable. + template + struct _ComparableConcept + { + void __constraints() { + __aux_require_boolean_expr(__a < __b); + __aux_require_boolean_expr(__a > __b); + __aux_require_boolean_expr(__a <= __b); + __aux_require_boolean_expr(__a >= __b); + } + _Tp __a, __b; + }; + +#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ + template \ + struct _NAME { \ + void __constraints() { (void)__constraints_(); } \ + bool __constraints_() { \ + return __a _OP __b; \ + } \ + _First __a; \ + _Second __b; \ + } + +#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ + template \ + struct _NAME { \ + void __constraints() { (void)__constraints_(); } \ + _Ret __constraints_() { \ + return __a _OP __b; \ + } \ + _First __a; \ + _Second __b; \ + } + + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); + + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); + +#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT +#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT + + //=========================================================================== + // Function Object Concepts + + template + struct _GeneratorConcept + { + void __constraints() { + const _Return& __r _IsUnused = __f();// require operator() member function + } + _Func __f; + }; + + + template + struct _GeneratorConcept<_Func,void> + { + void __constraints() { + __f(); // require operator() member function + } + _Func __f; + }; + + template + struct _UnaryFunctionConcept + { + void __constraints() { + __r = __f(__arg); // require operator() + } + _Func __f; + _Arg __arg; + _Return __r; + }; + + template + struct _UnaryFunctionConcept<_Func, void, _Arg> { + void __constraints() { + __f(__arg); // require operator() + } + _Func __f; + _Arg __arg; + }; + + template + struct _BinaryFunctionConcept + { + void __constraints() { + __r = __f(__first, __second); // require operator() + } + _Func __f; + _First __first; + _Second __second; + _Return __r; + }; + + template + struct _BinaryFunctionConcept<_Func, void, _First, _Second> + { + void __constraints() { + __f(__first, __second); // require operator() + } + _Func __f; + _First __first; + _Second __second; + }; + + template + struct _UnaryPredicateConcept + { + void __constraints() { + __aux_require_boolean_expr(__f(__arg)); // require op() returning bool + } + _Func __f; + _Arg __arg; + }; + + template + struct _BinaryPredicateConcept + { + void __constraints() { + __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool + } + _Func __f; + _First __a; + _Second __b; + }; + + // use this when functor is used inside a container class like std::set + template + struct _Const_BinaryPredicateConcept { + void __constraints() { + __const_constraints(__f); + } + void __const_constraints(const _Func& __fun) { + __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); + // operator() must be a const member function + __aux_require_boolean_expr(__fun(__a, __b)); + } + _Func __f; + _First __a; + _Second __b; + }; + + //=========================================================================== + // Iterator Concepts + + template + struct _TrivialIteratorConcept + { + void __constraints() { +// __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _AssignableConcept<_Tp> >(); + __function_requires< _EqualityComparableConcept<_Tp> >(); +// typedef typename std::iterator_traits<_Tp>::value_type _V; + (void)*__i; // require dereference operator + } + _Tp __i; + }; + + template + struct _Mutable_TrivialIteratorConcept + { + void __constraints() { + __function_requires< _TrivialIteratorConcept<_Tp> >(); + *__i = *__j; // require dereference and assignment + } + _Tp __i, __j; + }; + + template + struct _InputIteratorConcept + { + void __constraints() { + __function_requires< _TrivialIteratorConcept<_Tp> >(); + // require iterator_traits typedef's + typedef typename std::iterator_traits<_Tp>::difference_type _Diff; +// __function_requires< _SignedIntegerConcept<_Diff> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; + typedef typename std::iterator_traits<_Tp>::pointer _Pt; + typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::input_iterator_tag> >(); + ++__i; // require preincrement operator + __i++; // require postincrement operator + } + _Tp __i; + }; + + template + struct _OutputIteratorConcept + { + void __constraints() { + __function_requires< _AssignableConcept<_Tp> >(); + ++__i; // require preincrement operator + __i++; // require postincrement operator + *__i++ = __t; // require postincrement and assignment + } + _Tp __i; + _ValueT __t; + }; + + template + struct _ForwardIteratorConcept + { + void __constraints() { + __function_requires< _InputIteratorConcept<_Tp> >(); + __function_requires< _DefaultConstructibleConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::forward_iterator_tag> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; + _Ref __r _IsUnused = *__i; + } + _Tp __i; + }; + + template + struct _Mutable_ForwardIteratorConcept + { + void __constraints() { + __function_requires< _ForwardIteratorConcept<_Tp> >(); + *__i++ = *__i; // require postincrement and assignment + } + _Tp __i; + }; + + template + struct _BidirectionalIteratorConcept + { + void __constraints() { + __function_requires< _ForwardIteratorConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::bidirectional_iterator_tag> >(); + --__i; // require predecrement operator + __i--; // require postdecrement operator + } + _Tp __i; + }; + + template + struct _Mutable_BidirectionalIteratorConcept + { + void __constraints() { + __function_requires< _BidirectionalIteratorConcept<_Tp> >(); + __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >(); + *__i-- = *__i; // require postdecrement and assignment + } + _Tp __i; + }; + + + template + struct _RandomAccessIteratorConcept + { + void __constraints() { + __function_requires< _BidirectionalIteratorConcept<_Tp> >(); + __function_requires< _ComparableConcept<_Tp> >(); + __function_requires< _ConvertibleConcept< + typename std::iterator_traits<_Tp>::iterator_category, + std::random_access_iterator_tag> >(); + // ??? We don't use _Ref, are we just checking for "referenceability"? + typedef typename std::iterator_traits<_Tp>::reference _Ref; + + __i += __n; // require assignment addition operator + __i = __i + __n; __i = __n + __i; // require addition with difference type + __i -= __n; // require assignment subtraction op + __i = __i - __n; // require subtraction with + // difference type + __n = __i - __j; // require difference operator + (void)__i[__n]; // require element access operator + } + _Tp __a, __b; + _Tp __i, __j; + typename std::iterator_traits<_Tp>::difference_type __n; + }; + + template + struct _Mutable_RandomAccessIteratorConcept + { + void __constraints() { + __function_requires< _RandomAccessIteratorConcept<_Tp> >(); + __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >(); + __i[__n] = *__i; // require element access and assignment + } + _Tp __i; + typename std::iterator_traits<_Tp>::difference_type __n; + }; + + //=========================================================================== + // Container Concepts + + template + struct _ContainerConcept + { + typedef typename _Container::value_type _Value_type; + typedef typename _Container::difference_type _Difference_type; + typedef typename _Container::size_type _Size_type; + typedef typename _Container::const_reference _Const_reference; + typedef typename _Container::const_pointer _Const_pointer; + typedef typename _Container::const_iterator _Const_iterator; + + void __constraints() { + __function_requires< _InputIteratorConcept<_Const_iterator> >(); + __function_requires< _AssignableConcept<_Container> >(); + const _Container __c; + __i = __c.begin(); + __i = __c.end(); + __n = __c.size(); + __n = __c.max_size(); + __b = __c.empty(); + } + bool __b; + _Const_iterator __i; + _Size_type __n; + }; + + template + struct _Mutable_ContainerConcept + { + typedef typename _Container::value_type _Value_type; + typedef typename _Container::reference _Reference; + typedef typename _Container::iterator _Iterator; + typedef typename _Container::pointer _Pointer; + + void __constraints() { + __function_requires< _ContainerConcept<_Container> >(); + __function_requires< _AssignableConcept<_Value_type> >(); + __function_requires< _InputIteratorConcept<_Iterator> >(); + + __i = __c.begin(); + __i = __c.end(); + __c.swap(__c2); + } + _Iterator __i; + _Container __c, __c2; + }; + + template + struct _ForwardContainerConcept + { + void __constraints() { + __function_requires< _ContainerConcept<_ForwardContainer> >(); + typedef typename _ForwardContainer::const_iterator _Const_iterator; + __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); + } + }; + + template + struct _Mutable_ForwardContainerConcept + { + void __constraints() { + __function_requires< _ForwardContainerConcept<_ForwardContainer> >(); + __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >(); + typedef typename _ForwardContainer::iterator _Iterator; + __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); + } + }; + + template + struct _ReversibleContainerConcept + { + typedef typename _ReversibleContainer::const_iterator _Const_iterator; + typedef typename _ReversibleContainer::const_reverse_iterator + _Const_reverse_iterator; + + void __constraints() { + __function_requires< _ForwardContainerConcept<_ReversibleContainer> >(); + __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >(); + __function_requires< + _BidirectionalIteratorConcept<_Const_reverse_iterator> >(); + + const _ReversibleContainer __c; + _Const_reverse_iterator __i = __c.rbegin(); + __i = __c.rend(); + } + }; + + template + struct _Mutable_ReversibleContainerConcept + { + typedef typename _ReversibleContainer::iterator _Iterator; + typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator; + + void __constraints() { + __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >(); + __function_requires< + _Mutable_ForwardContainerConcept<_ReversibleContainer> >(); + __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >(); + __function_requires< + _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >(); + + _Reverse_iterator __i = __c.rbegin(); + __i = __c.rend(); + } + _ReversibleContainer __c; + }; + + template + struct _RandomAccessContainerConcept + { + typedef typename _RandomAccessContainer::size_type _Size_type; + typedef typename _RandomAccessContainer::const_reference _Const_reference; + typedef typename _RandomAccessContainer::const_iterator _Const_iterator; + typedef typename _RandomAccessContainer::const_reverse_iterator + _Const_reverse_iterator; + + void __constraints() { + __function_requires< + _ReversibleContainerConcept<_RandomAccessContainer> >(); + __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >(); + __function_requires< + _RandomAccessIteratorConcept<_Const_reverse_iterator> >(); + + const _RandomAccessContainer __c; + _Const_reference __r _IsUnused = __c[__n]; + } + _Size_type __n; + }; + + template + struct _Mutable_RandomAccessContainerConcept + { + typedef typename _RandomAccessContainer::size_type _Size_type; + typedef typename _RandomAccessContainer::reference _Reference; + typedef typename _RandomAccessContainer::iterator _Iterator; + typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator; + + void __constraints() { + __function_requires< + _RandomAccessContainerConcept<_RandomAccessContainer> >(); + __function_requires< + _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >(); + __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >(); + __function_requires< + _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >(); + + _Reference __r _IsUnused = __c[__i]; + } + _Size_type __i; + _RandomAccessContainer __c; + }; + + // A Sequence is inherently mutable + template + struct _SequenceConcept + { + typedef typename _Sequence::reference _Reference; + typedef typename _Sequence::const_reference _Const_reference; + + void __constraints() { + // Matt Austern's book puts DefaultConstructible here, the C++ + // standard places it in Container + // function_requires< DefaultConstructible >(); + __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); + __function_requires< _DefaultConstructibleConcept<_Sequence> >(); + + _Sequence + __c _IsUnused(__n, __t), + __c2 _IsUnused(__first, __last); + + __c.insert(__p, __t); + __c.insert(__p, __n, __t); + __c.insert(__p, __first, __last); + + __c.erase(__p); + __c.erase(__p, __q); + + _Reference __r _IsUnused = __c.front(); + + __const_constraints(__c); + } + void __const_constraints(const _Sequence& __c) { + _Const_reference __r _IsUnused = __c.front(); + } + typename _Sequence::value_type __t; + typename _Sequence::size_type __n; + typename _Sequence::value_type *__first, *__last; + typename _Sequence::iterator __p, __q; + }; + + template + struct _FrontInsertionSequenceConcept + { + void __constraints() { + __function_requires< _SequenceConcept<_FrontInsertionSequence> >(); + + __c.push_front(__t); + __c.pop_front(); + } + _FrontInsertionSequence __c; + typename _FrontInsertionSequence::value_type __t; + }; + + template + struct _BackInsertionSequenceConcept + { + typedef typename _BackInsertionSequence::reference _Reference; + typedef typename _BackInsertionSequence::const_reference _Const_reference; + + void __constraints() { + __function_requires< _SequenceConcept<_BackInsertionSequence> >(); + + __c.push_back(__t); + __c.pop_back(); + _Reference __r _IsUnused = __c.back(); + } + void __const_constraints(const _BackInsertionSequence& __c) { + _Const_reference __r _IsUnused = __c.back(); + }; + _BackInsertionSequence __c; + typename _BackInsertionSequence::value_type __t; + }; + + template + struct _AssociativeContainerConcept + { + void __constraints() { + __function_requires< _ForwardContainerConcept<_AssociativeContainer> >(); + __function_requires< + _DefaultConstructibleConcept<_AssociativeContainer> >(); + + __i = __c.find(__k); + __r = __c.equal_range(__k); + __c.erase(__k); + __c.erase(__i); + __c.erase(__r.first, __r.second); + __const_constraints(__c); + } + void __const_constraints(const _AssociativeContainer& __c) { + __ci = __c.find(__k); + __n = __c.count(__k); + __cr = __c.equal_range(__k); + } + typedef typename _AssociativeContainer::iterator _Iterator; + typedef typename _AssociativeContainer::const_iterator _Const_iterator; + + _AssociativeContainer __c; + _Iterator __i; + std::pair<_Iterator,_Iterator> __r; + _Const_iterator __ci; + std::pair<_Const_iterator,_Const_iterator> __cr; + typename _AssociativeContainer::key_type __k; + typename _AssociativeContainer::size_type __n; + }; + + template + struct _UniqueAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_UniqueAssociativeContainer> >(); + + _UniqueAssociativeContainer __c(__first, __last); + + __pos_flag = __c.insert(__t); + __c.insert(__first, __last); + } + std::pair __pos_flag; + typename _UniqueAssociativeContainer::value_type __t; + typename _UniqueAssociativeContainer::value_type *__first, *__last; + }; + + template + struct _MultipleAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_MultipleAssociativeContainer> >(); + + _MultipleAssociativeContainer __c(__first, __last); + + __pos = __c.insert(__t); + __c.insert(__first, __last); + + } + typename _MultipleAssociativeContainer::iterator __pos; + typename _MultipleAssociativeContainer::value_type __t; + typename _MultipleAssociativeContainer::value_type *__first, *__last; + }; + + template + struct _SimpleAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SimpleAssociativeContainer> >(); + typedef typename _SimpleAssociativeContainer::key_type _Key_type; + typedef typename _SimpleAssociativeContainer::value_type _Value_type; + typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type + _Required; + } + }; + + template + struct _PairAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SimpleAssociativeContainer> >(); + typedef typename _SimpleAssociativeContainer::key_type _Key_type; + typedef typename _SimpleAssociativeContainer::value_type _Value_type; + typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type; + typedef std::pair _Required_value_type; + typedef typename _Aux_require_same<_Value_type, + _Required_value_type>::_Type _Required; + } + }; + + template + struct _SortedAssociativeContainerConcept + { + void __constraints() { + __function_requires< + _AssociativeContainerConcept<_SortedAssociativeContainer> >(); + __function_requires< + _ReversibleContainerConcept<_SortedAssociativeContainer> >(); + + _SortedAssociativeContainer + __c _IsUnused(__kc), + __c2 _IsUnused(__first, __last), + __c3 _IsUnused(__first, __last, __kc); + + __p = __c.upper_bound(__k); + __p = __c.lower_bound(__k); + __r = __c.equal_range(__k); + + __c.insert(__p, __t); + } + void __const_constraints(const _SortedAssociativeContainer& __c) { + __kc = __c.key_comp(); + __vc = __c.value_comp(); + + __cp = __c.upper_bound(__k); + __cp = __c.lower_bound(__k); + __cr = __c.equal_range(__k); + } + typename _SortedAssociativeContainer::key_compare __kc; + typename _SortedAssociativeContainer::value_compare __vc; + typename _SortedAssociativeContainer::value_type __t; + typename _SortedAssociativeContainer::key_type __k; + typedef typename _SortedAssociativeContainer::iterator _Iterator; + typedef typename _SortedAssociativeContainer::const_iterator + _Const_iterator; + + _Iterator __p; + _Const_iterator __cp; + std::pair<_Iterator,_Iterator> __r; + std::pair<_Const_iterator,_Const_iterator> __cr; + typename _SortedAssociativeContainer::value_type *__first, *__last; + }; + + // HashedAssociativeContainer + +} // namespace __gnu_cxx + +#undef _IsUnused + +#endif // _GLIBCXX_BOOST_CONCEPT_CHECK + + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/char_traits.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/char_traits.h new file mode 100644 index 00000000000..323fdfb47c0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/char_traits.h @@ -0,0 +1,376 @@ +// Character Traits for use by standard string and iostream -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file char_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CHAR_TRAITS_H +#define _CHAR_TRAITS_H 1 + +#pragma GCC system_header + +#include // For memmove, memset, memchr +#include // For copy, lexicographical_compare, fill_n +#include // For streampos + +namespace __gnu_cxx +{ + /** + * @brief Mapping from character type to associated types. + * + * + * @note This is an implementation class for the generic version + * of char_traits. It defines int_type, off_type, pos_type, and + * state_type. By default these are unsigned long, streamoff, + * streampos, and mbstate_t. Users who need a different set of + * types, but who don't need to change the definitions of any function + * defined in char_traits, can specialize __gnu_cxx::_Char_types + * while leaving __gnu_cxx::char_traits alone. */ + template + struct _Char_types + { + typedef unsigned long int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + typedef std::mbstate_t state_type; + }; + + + /** + * @brief Base class used to implement std::char_traits. + * + * @note For any given actual character type, this definition is + * probably wrong. (Most of the member functions are likely to be + * right, but the int_type and state_type typedefs, and the eof() + * member function, are likely to be wrong.) The reason this class + * exists is so users can specialize it. Classes in namespace std + * may not be specialized for fundamentl types, but classes in + * namespace __gnu_cxx may be. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. */ + template + struct char_traits + { + typedef _CharT char_type; + typedef typename _Char_types<_CharT>::int_type int_type; + typedef typename _Char_types<_CharT>::pos_type pos_type; + typedef typename _Char_types<_CharT>::off_type off_type; + typedef typename _Char_types<_CharT>::state_type state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, std::size_t __n); + + static std::size_t + length(const char_type* __s); + + static const char_type* + find(const char_type* __s, std::size_t __n, const char_type& __a); + + static char_type* + move(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + copy(char_type* __s1, const char_type* __s2, std::size_t __n); + + static char_type* + assign(char_type* __s, std::size_t __n, char_type __a); + + static char_type + to_char_type(const int_type& __c) + { return static_cast(__c); } + + static int_type + to_int_type(const char_type& __c) + { return static_cast(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() + { return static_cast(EOF); } + + static int_type + not_eof(const int_type& __c) + { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } + }; + + template + int + char_traits<_CharT>:: + compare(const char_type* __s1, const char_type* __s2, std::size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (lt(__s1[__i], __s2[__i])) + return -1; + else if (lt(__s2[__i], __s1[__i])) + return 1; + return 0; + } + + template + std::size_t + char_traits<_CharT>:: + length(const char_type* __p) + { + std::size_t __i = 0; + while (!eq(__p[__i], char_type())) + ++__i; + return __i; + } + + template + const typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + find(const char_type* __s, std::size_t __n, const char_type& __a) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (eq(__s[__i], __a)) + return __s + __i; + return 0; + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + move(char_type* __s1, const char_type* __s2, std::size_t __n) + { + return static_cast<_CharT*>(std::memmove(__s1, __s2, + __n * sizeof(char_type))); + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + copy(char_type* __s1, const char_type* __s2, std::size_t __n) + { + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } + + template + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + assign(char_type* __s, std::size_t __n, char_type __a) + { + std::fill_n(__s, __n, __a); + return __s; + } +} + +namespace std +{ + // 21.1 + /** + * @brief Basis for explicit traits specializations. + * + * @note For any given actual character type, this definition is + * probably wrong. Since this is just a thin wrapper around + * __gnu_cxx::char_traits, it is possible to achieve a more + * appropriate definition by specializing __gnu_cxx::char_traits. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. + */ + template + struct char_traits + : public __gnu_cxx::char_traits<_CharT> + { }; + + + /// 21.1.3.1 char_traits specializations + template<> + struct char_traits + { + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return memcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return strlen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return static_cast(memchr(__s, __a, __n)); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memmove(__s1, __s2, __n)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return static_cast(memcpy(__s1, __s2, __n)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return static_cast(memset(__s, __a, __n)); } + + static char_type + to_char_type(const int_type& __c) + { return static_cast(__c); } + + // To keep both the byte 0xff and the eof symbol 0xffffffff + // from ending up as 0xffffffff. + static int_type + to_int_type(const char_type& __c) + { return static_cast(static_cast(__c)); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(EOF); } + + static int_type + not_eof(const int_type& __c) + { return (__c == eof()) ? 0 : __c; } + }; + + +#ifdef _GLIBCXX_USE_WCHAR_T + /// 21.1.3.2 char_traits specializations + template<> + struct char_traits + { + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcmp(__s1, __s2, __n); } + + static size_t + length(const char_type* __s) + { return wcslen(__s); } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { return wmemchr(__s, __a, __n); } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemmove(__s1, __s2, __n); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return wmemcpy(__s1, __s2, __n); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { return wmemset(__s, __a, __n); } + + static char_type + to_char_type(const int_type& __c) { return char_type(__c); } + + static int_type + to_int_type(const char_type& __c) { return int_type(__c); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(WEOF); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? 0 : __c; } + }; +#endif //_GLIBCXX_USE_WCHAR_T + + template + struct _Char_traits_match + { + _CharT _M_c; + _Char_traits_match(_CharT const& __c) : _M_c(__c) { } + + bool + operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); } + }; +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/cmath.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/cmath.tcc new file mode 100644 index 00000000000..d771467ec61 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/cmath.tcc @@ -0,0 +1,54 @@ +// -*- C++ -*- C math library. + +// Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file was written by Gabriel Dos Reis + +#ifndef _GLIBCXX_CMATH_TCC +#define _GLIBCXX_CMATH_TCC 1 + +namespace std +{ + template + inline _Tp + __cmath_power(_Tp __x, unsigned int __n) + { + _Tp __y = __n % 2 ? __x : 1; + + while (__n >>= 1) + { + __x = __x * __x; + if (__n % 2) + __y = __y * __x; + } + + return __y; + } +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/codecvt.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/codecvt.h new file mode 100644 index 00000000000..d31ebf2d362 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/codecvt.h @@ -0,0 +1,478 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Written by Benjamin Kosnik + +/** @file codecvt.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CODECVT_H +#define _CODECVT_H 1 + +#pragma GCC system_header + + // 22.2.1.5 Template class codecvt + /// Base class for codecvt facet providing conversion result enum. + class codecvt_base + { + public: + enum result + { + ok, + partial, + error, + noconv + }; + }; + + // Template class __codecvt_abstract_base + // NB: An abstract base class that fills in the public inlines, so + // that the specializations don't have to re-copy the public + // interface. + /** + * @brief Common base for codecvt facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abstract stubs for the protected virtual + * functions. + */ + template + class __codecvt_abstract_base + : public locale::facet, public codecvt_base + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + // 22.2.1.5.1 codecvt members + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This is analogous to wcsrtombs. It does this by + * calling codecvt::do_out. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If all the + * input is converted, returns codecvt_base::ok. If no conversion is + * necessary, returns codecvt_base::noconv. If the input ends early or + * there is insufficient space in the output, returns codecvt_base::partial. + * Otherwise the conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + return this->do_out(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + /** + * @brief Reset conversion state. + * + * Writes characters to output that would restore @a state to initial + * conditions. The idea is that if a partial conversion occurs, then + * the converting the characters written by this function would leave + * the state in initial conditions, rather than partial conversion + * state. It does this by calling codecvt::do_unshift(). + * + * For example, if 4 external characters always converted to 1 internal + * character, and input to in() had 6 external characters with state + * saved, this function would write two characters to the output and + * set the state to initialized conditions. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The result returned is a member of codecvt_base::result. If the + * state could be reset and data written, returns codecvt_base::ok. If + * no conversion is necessary, returns codecvt_base::noconv. If the + * output has insufficient space, returns codecvt_base::partial. + * Otherwise the reset failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + unshift(state_type& __state, extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { return this->do_unshift(__state, __to,__to_end,__to_next); } + + /** + * @brief Convert from external to internal character set. + * + * Converts input string of extern_type to output string of + * intern_type. This is analogous to mbsrtowcs. It does this by + * calling codecvt::do_in. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If all the + * input is converted, returns codecvt_base::ok. If no conversion is + * necessary, returns codecvt_base::noconv. If the input ends early or + * there is insufficient space in the output, returns codecvt_base::partial. + * Otherwise the conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ + result + in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + return this->do_in(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); + } + + int + encoding() const throw() + { return this->do_encoding(); } + + bool + always_noconv() const throw() + { return this->do_always_noconv(); } + + int + length(state_type& __state, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return this->do_length(__state, __from, __end, __max); } + + int + max_length() const throw() + { return this->do_max_length(); } + + protected: + explicit + __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } + + virtual + ~__codecvt_abstract_base() { } + + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This function is a hook for derived classes to change + * the value returned. @see out for more information. + */ + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const = 0; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const = 0; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const = 0; + + virtual int + do_encoding() const throw() = 0; + + virtual bool + do_always_noconv() const throw() = 0; + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const = 0; + + virtual int + do_max_length() const throw() = 0; + }; + + // 22.2.1.5 Template class codecvt + // NB: Generic, mostly useless implementation. + template + class codecvt + : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { } + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~codecvt() { } + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template + locale::id codecvt<_InternT, _ExternT, _StateT>::id; + + // codecvt required specialization + template<> + class codecvt + : public __codecvt_abstract_base + { + public: + // Types: + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~codecvt(); + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + +#ifdef _GLIBCXX_USE_WCHAR_T + // codecvt required specialization + template<> + class codecvt + : public __codecvt_abstract_base + { + public: + // Types: + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; + + public: + static locale::id id; + + explicit + codecvt(size_t __refs = 0); + + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + + protected: + virtual + ~codecvt(); + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, + const extern_type* __from, const extern_type* __from_end, + const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual + int do_encoding() const throw(); + + virtual + bool do_always_noconv() const throw(); + + virtual + int do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; +#endif //_GLIBCXX_USE_WCHAR_T + + // 22.2.1.6 Template class codecvt_byname + template + class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> + { + public: + explicit + codecvt_byname(const char* __s, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_codecvt); + this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); + } + } + + protected: + virtual + ~codecvt_byname() { } + }; + + // Include host and configuration specific partial specializations + // with additional functionality, if possible. +#ifdef _GLIBCXX_USE_WCHAR_T + #include +#endif + +#endif // _CODECVT_H diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/concept_check.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/concept_check.h new file mode 100644 index 00000000000..80c1439342d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/concept_check.h @@ -0,0 +1,85 @@ +// Concept-checking control -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file concept_check.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CONCEPT_CHECK_H +#define _CONCEPT_CHECK_H 1 + +#pragma GCC system_header + +#include + +// All places in libstdc++-v3 where these are used, or /might/ be used, or +// don't need to be used, or perhaps /should/ be used, are commented with +// "concept requirements" (and maybe some more text). So grep like crazy +// if you're looking for additional places to use these. + +// Concept-checking code is off by default unless users turn it on via +// configure options or editing c++config.h. + +#ifndef _GLIBCXX_CONCEPT_CHECKS + +#define __glibcxx_function_requires(...) +#define __glibcxx_class_requires(_a,_b) +#define __glibcxx_class_requires2(_a,_b,_c) +#define __glibcxx_class_requires3(_a,_b,_c,_d) +#define __glibcxx_class_requires4(_a,_b,_c,_d,_e) + +#else // the checks are on + +#include + +// Note that the obvious and elegant approach of +// +//#define glibcxx_function_requires(C) boost::function_requires< boost::C >() +// +// won't work due to concept templates with more than one parameter, e.g., +// BinaryPredicateConcept. The preprocessor tries to split things up on +// the commas in the template argument list. We can't use an inner pair of +// parenthesis to hide the commas, because "boost::(Temp)" isn't +// a valid instantiation pattern. Thus, we steal a feature from C99. + +#define __glibcxx_function_requires(...) \ + __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >(); +#define __glibcxx_class_requires(_a,_C) \ + _GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C); +#define __glibcxx_class_requires2(_a,_b,_C) \ + _GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C); +#define __glibcxx_class_requires3(_a,_b,_c,_C) \ + _GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C); +#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \ + _GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C); + +#endif // enable/disable + +#endif // _GLIBCXX_CONCEPT_CHECK diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/concurrence.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/concurrence.h new file mode 100644 index 00000000000..c436a1b0806 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/concurrence.h @@ -0,0 +1,95 @@ +// Support for concurrent programing -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CONCURRENCE_H +#define _CONCURRENCE_H 1 + +// GCC's thread abstraction layer +#include "bits/gthr.h" + +#if __GTHREADS + +# ifdef __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_type __gthread_mutex_t +# define __glibcxx_mutex_define_initialized(NAME) \ +__gthread_mutex_t NAME = __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_lock(NAME) \ +__gthread_mutex_lock(&NAME) +# else +// Implies __GTHREAD_MUTEX_INIT_FUNCTION +struct __glibcxx_mutex : public __gthread_mutex_t +{ + __glibcxx_mutex() { __GTHREAD_MUTEX_INIT_FUNCTION(this); } +}; + +# define __glibcxx_mutex_type __glibcxx_mutex +# define __glibcxx_mutex_define_initialized(NAME) \ +__glibcxx_mutex NAME +# define __glibcxx_mutex_lock(NAME) \ +__gthread_mutex_lock(&NAME) +# endif + +# define __glibcxx_mutex_unlock(NAME) __gthread_mutex_unlock(&NAME) + +#else + +# define __glibcxx_mutex_type __gthread_mutex_t +# define __glibcxx_mutex_define_initialized(NAME) __gthread_mutex_t NAME +# define __glibcxx_mutex_lock(NAME) +# define __glibcxx_mutex_unlock(NAME) + +#endif + +namespace __gnu_cxx +{ + typedef __glibcxx_mutex_type mutex_type; + + // Scoped lock idiom. + // Acquire the mutex here with a constructor call, then release with + // the destructor call in accordance with RAII style. + class lock + { + // Externally defined and initialized. + mutex_type& device; + + public: + explicit lock(mutex_type& name) : device(name) + { __glibcxx_mutex_lock(device); } + + ~lock() throw() + { __glibcxx_mutex_unlock(device); } + + private: + lock(const lock&); + lock& operator=(const lock&); + }; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/cpp_type_traits.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/cpp_type_traits.h new file mode 100644 index 00000000000..d4e4ea0410a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/cpp_type_traits.h @@ -0,0 +1,345 @@ +// The -*- C++ -*- type traits classes for internal use in libstdc++ + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file cpp_type_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CPP_TYPE_TRAITS_H +#define _CPP_TYPE_TRAITS_H 1 + +#pragma GCC system_header + +// +// This file provides some compile-time information about various types. +// These representations were designed, on purpose, to be constant-expressions +// and not types as found in . In particular, they +// can be used in control structures and the optimizer hopefully will do +// the obvious thing. +// +// Why integral expressions, and not functions nor types? +// Firstly, these compile-time entities are used as template-arguments +// so function return values won't work: We need compile-time entities. +// We're left with types and constant integral expressions. +// Secondly, from the point of view of ease of use, type-based compile-time +// information is -not- *that* convenient. On has to write lots of +// overloaded functions and to hope that the compiler will select the right +// one. As a net effect, the overall structure isn't very clear at first +// glance. +// Thirdly, partial ordering and overload resolution (of function templates) +// is highly costly in terms of compiler-resource. It is a Good Thing to +// keep these resource consumption as least as possible. +// +// See valarray_array.h for a case use. +// +// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. +// + +// NB: g++ can not compile these if declared within the class +// __is_pod itself. +namespace __gnu_internal +{ + typedef char __one; + typedef char __two[2]; + + template + __one __test_type (int _Tp::*); + template + __two& __test_type (...); +} // namespace __gnu_internal + +namespace std +{ + // Compare for equality of types. + template + struct __are_same + { + enum + { + _M_type = 0 + }; + }; + + template + struct __are_same<_Tp, _Tp> + { + enum + { + _M_type = 1 + }; + }; + + // Define a nested type if some predicate holds. + template + struct __enable_if + { + }; + + template + struct __enable_if<_Tp, true> + { + typedef _Tp _M_type; + }; + + // Holds if the template-argument is a void type. + template + struct __is_void + { + enum + { + _M_type = 0 + }; + }; + + template<> + struct __is_void + { + enum + { + _M_type = 1 + }; + }; + + // + // Integer types + // + template + struct __is_integer + { + enum + { + _M_type = 0 + }; + }; + + // Thirteen specializations (yes there are eleven standard integer + // types; 'long long' and 'unsigned long long' are supported as + // extensions) + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + +# ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; +# endif + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_integer + { + enum + { + _M_type = 1 + }; + }; + + // + // Floating point types + // + template + struct __is_floating + { + enum + { + _M_type = 0 + }; + }; + + // three specializations (float, double and 'long double') + template<> + struct __is_floating + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_floating + { + enum + { + _M_type = 1 + }; + }; + + template<> + struct __is_floating + { + enum + { + _M_type = 1 + }; + }; + + // + // An arithmetic type is an integer type or a floating point type + // + template + struct __is_arithmetic + { + enum + { + _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type + }; + }; + + // + // A fundamental type is `void' or and arithmetic type + // + template + struct __is_fundamental + { + enum + { + _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type + }; + }; + + // + // For the immediate use, the following is a good approximation + // + template + struct __is_pod + { + enum + { + _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0)) + != sizeof(__gnu_internal::__one)) + }; + }; + +} // namespace std + +#endif //_CPP_TYPE_TRAITS_H diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/deque.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/deque.tcc new file mode 100644 index 00000000000..e8e043886ab --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/deque.tcc @@ -0,0 +1,719 @@ +// Deque implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file deque.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _DEQUE_TCC +#define _DEQUE_TCC 1 + +namespace _GLIBCXX_STD +{ + template + deque<_Tp,_Alloc>& + deque<_Tp,_Alloc>:: + operator=(const deque& __x) + { + const size_type __len = size(); + if (&__x != this) + { + if (__len >= __x.size()) + erase(std::copy(__x.begin(), __x.end(), this->_M_impl._M_start), + this->_M_impl._M_finish); + else + { + const_iterator __mid = __x.begin() + difference_type(__len); + std::copy(__x.begin(), __mid, this->_M_impl._M_start); + insert(this->_M_impl._M_finish, __mid, __x.end()); + } + } + return *this; + } + + template + typename deque<_Tp,_Alloc>::iterator + deque<_Tp,_Alloc>:: + insert(iterator position, const value_type& __x) + { + if (position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(__x); + return this->_M_impl._M_start; + } + else if (position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(__x); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } + else + return _M_insert_aux(position, __x); + } + + template + typename deque<_Tp,_Alloc>::iterator + deque<_Tp,_Alloc>:: + erase(iterator __position) + { + iterator __next = __position; + ++__next; + size_type __index = __position - this->_M_impl._M_start; + if (__index < (size() >> 1)) + { + std::copy_backward(this->_M_impl._M_start, __position, __next); + pop_front(); + } + else + { + std::copy(__next, this->_M_impl._M_finish, __position); + pop_back(); + } + return this->_M_impl._M_start + __index; + } + + template + typename deque<_Tp,_Alloc>::iterator + deque<_Tp,_Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == this->_M_impl._M_start && __last == this->_M_impl._M_finish) + { + clear(); + return this->_M_impl._M_finish; + } + else + { + const difference_type __n = __last - __first; + const difference_type __elems_before = __first - this->_M_impl._M_start; + if (static_cast(__elems_before) < (size() - __n) / 2) + { + std::copy_backward(this->_M_impl._M_start, __first, __last); + iterator __new_start = this->_M_impl._M_start + __n; + std::_Destroy(this->_M_impl._M_start, __new_start); + _M_destroy_nodes(this->_M_impl._M_start._M_node, __new_start._M_node); + this->_M_impl._M_start = __new_start; + } + else + { + std::copy(__last, this->_M_impl._M_finish, __first); + iterator __new_finish = this->_M_impl._M_finish - __n; + std::_Destroy(__new_finish, this->_M_impl._M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, + this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish = __new_finish; + } + return this->_M_impl._M_start + __elems_before; + } + } + + template + void + deque<_Tp,_Alloc>:: + clear() + { + for (_Map_pointer __node = this->_M_impl._M_start._M_node + 1; + __node < this->_M_impl._M_finish._M_node; + ++__node) + { + std::_Destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); + } + + if (this->_M_impl._M_start._M_node != this->_M_impl._M_finish._M_node) + { + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_start._M_last); + std::_Destroy(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur); + _M_deallocate_node(this->_M_impl._M_finish._M_first); + } + else + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_finish._M_cur); + + this->_M_impl._M_finish = this->_M_impl._M_start; + } + + template + template + void + deque<_Tp,_Alloc> + ::_M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void + deque<_Tp,_Alloc>:: + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) + { + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_fill(__new_start, this->_M_impl._M_start, __x); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_fill(this->_M_impl._M_finish, __new_finish, __x); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else + _M_insert_aux(__pos, __n, __x); + } + + template + void + deque<_Tp,_Alloc>:: + _M_fill_initialize(const value_type& __value) + { + _Map_pointer __cur; + try + { + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; + ++__cur) + std::uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + std::uninitialized_fill(this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, + __value); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur)); + __throw_exception_again; + } + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + this->_M_initialize_map(0); + try + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + catch(...) + { + clear(); + __throw_exception_again; + } + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + this->_M_initialize_map(__n); + + _Map_pointer __cur_node; + try + { + for (__cur_node = this->_M_impl._M_start._M_node; + __cur_node < this->_M_impl._M_finish._M_node; + ++__cur_node) + { + _ForwardIterator __mid = __first; + std::advance(__mid, _S_buffer_size()); + std::uninitialized_copy(__first, __mid, *__cur_node); + __first = __mid; + } + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish._M_first); + } + catch(...) + { + std::_Destroy(this->_M_impl._M_start, iterator(*__cur_node, __cur_node)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. + template + void + deque<_Tp,_Alloc>:: + _M_push_back_aux(const value_type& __t) + { + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); + try + { + std::_Construct(this->_M_impl._M_finish._M_cur, __t_copy); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; + } + catch(...) + { + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. + template + void + deque<_Tp,_Alloc>:: + _M_push_front_aux(const value_type& __t) + { + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); + try + { + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + std::_Construct(this->_M_impl._M_start._M_cur, __t_copy); + } + catch(...) + { + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); + __throw_exception_again; + } + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. + template + void deque<_Tp,_Alloc>:: + _M_pop_back_aux() + { + _M_deallocate_node(this->_M_impl._M_finish._M_first); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; + std::_Destroy(this->_M_impl._M_finish._M_cur); + } + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. Note that + // if the deque has at least one element (a precondition for this member + // function), and if _M_impl._M_start._M_cur == _M_impl._M_start._M_last, then the deque + // must have at least two nodes. + template + void deque<_Tp,_Alloc>:: + _M_pop_front_aux() + { + std::_Destroy(this->_M_impl._M_start._M_cur); + _M_deallocate_node(this->_M_impl._M_start._M_first); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_insert_aux(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) + { std::copy(__first, __last, std::inserter(*this, __pos)); } + + template + template + void + deque<_Tp,_Alloc>:: + _M_range_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + size_type __n = std::distance(__first, __last); + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_copy(__first, __last, __new_start); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else + _M_insert_aux(__pos, __first, __last, __n); + } + + template + typename deque<_Tp, _Alloc>::iterator + deque<_Tp,_Alloc>:: + _M_insert_aux(iterator __pos, const value_type& __x) + { + difference_type __index = __pos - this->_M_impl._M_start; + value_type __x_copy = __x; // XXX copy + if (static_cast(__index) < size() / 2) + { + push_front(front()); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::copy(__front2, __pos1, __front1); + } + else + { + push_back(back()); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + std::copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; + } + + template + void + deque<_Tp,_Alloc>:: + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) + { + const difference_type __elems_before = __pos - this->_M_impl._M_start; + size_type __length = this->size(); + value_type __x_copy = __x; + if (__elems_before < difference_type(__length / 2)) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, + __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); + } + else + { + std::__uninitialized_copy_fill(this->_M_impl._M_start, __pos, + __new_start, + this->_M_impl._M_start, __x_copy); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_impl._M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); + } + else + { + std::__uninitialized_fill_copy(this->_M_impl._M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + + template + template + void + deque<_Tp,_Alloc>:: + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n) + { + const difference_type __elemsbefore = __pos - this->_M_impl._M_start; + size_type __length = size(); + if (static_cast(__elemsbefore) < __length / 2) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elemsbefore; + try + { + if (__elemsbefore >= difference_type(__n)) + { + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, + __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_copy_copy(this->_M_impl._M_start, __pos, + __first, __mid, __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__mid, __last, __old_start); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = this->_M_impl._M_finish - __elemsafter; + try + { + if (__elemsafter > difference_type(__n)) + { + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_copy(__mid, __last, __pos, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy(__first, __mid, __pos); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + } + + template + void + deque<_Tp,_Alloc>:: + _M_new_elements_at_front(size_type __new_elems) + { + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_front(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); + __throw_exception_again; + } + } + + template + void + deque<_Tp,_Alloc>:: + _M_new_elements_at_back(size_type __new_elems) + { + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_back(__new_nodes); + size_type __i; + try + { + for (__i = 1; __i <= __new_nodes; ++__i) + *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); + } + catch(...) + { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); + __throw_exception_again; + } + } + + template + void + deque<_Tp,_Alloc>:: + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) + { + size_type __old_num_nodes + = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; + size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (this->_M_impl._M_map_size > 2 * __new_num_nodes) + { + __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size + - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < this->_M_impl._M_start._M_node) + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + else + std::copy_backward(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } + else + { + size_type __new_map_size = this->_M_impl._M_map_size + + std::max(this->_M_impl._M_map_size, + __nodes_to_add) + 2; + + _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + + this->_M_impl._M_map = __new_map; + this->_M_impl._M_map_size = __new_map_size; + } + + this->_M_impl._M_start._M_set_node(__new_nstart); + this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); + } +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/fstream.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/fstream.tcc new file mode 100644 index 00000000000..25a4d48cb72 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/fstream.tcc @@ -0,0 +1,877 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +#ifndef _FSTREAM_TCC +#define _FSTREAM_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + void + basic_filebuf<_CharT, _Traits>:: + _M_allocate_internal_buffer() + { + // Allocate internal buffer only if one doesn't already exist + // (either allocated or provided by the user via setbuf). + if (!_M_buf_allocated && !this->_M_buf) + { + this->_M_buf = new char_type[this->_M_buf_size]; + _M_buf_allocated = true; + } + } + + template + void + basic_filebuf<_CharT, _Traits>:: + _M_destroy_internal_buffer() throw() + { + if (_M_buf_allocated) + { + delete [] this->_M_buf; + this->_M_buf = NULL; + _M_buf_allocated = false; + } + delete [] _M_ext_buf; + _M_ext_buf = NULL; + _M_ext_buf_size = 0; + _M_ext_next = NULL; + _M_ext_end = NULL; + } + + template + basic_filebuf<_CharT, _Traits>:: + basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock), + _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(), + _M_state_last(), _M_buf(NULL), _M_buf_size(BUFSIZ), + _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(), + _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), + _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0), + _M_ext_end(0) + { + if (has_facet<__codecvt_type>(this->_M_buf_locale)) + _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale); + } + + template + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + open(const char* __s, ios_base::openmode __mode) + { + __filebuf_type *__ret = NULL; + if (!this->is_open()) + { + _M_file.open(__s, __mode); + if (this->is_open()) + { + _M_allocate_internal_buffer(); + this->_M_mode = __mode; + + // Setup initial buffer to 'uncommitted' mode. + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + + // Reset to initial state. + _M_state_last = _M_state_cur = _M_state_beg; + + // 27.8.1.3,4 + if ((__mode & ios_base::ate) + && this->seekoff(0, ios_base::end, __mode) + == pos_type(off_type(-1))) + this->close(); + else + __ret = this; + } + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + basic_filebuf<_CharT, _Traits>:: + close() throw() + { + __filebuf_type* __ret = NULL; + if (this->is_open()) + { + bool __testfail = false; + try + { + if (!_M_terminate_output()) + __testfail = true; + } + catch(...) + { __testfail = true; } + + // NB: Do this here so that re-opened filebufs will be cool... + this->_M_mode = ios_base::openmode(0); + this->_M_pback_init = false; + _M_destroy_internal_buffer(); + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + + if (!_M_file.close()) + __testfail = true; + + if (!__testfail) + __ret = this; + } + return __ret; + } + + template + streamsize + basic_filebuf<_CharT, _Traits>:: + showmanyc() + { + streamsize __ret = -1; + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && this->is_open()) + { + // For a stateful encoding (-1) the pending sequence might be just + // shift and unshift prefixes with no actual character. + __ret = this->egptr() - this->gptr(); + if (__check_facet(_M_codecvt).encoding() >= 0) + __ret += _M_file.showmanyc() / _M_codecvt->max_length(); + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Check for pback madness, and if so swich back to the + // normal buffers and jet outta here before expensive + // fileops happen... + _M_destroy_pback(); + + if (this->gptr() < this->egptr()) + return traits_type::to_int_type(*this->gptr()); + + // Get and convert input sequence. + const size_t __buflen = this->_M_buf_size > 1 + ? this->_M_buf_size - 1 : 1; + + // Will be set to true if ::read() returns 0 indicating EOF. + bool __got_eof = false; + // Number of internal characters produced. + streamsize __ilen = 0; + codecvt_base::result __r = codecvt_base::ok; + if (__check_facet(_M_codecvt).always_noconv()) + { + __ilen = _M_file.xsgetn(reinterpret_cast(this->eback()), + __buflen); + if (__ilen == 0) + __got_eof = true; + } + else + { + // Worst-case number of external bytes. + // XXX Not done encoding() == -1. + const int __enc = _M_codecvt->encoding(); + streamsize __blen; // Minimum buffer size. + streamsize __rlen; // Number of chars to read. + if (__enc > 0) + __blen = __rlen = __buflen * __enc; + else + { + __blen = __buflen + _M_codecvt->max_length() - 1; + __rlen = __buflen; + } + const streamsize __remainder = _M_ext_end - _M_ext_next; + __rlen = __rlen > __remainder ? __rlen - __remainder : 0; + + // An imbue in 'read' mode implies first converting the external + // chars already present. + if (_M_reading && this->egptr() == this->eback() && __remainder) + __rlen = 0; + + // Allocate buffer if necessary and move unconverted + // bytes to front. + if (_M_ext_buf_size < __blen) + { + char* __buf = new char[__blen]; + if (__remainder) + std::memcpy(__buf, _M_ext_next, __remainder); + + delete [] _M_ext_buf; + _M_ext_buf = __buf; + _M_ext_buf_size = __blen; + } + else if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_state_last = _M_state_cur; + + do + { + if (__rlen > 0) + { + // Sanity check! + // This may fail if the return value of + // codecvt::max_length() is bogus. + if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) + { + __throw_ios_failure(__N("basic_filebuf::underflow " + "codecvt::max_length() " + "is not valid")); + } + streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); + if (__elen == 0) + __got_eof = true; + else if (__elen == -1) + break; + _M_ext_end += __elen; + } + + char_type* __iend; + __r = _M_codecvt->in(_M_state_cur, _M_ext_next, + _M_ext_end, _M_ext_next, this->eback(), + this->eback() + __buflen, __iend); + if (__r == codecvt_base::noconv) + { + size_t __avail = _M_ext_end - _M_ext_buf; + __ilen = std::min(__avail, __buflen); + traits_type::copy(this->eback(), + reinterpret_cast(_M_ext_buf), __ilen); + _M_ext_next = _M_ext_buf + __ilen; + } + else + __ilen = __iend - this->eback(); + + // _M_codecvt->in may return error while __ilen > 0: this is + // ok, and actually occurs in case of mixed encodings (e.g., + // XML files). + if (__r == codecvt_base::error) + break; + + __rlen = 1; + } + while (__ilen == 0 && !__got_eof); + } + + if (__ilen > 0) + { + _M_set_buffer(__ilen); + _M_reading = true; + __ret = traits_type::to_int_type(*this->gptr()); + } + else if (__got_eof) + { + // If the actual end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without an + // intervening seek. + _M_set_buffer(-1); + _M_reading = false; + // However, reaching it while looping on partial means that + // the file has got an incomplete character. + if (__r == codecvt_base::partial) + __throw_ios_failure(__N("basic_filebuf::underflow " + "incomplete character in file")); + } + else if (__r == codecvt_base::error) + __throw_ios_failure(__N("basic_filebuf::underflow " + "invalid byte sequence in file")); + else + __throw_ios_failure(__N("basic_filebuf::underflow " + "error reading the file")); + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + pbackfail(int_type __i) + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Remember whether the pback buffer is active, otherwise below + // we may try to store in it a second char (libstdc++/9761). + const bool __testpb = this->_M_pback_init; + const bool __testeof = traits_type::eq_int_type(__i, __ret); + int_type __tmp; + if (this->eback() < this->gptr()) + { + this->gbump(-1); + __tmp = traits_type::to_int_type(*this->gptr()); + } + else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1))) + { + __tmp = this->underflow(); + if (traits_type::eq_int_type(__tmp, __ret)) + return __ret; + } + else + { + // At the beginning of the buffer, need to make a + // putback position available. But the seek may fail + // (f.i., at the beginning of a file, see + // libstdc++/9439) and in that case we return + // traits_type::eof(). + return __ret; + } + + // Try to put back __i into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && traits_type::eq_int_type(__i, __tmp)) + __ret = __i; + else if (__testeof) + __ret = traits_type::not_eof(__i); + else if (!__testpb) + { + _M_create_pback(); + _M_reading = true; + *this->gptr() = traits_type::to_char_type(__i); + __ret = __i; + } + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + overflow(int_type __c) + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + const bool __testout = this->_M_mode & ios_base::out; + if (__testout && !_M_reading) + { + if (this->pbase() < this->pptr()) + { + // If appropriate, append the overflow char. + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + + // Convert pending sequence to external representation, + // and output. + if (_M_convert_to_external(this->pbase(), + this->pptr() - this->pbase())) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else if (this->_M_buf_size > 1) + { + // Overflow in 'uncommitted' mode: set _M_writing, set + // the buffer to the initial 'write' mode, and put __c + // into the buffer. + _M_set_buffer(0); + _M_writing = true; + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + __ret = traits_type::not_eof(__c); + } + else + { + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (__testeof || _M_convert_to_external(&__conv, 1)) + { + _M_writing = true; + __ret = traits_type::not_eof(__c); + } + } + } + return __ret; + } + + template + bool + basic_filebuf<_CharT, _Traits>:: + _M_convert_to_external(_CharT* __ibuf, streamsize __ilen) + { + // Sizes of external and pending output. + streamsize __elen; + streamsize __plen; + if (__check_facet(_M_codecvt).always_noconv()) + { + __elen = _M_file.xsputn(reinterpret_cast(__ibuf), __ilen); + __plen = __ilen; + } + else + { + // Worst-case number of external bytes needed. + // XXX Not done encoding() == -1. + streamsize __blen = __ilen * _M_codecvt->max_length(); + char* __buf = static_cast(__builtin_alloca(__blen)); + + char* __bend; + const char_type* __iend; + codecvt_base::result __r; + __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, + __iend, __buf, __buf + __blen, __bend); + + if (__r == codecvt_base::ok || __r == codecvt_base::partial) + __blen = __bend - __buf; + else if (__r == codecvt_base::noconv) + { + // Same as the always_noconv case above. + __buf = reinterpret_cast(__ibuf); + __blen = __ilen; + } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + + __elen = _M_file.xsputn(__buf, __blen); + __plen = __blen; + + // Try once more for partial conversions. + if (__r == codecvt_base::partial && __elen == __plen) + { + const char_type* __iresume = __iend; + streamsize __rlen = this->pptr() - __iend; + __r = _M_codecvt->out(_M_state_cur, __iresume, + __iresume + __rlen, __iend, __buf, + __buf + __blen, __bend); + if (__r != codecvt_base::error) + { + __rlen = __bend - __buf; + __elen = _M_file.xsputn(__buf, __rlen); + __plen = __rlen; + } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + } + } + return __elen == __plen; + } + + template + streamsize + basic_filebuf<_CharT, _Traits>:: + xsgetn(_CharT* __s, streamsize __n) + { + // Clear out pback buffer before going on to the real deal... + streamsize __ret = 0; + if (this->_M_pback_init) + { + if (__n > 0 && this->gptr() == this->eback()) + { + *__s++ = *this->gptr(); + this->gbump(1); + __ret = 1; + --__n; + } + _M_destroy_pback(); + } + + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n > __buflen we read directly instead of using the + // buffer repeatedly. + const bool __testin = this->_M_mode & ios_base::in; + const streamsize __buflen = this->_M_buf_size > 1 ? this->_M_buf_size - 1 + : 1; + if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() + && __testin && !_M_writing) + { + // First, copy the chars already present in the buffer. + const streamsize __avail = this->egptr() - this->gptr(); + if (__avail != 0) + { + if (__avail == 1) + *__s = *this->gptr(); + else + traits_type::copy(__s, this->gptr(), __avail); + __s += __avail; + this->gbump(__avail); + __ret += __avail; + __n -= __avail; + } + + const streamsize __len = _M_file.xsgetn(reinterpret_cast(__s), + __n); + if (__len == -1) + __throw_ios_failure(__N("basic_filebuf::xsgetn " + "error reading the file")); + __ret += __len; + if (__len == __n) + { + _M_set_buffer(0); + _M_reading = true; + } + else if (__len == 0) + { + // If end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without + // an intervening seek. + _M_set_buffer(-1); + _M_reading = false; + } + } + else + __ret += __streambuf_type::xsgetn(__s, __n); + + return __ret; + } + + template + streamsize + basic_filebuf<_CharT, _Traits>:: + xsputn(const _CharT* __s, streamsize __n) + { + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + streamsize __ret = 0; + const bool __testout = this->_M_mode & ios_base::out; + if (__check_facet(_M_codecvt).always_noconv() + && __testout && !_M_reading) + { + // Measurement would reveal the best choice. + const streamsize __chunk = 1ul << 10; + streamsize __bufavail = this->epptr() - this->pptr(); + + // Don't mistake 'uncommitted' mode buffered with unbuffered. + if (!_M_writing && this->_M_buf_size > 1) + __bufavail = this->_M_buf_size - 1; + + const streamsize __limit = std::min(__chunk, __bufavail); + if (__n >= __limit) + { + const streamsize __buffill = this->pptr() - this->pbase(); + const char* __buf = reinterpret_cast(this->pbase()); + __ret = _M_file.xsputn_2(__buf, __buffill, + reinterpret_cast(__s), + __n); + if (__ret == __buffill + __n) + { + _M_set_buffer(0); + _M_writing = true; + } + if (__ret > __buffill) + __ret -= __buffill; + else + __ret = 0; + } + else + __ret = __streambuf_type::xsputn(__s, __n); + } + else + __ret = __streambuf_type::xsputn(__s, __n); + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::__streambuf_type* + basic_filebuf<_CharT, _Traits>:: + setbuf(char_type* __s, streamsize __n) + { + if (!this->is_open()) + if (__s == 0 && __n == 0) + this->_M_buf_size = 1; + else if (__s && __n > 0) + { + // This is implementation-defined behavior, and assumes that + // an external char_type array of length __n exists and has + // been pre-allocated. If this is not the case, things will + // quickly blow up. When __n > 1, __n - 1 positions will be + // used for the get area, __n - 1 for the put area and 1 + // position to host the overflow char of a full put area. + // When __n == 1, 1 position will be used for the get area + // and 0 for the put area, as in the unbuffered case above. + this->_M_buf = __s; + this->_M_buf_size = __n; + } + return this; + } + + + // According to 27.8.1.4 p11 - 13, seekoff should ignore the last + // argument (of type openmode). + template + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) + { + int __width = 0; + if (_M_codecvt) + __width = _M_codecvt->encoding(); + if (__width < 0) + __width = 0; + + pos_type __ret = pos_type(off_type(-1)); + const bool __testfail = __off != 0 && __width <= 0; + if (this->is_open() && !__testfail) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + + // Correct state at destination. Note that this is the correct + // state for the current position during output, because + // codecvt::unshift() returns the state to the initial state. + // This is also the correct state at the end of the file because + // an unshift sequence should have been written at the end. + __state_type __state = _M_state_beg; + off_type __computed_off = __off * __width; + if (_M_reading && __way == ios_base::cur) + { + if (_M_codecvt->always_noconv()) + __computed_off += this->gptr() - this->egptr(); + else + { + // Calculate offset from _M_ext_buf that corresponds + // to gptr(). Note: uses _M_state_last, which + // corresponds to eback(). + const int __gptr_off = + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + __computed_off += _M_ext_buf + __gptr_off - _M_ext_end; + + // _M_state_last is modified by codecvt::length() so + // it now corresponds to gptr(). + __state = _M_state_last; + } + } + __ret = _M_seek(__computed_off, __way, __state); + } + return __ret; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 171. Strange seekpos() semantics due to joint position + // According to the resolution of DR 171, seekpos should ignore the last + // argument (of type openmode). + template + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + seekpos(pos_type __pos, ios_base::openmode) + { + pos_type __ret = pos_type(off_type(-1)); + if (this->is_open()) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state()); + } + return __ret; + } + + template + typename basic_filebuf<_CharT, _Traits>::pos_type + basic_filebuf<_CharT, _Traits>:: + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state) + { + pos_type __ret = pos_type(off_type(-1)); + if (_M_terminate_output()) + { + // Returns pos_type(off_type(-1)) in case of failure. + __ret = pos_type(_M_file.seekoff(__off, __way)); + _M_reading = false; + _M_writing = false; + _M_ext_next = _M_ext_end = _M_ext_buf; + _M_set_buffer(-1); + _M_state_cur = __state; + __ret.state(_M_state_cur); + } + return __ret; + } + + template + bool + basic_filebuf<_CharT, _Traits>:: + _M_terminate_output() + { + // Part one: update the output sequence. + bool __testvalid = true; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + + // Part two: output unshift sequence. + if (_M_writing && !__check_facet(_M_codecvt).always_noconv() + && __testvalid) + { + // Note: this value is arbitrary, since there is no way to + // get the length of the unshift sequence from codecvt, + // without calling unshift. + const size_t __blen = 128; + char __buf[__blen]; + codecvt_base::result __r; + streamsize __ilen = 0; + + do + { + char* __next; + __r = _M_codecvt->unshift(_M_state_cur, __buf, + __buf + __blen, __next); + if (__r == codecvt_base::error) + __testvalid = false; + else if (__r == codecvt_base::ok || + __r == codecvt_base::partial) + { + __ilen = __next - __buf; + if (__ilen > 0) + { + const streamsize __elen = _M_file.xsputn(__buf, __ilen); + if (__elen != __ilen) + __testvalid = false; + } + } + } + while (__r == codecvt_base::partial && __ilen > 0 && __testvalid); + + if (__testvalid) + { + // This second call to overflow() is required by the standard, + // but it's not clear why it's needed, since the output buffer + // should be empty by this point (it should have been emptied + // in the first call to overflow()). + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + } + return __testvalid; + } + + template + int + basic_filebuf<_CharT, _Traits>:: + sync() + { + // Make sure that the internal buffer resyncs its idea of + // the file position with the external file. + int __ret = 0; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __ret = -1; + } + return __ret; + } + + template + void + basic_filebuf<_CharT, _Traits>:: + imbue(const locale& __loc) + { + bool __testvalid = true; + + const __codecvt_type* _M_codecvt_tmp = 0; + if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) + _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc); + + if (this->is_open()) + { + // encoding() == -1 is ok only at the beginning. + if ((_M_reading || _M_writing) + && __check_facet(_M_codecvt).encoding() == -1) + __testvalid = false; + else + { + if (_M_reading) + { + if (__check_facet(_M_codecvt).always_noconv()) + { + if (_M_codecvt_tmp + && !__check_facet(_M_codecvt_tmp).always_noconv()) + __testvalid = this->seekoff(0, ios_base::cur, this->_M_mode) + != pos_type(off_type(-1)); + } + else + { + // External position corresponding to gptr(). + _M_ext_next = _M_ext_buf + + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + const streamsize __remainder = _M_ext_end - _M_ext_next; + if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + } + } + else if (_M_writing && (__testvalid = _M_terminate_output())) + _M_set_buffer(-1); + } + } + + if (__testvalid) + _M_codecvt = _M_codecvt_tmp; + else + _M_codecvt = 0; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_filebuf; + extern template class basic_ifstream; + extern template class basic_ofstream; + extern template class basic_fstream; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_filebuf; + extern template class basic_ifstream; + extern template class basic_ofstream; + extern template class basic_fstream; +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/functexcept.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/functexcept.h new file mode 100644 index 00000000000..8b1d16c8e59 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/functexcept.h @@ -0,0 +1,85 @@ +// Function-Based Exception Support -*- C++ -*- + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#include + +namespace std +{ + // Helper for exception objects in + void + __throw_bad_exception(void); + + // Helper for exception objects in + void + __throw_bad_alloc(void); + + // Helper for exception objects in + void + __throw_bad_cast(void); + + void + __throw_bad_typeid(void); + + // Helpers for exception objects in + void + __throw_logic_error(const char* __s); + + void + __throw_domain_error(const char* __s); + + void + __throw_invalid_argument(const char* __s); + + void + __throw_length_error(const char* __s); + + void + __throw_out_of_range(const char* __s); + + void + __throw_runtime_error(const char* __s); + + void + __throw_range_error(const char* __s); + + void + __throw_overflow_error(const char* __s); + + void + __throw_underflow_error(const char* __s); + + // Helpers for exception objects in basic_ios + void + __throw_ios_failure(const char* __s); +} // namespace std + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice.h new file mode 100644 index 00000000000..78f8a67146b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice.h @@ -0,0 +1,165 @@ +// The template and inlines for the -*- C++ -*- gslice class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file gslice.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GSLICE_H +#define _GSLICE_H 1 + +#pragma GCC system_header + +namespace std { + + /** + * @brief Class defining multi-dimensional subset of an array. + * + * The slice class represents a multi-dimensional subset of an array, + * specified by three parameter sets: start offset, size array, and stride + * array. The start offset is the index of the first element of the array + * that is part of the subset. The size and stride array describe each + * dimension of the slice. Size is the number of elements in that + * dimension, and stride is the distance in the array between successive + * elements in that dimension. Each dimension's size and stride is taken + * to begin at an array element described by the previous dimension. The + * size array and stride array must be the same size. + * + * For example, if you have offset==3, stride[0]==11, size[1]==3, + * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], + * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], + * slice[1,2]==array[20]. + */ + class gslice + { + public: + /// Construct an empty slice. + gslice (); + + /** + * @brief Construct a slice. + * + * Constructs a slice with as many dimensions as the length of the @a l + * and @a s arrays. + * + * @param o Offset in array of first element. + * @param l Array of dimension lengths. + * @param s Array of dimension strides between array elements. + */ + gslice(size_t, const valarray&, const valarray&); + + // XXX: the IS says the copy-ctor and copy-assignment operators are + // synthetized by the compiler but they are just unsuitable + // for a ref-counted semantic + /// Copy constructor. + gslice(const gslice&); + + /// Destructor. + ~gslice(); + + // XXX: See the note above. + /// Assignment operator. + gslice& operator=(const gslice&); + + /// Return array offset of first slice element. + size_t start() const; + + /// Return array of sizes of slice dimensions. + valarray size() const; + + /// Return array of array strides for each dimension. + valarray stride() const; + + private: + struct _Indexer { + size_t _M_count; + size_t _M_start; + valarray _M_size; + valarray _M_stride; + valarray _M_index; // Linear array of referenced indices + _Indexer(size_t, const valarray&, + const valarray&); + void _M_increment_use() { ++_M_count; } + size_t _M_decrement_use() { return --_M_count; } + }; + + _Indexer* _M_index; + + template friend class valarray; + }; + + inline size_t + gslice::start () const + { return _M_index ? _M_index->_M_start : 0; } + + inline valarray + gslice::size () const + { return _M_index ? _M_index->_M_size : valarray(); } + + inline valarray + gslice::stride () const + { return _M_index ? _M_index->_M_stride : valarray(); } + + inline gslice::gslice () : _M_index(0) {} + + inline + gslice::gslice(size_t __o, const valarray& __l, + const valarray& __s) + : _M_index(new gslice::_Indexer(__o, __l, __s)) {} + + inline + gslice::gslice(const gslice& __g) : _M_index(__g._M_index) + { if (_M_index) _M_index->_M_increment_use(); } + + inline + gslice::~gslice() + { if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } + + inline gslice& + gslice::operator= (const gslice& __g) + { + if (__g._M_index) __g._M_index->_M_increment_use(); + if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; + _M_index = __g._M_index; + return *this; + } + + +} // std:: + + +#endif /* _GSLICE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice_array.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice_array.h new file mode 100644 index 00000000000..7e2e6848e88 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/gslice_array.h @@ -0,0 +1,220 @@ +// The template and inlines for the -*- C++ -*- gslice_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file gslice_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GSLICE_ARRAY_H +#define _GSLICE_ARRAY_H 1 + +#pragma GCC system_header + +namespace std { + + /** + * @brief Reference to multi-dimensional subset of an array. + * + * A gslice_array is a reference to the actual elements of an array + * specified by a gslice. The way to get a gslice_array is to call + * operator[](gslice) on a valarray. The returned gslice_array then + * permits carrying operations out on the referenced subset of elements in + * the original valarray. For example, operator+=(valarray) will add + * values to the subset of elements in the underlying valarray this + * gslice_array refers to. + * + * @param Tp Element type. + */ + template + class gslice_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + gslice_array(const gslice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + gslice_array& operator=(const gslice_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp&) const; + + template + void operator=(const _Expr<_Dom,_Tp>&) const; + template + void operator*=(const _Expr<_Dom,_Tp>&) const; + template + void operator/=(const _Expr<_Dom,_Tp>&) const; + template + void operator%=(const _Expr<_Dom,_Tp>&) const; + template + void operator+=(const _Expr<_Dom,_Tp>&) const; + template + void operator-=(const _Expr<_Dom,_Tp>&) const; + template + void operator^=(const _Expr<_Dom,_Tp>&) const; + template + void operator&=(const _Expr<_Dom,_Tp>&) const; + template + void operator|=(const _Expr<_Dom,_Tp>&) const; + template + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + _Array<_Tp> _M_array; + const valarray& _M_index; + + friend class valarray<_Tp>; + + gslice_array(_Array<_Tp>, const valarray&); + + // not implemented + gslice_array(); + }; + + template + inline + gslice_array<_Tp>::gslice_array(_Array<_Tp> __a, + const valarray& __i) + : _M_array(__a), _M_index(__i) {} + + + template + inline + gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a) + : _M_array(__a._M_array), _M_index(__a._M_index) {} + + + template + inline gslice_array<_Tp>& + gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a) + { + std::__valarray_copy(_Array<_Tp>(__a._M_array), + _Array(__a._M_index), _M_index.size(), + _M_array, _Array(_M_index)); + return *this; + } + + template + inline void + gslice_array<_Tp>::operator=(const _Tp& __t) const + { + std::__valarray_fill(_M_array, _Array(_M_index), + _M_index.size(), __t); + } + + template + inline void + gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { + std::__valarray_copy(_Array<_Tp>(__v), __v.size(), + _M_array, _Array(_M_index)); + } + + template + template + inline void + gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const + { + std::__valarray_copy (__e, _M_index.size(), _M_array, + _Array(_M_index)); + } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template \ + inline void \ + gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _Array(_M_index), \ + _Array<_Tp>(__v), __v.size()); \ + } \ + \ + template \ + template \ + inline void \ + gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _Array(_M_index), __e,\ + _M_index.size()); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _GSLICE_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/indirect_array.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/indirect_array.h new file mode 100644 index 00000000000..912f522450d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/indirect_array.h @@ -0,0 +1,212 @@ +// The template and inlines for the -*- C++ -*- indirect_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file indirect_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _INDIRECT_ARRAY_H +#define _INDIRECT_ARRAY_H 1 + +#pragma GCC system_header + +namespace std +{ + /** + * @brief Reference to arbitrary subset of an array. + * + * An indirect_array is a reference to the actual elements of an array + * specified by an ordered array of indices. The way to get an indirect_array is to + * call operator[](valarray) on a valarray. The returned + * indirect_array then permits carrying operations out on the referenced + * subset of elements in the original valarray. + * + * For example, if an indirect_array is obtained using the array (4,2,0) as + * an argument, and then assigned to an array containing (1,2,3), then the + * underlying array will have array[0]==3, array[2]==2, and array[4]==1. + * + * @param Tp Element type. + */ + template + class indirect_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(const indirect_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + indirect_array& operator=(const indirect_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator= (const _Tp&) const; + // ~indirect_array(); + + template + void operator=(const _Expr<_Dom, _Tp>&) const; + template + void operator*=(const _Expr<_Dom, _Tp>&) const; + template + void operator/=(const _Expr<_Dom, _Tp>&) const; + template + void operator%=(const _Expr<_Dom, _Tp>&) const; + template + void operator+=(const _Expr<_Dom, _Tp>&) const; + template + void operator-=(const _Expr<_Dom, _Tp>&) const; + template + void operator^=(const _Expr<_Dom, _Tp>&) const; + template + void operator&=(const _Expr<_Dom, _Tp>&) const; + template + void operator|=(const _Expr<_Dom, _Tp>&) const; + template + void operator<<=(const _Expr<_Dom, _Tp>&) const; + template + void operator>>=(const _Expr<_Dom, _Tp>&) const; + + private: + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(_Array<_Tp>, size_t, _Array); + + friend class valarray<_Tp>; + friend class gslice_array<_Tp>; + + const size_t _M_sz; + const _Array _M_index; + const _Array<_Tp> _M_array; + + // not implemented + indirect_array(); + }; + + template + inline + indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) + : _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {} + + template + inline + indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s, + _Array __i) + : _M_sz(__s), _M_index(__i), _M_array(__a) {} + + template + inline indirect_array<_Tp>& + indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, _M_index); + return *this; + } + + + template + inline void + indirect_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_index, _M_sz, __t); } + + template + inline void + indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); } + + template + template + inline void + indirect_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const + { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template \ + inline void \ + indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \ + } \ + \ + template \ + template \ + inline void \ + indirect_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_index, __e, _M_sz); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _INDIRECT_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/ios_base.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/ios_base.h new file mode 100644 index 00000000000..08c952d6ba5 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/ios_base.h @@ -0,0 +1,969 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +/** @file ios_base.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _IOS_BASE_H +#define _IOS_BASE_H 1 + +#pragma GCC system_header + +#include +#include +#include + +namespace std +{ + // The following definitions of bitmask types are enums, not ints, + // as permitted (but not required) in the standard, in order to provide + // better type safety in iostream calls. A side effect is that + // expressions involving them are no longer compile-time constants. + enum _Ios_Fmtflags + { + _S_boolalpha = 1L << 0, + _S_dec = 1L << 1, + _S_fixed = 1L << 2, + _S_hex = 1L << 3, + _S_internal = 1L << 4, + _S_left = 1L << 5, + _S_oct = 1L << 6, + _S_right = 1L << 7, + _S_scientific = 1L << 8, + _S_showbase = 1L << 9, + _S_showpoint = 1L << 10, + _S_showpos = 1L << 11, + _S_skipws = 1L << 12, + _S_unitbuf = 1L << 13, + _S_uppercase = 1L << 14, + _S_adjustfield = _S_left | _S_right | _S_internal, + _S_basefield = _S_dec | _S_oct | _S_hex, + _S_floatfield = _S_scientific | _S_fixed, + _S_ios_fmtflags_end = 1L << 16 + }; + + inline _Ios_Fmtflags + operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Fmtflags + operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Fmtflags + operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) + { return _Ios_Fmtflags(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Fmtflags& + operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a | __b; } + + inline _Ios_Fmtflags& + operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a & __b; } + + inline _Ios_Fmtflags& + operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) + { return __a = __a ^ __b; } + + inline _Ios_Fmtflags + operator~(_Ios_Fmtflags __a) + { return _Ios_Fmtflags(~static_cast(__a)); } + + + enum _Ios_Openmode + { + _S_app = 1L << 0, + _S_ate = 1L << 1, + _S_bin = 1L << 2, + _S_in = 1L << 3, + _S_out = 1L << 4, + _S_trunc = 1L << 5, + _S_ios_openmode_end = 1L << 16 + }; + + inline _Ios_Openmode + operator&(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Openmode + operator|(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Openmode + operator^(_Ios_Openmode __a, _Ios_Openmode __b) + { return _Ios_Openmode(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Openmode& + operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a | __b; } + + inline _Ios_Openmode& + operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a & __b; } + + inline _Ios_Openmode& + operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) + { return __a = __a ^ __b; } + + inline _Ios_Openmode + operator~(_Ios_Openmode __a) + { return _Ios_Openmode(~static_cast(__a)); } + + + enum _Ios_Iostate + { + _S_goodbit = 0, + _S_badbit = 1L << 0, + _S_eofbit = 1L << 1, + _S_failbit = 1L << 2, + _S_ios_iostate_end = 1L << 16 + }; + + inline _Ios_Iostate + operator&(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) & static_cast(__b)); } + + inline _Ios_Iostate + operator|(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) | static_cast(__b)); } + + inline _Ios_Iostate + operator^(_Ios_Iostate __a, _Ios_Iostate __b) + { return _Ios_Iostate(static_cast(__a) ^ static_cast(__b)); } + + inline _Ios_Iostate& + operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a | __b; } + + inline _Ios_Iostate& + operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a & __b; } + + inline _Ios_Iostate& + operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) + { return __a = __a ^ __b; } + + inline _Ios_Iostate + operator~(_Ios_Iostate __a) + { return _Ios_Iostate(~static_cast(__a)); } + + enum _Ios_Seekdir + { + _S_beg = 0, + _S_cur = SEEK_CUR, + _S_end = SEEK_END, + _S_ios_seekdir_end = 1L << 16 + }; + + // 27.4.2 Class ios_base + /** + * @brief The very top of the I/O class hierarchy. + * + * This class defines everything that can be defined about I/O that does + * not depend on the type of characters being input or output. Most + * people will only see @c ios_base when they need to specify the full + * name of the various I/O flags (e.g., the openmodes). + */ + class ios_base + { + public: + + // 27.4.2.1.1 Class ios_base::failure + /// These are thrown to indicate problems. Doc me. + class failure : public exception + { + public: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 48. Use of non-existent exception constructor + explicit + failure(const string& __str) throw(); + + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual + ~failure() throw(); + + virtual const char* + what() const throw(); + + private: + string _M_msg; + }; + + // 27.4.2.1.2 Type ios_base::fmtflags + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Fmtflags" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type fmtflags are: + * - boolalpha + * - dec + * - fixed + * - hex + * - internal + * - left + * - oct + * - right + * - scientific + * - showbase + * - showpoint + * - showpos + * - skipws + * - unitbuf + * - uppercase + * - adjustfield + * - basefield + * - floatfield + */ + typedef _Ios_Fmtflags fmtflags; + + /// Insert/extract @c bool in alphabetic rather than numeric format. + static const fmtflags boolalpha = fmtflags(__ios_flags::_S_boolalpha); + + /// Converts integer input or generates integer output in decimal base. + static const fmtflags dec = fmtflags(__ios_flags::_S_dec); + + /// Generate floating-point output in fixed-point notation. + static const fmtflags fixed = fmtflags(__ios_flags::_S_fixed); + + /// Converts integer input or generates integer output in hexadecimal base. + static const fmtflags hex = fmtflags(__ios_flags::_S_hex); + + /// Adds fill characters at a designated internal point in certain + /// generated output, or identical to @c right if no such point is + /// designated. + static const fmtflags internal = fmtflags(__ios_flags::_S_internal); + + /// Adds fill characters on the right (final positions) of certain + /// generated output. (I.e., the thing you print is flush left.) + static const fmtflags left = fmtflags(__ios_flags::_S_left); + + /// Converts integer input or generates integer output in octal base. + static const fmtflags oct = fmtflags(__ios_flags::_S_oct); + + /// Adds fill characters on the left (initial positions) of certain + /// generated output. (I.e., the thing you print is flush right.) + static const fmtflags right = fmtflags(__ios_flags::_S_right); + + /// Generates floating-point output in scientific notation. + static const fmtflags scientific = fmtflags(__ios_flags::_S_scientific); + + /// Generates a prefix indicating the numeric base of generated integer + /// output. + static const fmtflags showbase = fmtflags(__ios_flags::_S_showbase); + + /// Generates a decimal-point character unconditionally in generated + /// floating-point output. + static const fmtflags showpoint = fmtflags(__ios_flags::_S_showpoint); + + /// Generates a + sign in non-negative generated numeric output. + static const fmtflags showpos = fmtflags(__ios_flags::_S_showpos); + + /// Skips leading white space before certain input operations. + static const fmtflags skipws = fmtflags(__ios_flags::_S_skipws); + + /// Flushes output after each output operation. + static const fmtflags unitbuf = fmtflags(__ios_flags::_S_unitbuf); + + /// Replaces certain lowercase letters with their uppercase equivalents + /// in generated output. + static const fmtflags uppercase = fmtflags(__ios_flags::_S_uppercase); + + /// A mask of left|right|internal. Useful for the 2-arg form of @c setf. + static const fmtflags adjustfield = fmtflags(__ios_flags::_S_adjustfield); + + /// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf. + static const fmtflags basefield = fmtflags(__ios_flags::_S_basefield); + + /// A mask of scientific|fixed. Useful for the 2-arg form of @c setf. + static const fmtflags floatfield = fmtflags(__ios_flags::_S_floatfield); + + // 27.4.2.1.3 Type ios_base::iostate + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Iostate" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type iostate are: + * - badbit + * - eofbit + * - failbit + * - goodbit + */ + typedef _Ios_Iostate iostate; + + /// Indicates a loss of integrity in an input or output sequence (such + /// as an irrecoverable read error from a file). + static const iostate badbit = iostate(__ios_flags::_S_badbit); + + /// Indicates that an input operation reached the end of an input sequence. + static const iostate eofbit = iostate(__ios_flags::_S_eofbit); + + /// Indicates that an input operation failed to read the expected + /// characters, or that an output operation failed to generate the + /// desired characters. + static const iostate failbit = iostate(__ios_flags::_S_failbit); + + /// Indicates all is well. + static const iostate goodbit = iostate(0); + + // 27.4.2.1.4 Type ios_base::openmode + /** + * @brief This is a bitmask type. + * + * @c "_Ios_Openmode" is implementation-defined, but it is valid to + * perform bitwise operations on these values and expect the Right + * Thing to happen. Defined objects of type openmode are: + * - app + * - ate + * - binary + * - in + * - out + * - trunc + */ + typedef _Ios_Openmode openmode; + + /// Seek to end before each write. + static const openmode app = openmode(__ios_flags::_S_app); + + /// Open and seek to end immediately after opening. + static const openmode ate = openmode(__ios_flags::_S_ate); + + /// Perform input and output in binary mode (as opposed to text mode). + /// This is probably not what you think it is; see + /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3 and + /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7 for more. + static const openmode binary = openmode(__ios_flags::_S_bin); + + /// Open for input. Default for @c ifstream and fstream. + static const openmode in = openmode(__ios_flags::_S_in); + + /// Open for output. Default for @c ofstream and fstream. + static const openmode out = openmode(__ios_flags::_S_out); + + /// Open for input. Default for @c ofstream. + static const openmode trunc = openmode(__ios_flags::_S_trunc); + + // 27.4.2.1.5 Type ios_base::seekdir + /** + * @brief This is an enumerated type. + * + * @c "_Ios_Seekdir" is implementation-defined. Defined values + * of type seekdir are: + * - beg + * - cur, equivalent to @c SEEK_CUR in the C standard library. + * - end, equivalent to @c SEEK_END in the C standard library. + */ + typedef _Ios_Seekdir seekdir; + + /// Request a seek relative to the beginning of the stream. + static const seekdir beg = seekdir(0); + + /// Request a seek relative to the current position within the sequence. + static const seekdir cur = seekdir(SEEK_CUR); + + /// Request a seek relative to the current end of the sequence. + static const seekdir end = seekdir(SEEK_END); + +#ifdef _GLIBCXX_DEPRECATED + // Annex D.6 + typedef int io_state; + typedef int open_mode; + typedef int seek_dir; + + typedef std::streampos streampos; + typedef std::streamoff streamoff; +#endif + + // Callbacks; + /** + * @brief The set of events that may be passed to an event callback. + * + * erase_event is used during ~ios() and copyfmt(). imbue_event is used + * during imbue(). copyfmt_event is used during copyfmt(). + */ + enum event + { + erase_event, + imbue_event, + copyfmt_event + }; + + /** + * @brief The type of an event callback function. + * @param event One of the members of the event enum. + * @param ios_base Reference to the ios_base object. + * @param int The integer provided when the callback was registered. + * + * Event callbacks are user defined functions that get called during + * several ios_base and basic_ios functions, specifically imbue(), + * copyfmt(), and ~ios(). + */ + typedef void (*event_callback) (event, ios_base&, int); + + /** + * @brief Add the callback __fn with parameter __index. + * @param __fn The function to add. + * @param __index The integer to pass to the function when invoked. + * + * Registers a function as an event callback with an integer parameter to + * be passed to the function when invoked. Multiple copies of the + * function are allowed. If there are multiple callbacks, they are + * invoked in the order they were registered. + */ + void + register_callback(event_callback __fn, int __index); + + protected: + //@{ + /** + * @if maint + * ios_base data members (doc me) + * @endif + */ + streamsize _M_precision; + streamsize _M_width; + fmtflags _M_flags; + iostate _M_exception; + iostate _M_streambuf_state; + //@} + + // 27.4.2.6 Members for callbacks + // 27.4.2.6 ios_base callbacks + struct _Callback_list + { + // Data Members + _Callback_list* _M_next; + ios_base::event_callback _M_fn; + int _M_index; + _Atomic_word _M_refcount; // 0 means one reference. + + _Callback_list(ios_base::event_callback __fn, int __index, + _Callback_list* __cb) + : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } + + void + _M_add_reference() { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + // 0 => OK to delete. + int + _M_remove_reference() + { return __gnu_cxx::__exchange_and_add(&_M_refcount, -1); } + }; + + _Callback_list* _M_callbacks; + + void + _M_call_callbacks(event __ev) throw(); + + void + _M_dispose_callbacks(void); + + // 27.4.2.5 Members for iword/pword storage + struct _Words + { + void* _M_pword; + long _M_iword; + _Words() : _M_pword(0), _M_iword(0) { } + }; + + // Only for failed iword/pword calls. + _Words _M_word_zero; + + // Guaranteed storage. + // The first 5 iword and pword slots are reserved for internal use. + static const int _S_local_word_size = 8; + _Words _M_local_word[_S_local_word_size]; + + // Allocated storage. + int _M_word_size; + _Words* _M_word; + + _Words& + _M_grow_words(int __index, bool __iword); + + // Members for locale and locale caching. + locale _M_ios_locale; + + void + _M_init(); + + public: + + // 27.4.2.1.6 Class ios_base::Init + // Used to initialize standard streams. In theory, g++ could use + // -finit-priority to order this stuff correctly without going + // through these machinations. + class Init + { + friend class ios_base; + public: + Init(); + ~Init(); + + private: + static _Atomic_word _S_refcount; + static bool _S_synced_with_stdio; + }; + + // [27.4.2.2] fmtflags state functions + /** + * @brief Access to format flags. + * @return The format control flags for both input and output. + */ + inline fmtflags + flags() const { return _M_flags; } + + /** + * @brief Setting new format flags all at once. + * @param fmtfl The new flags to set. + * @return The previous format control flags. + * + * This function overwrites all the format flags with @a fmtfl. + */ + inline fmtflags + flags(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags = __fmtfl; + return __old; + } + + /** + * @brief Setting new format flags. + * @param fmtfl Additional flags to set. + * @return The previous format control flags. + * + * This function sets additional flags in format control. Flags that + * were previously set remain set. + */ + inline fmtflags + setf(fmtflags __fmtfl) + { + fmtflags __old = _M_flags; + _M_flags |= __fmtfl; + return __old; + } + + /** + * @brief Setting new format flags. + * @param fmtfl Additional flags to set. + * @param mask The flags mask for @a fmtfl. + * @return The previous format control flags. + * + * This function clears @a mask in the format flags, then sets + * @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield. + */ + inline fmtflags + setf(fmtflags __fmtfl, fmtflags __mask) + { + fmtflags __old = _M_flags; + _M_flags &= ~__mask; + _M_flags |= (__fmtfl & __mask); + return __old; + } + + /** + * @brief Clearing format flags. + * @param mask The flags to unset. + * + * This function clears @a mask in the format flags. + */ + inline void + unsetf(fmtflags __mask) { _M_flags &= ~__mask; } + + /** + * @brief Flags access. + * @return The precision to generate on certain output operations. + * + * @if maint + * Be careful if you try to give a definition of "precision" here; see + * DR 189. + * @endif + */ + inline streamsize + precision() const { return _M_precision; } + + /** + * @brief Changing flags. + * @param prec The new precision value. + * @return The previous value of precision(). + */ + inline streamsize + precision(streamsize __prec) + { + streamsize __old = _M_precision; + _M_precision = __prec; + return __old; + } + + /** + * @brief Flags access. + * @return The minimum field width to generate on output operations. + * + * "Minimum field width" refers to the number of characters. + */ + inline streamsize + width() const { return _M_width; } + + /** + * @brief Changing flags. + * @param wide The new width value. + * @return The previous value of width(). + */ + inline streamsize + width(streamsize __wide) + { + streamsize __old = _M_width; + _M_width = __wide; + return __old; + } + + // [27.4.2.4] ios_base static members + /** + * @brief Interaction with the standard C I/O objects. + * @param sync Whether to synchronize or not. + * @return True if the standard streams were previously synchronized. + * + * The synchronization referred to is @e only that between the standard + * C facilities (e.g., stdout) and the standard C++ objects (e.g., + * cout). User-declared streams are unaffected. See + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#8 for more. + */ + static bool + sync_with_stdio(bool __sync = true); + + // [27.4.2.3] ios_base locale functions + /** + * @brief Setting a new locale. + * @param loc The new locale. + * @return The previous locale. + * + * Sets the new locale for this stream, and then invokes each callback + * with imbue_event. + */ + locale + imbue(const locale& __loc); + + /** + * @brief Locale access + * @return A copy of the current locale. + * + * If @c imbue(loc) has previously been called, then this function + * returns @c loc. Otherwise, it returns a copy of @c std::locale(), + * the global C++ locale. + */ + inline locale + getloc() const { return _M_ios_locale; } + + /** + * @brief Locale access + * @return A reference to the current locale. + * + * Like getloc above, but returns a reference instead of + * generating a copy. + */ + inline const locale& + _M_getloc() const { return _M_ios_locale; } + + // [27.4.2.5] ios_base storage functions + /** + * @brief Access to unique indices. + * @return An integer different from all previous calls. + * + * This function returns a unique integer every time it is called. It + * can be used for any purpose, but is primarily intended to be a unique + * index for the iword and pword functions. The expectation is that an + * application calls xalloc in order to obtain an index in the iword and + * pword arrays that can be used without fear of conflict. + * + * The implementation maintains a static variable that is incremented and + * returned on each invocation. xalloc is guaranteed to return an index + * that is safe to use in the iword and pword arrays. + */ + static int + xalloc() throw(); + + /** + * @brief Access to integer array. + * @param __ix Index into the array. + * @return A reference to an integer associated with the index. + * + * The iword function provides access to an array of integers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All integers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. + */ + inline long& + iword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, true); + return __word._M_iword; + } + + /** + * @brief Access to void pointer array. + * @param __ix Index into the array. + * @return A reference to a void* associated with the index. + * + * The pword function provides access to an array of pointers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All pointers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. + */ + inline void*& + pword(int __ix) + { + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, false); + return __word._M_pword; + } + + // Destructor + /** + * Invokes each callback with erase_event. Destroys local storage. + * + * Note that the ios_base object for the standard streams never gets + * destroyed. As a result, any callbacks registered with the standard + * streams will not get invoked with erase_event (unless copyfmt is + * used). + */ + virtual ~ios_base(); + + protected: + ios_base(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 50. Copy constructor and assignment operator of ios_base + private: + ios_base(const ios_base&); + + ios_base& + operator=(const ios_base&); + }; + + // [27.4.5.1] fmtflags manipulators + /// Calls base.setf(ios_base::boolalpha). + inline ios_base& + boolalpha(ios_base& __base) + { + __base.setf(ios_base::boolalpha); + return __base; + } + + /// Calls base.unsetf(ios_base::boolalpha). + inline ios_base& + noboolalpha(ios_base& __base) + { + __base.unsetf(ios_base::boolalpha); + return __base; + } + + /// Calls base.setf(ios_base::showbase). + inline ios_base& + showbase(ios_base& __base) + { + __base.setf(ios_base::showbase); + return __base; + } + + /// Calls base.unsetf(ios_base::showbase). + inline ios_base& + noshowbase(ios_base& __base) + { + __base.unsetf(ios_base::showbase); + return __base; + } + + /// Calls base.setf(ios_base::showpoint). + inline ios_base& + showpoint(ios_base& __base) + { + __base.setf(ios_base::showpoint); + return __base; + } + + /// Calls base.unsetf(ios_base::showpoint). + inline ios_base& + noshowpoint(ios_base& __base) + { + __base.unsetf(ios_base::showpoint); + return __base; + } + + /// Calls base.setf(ios_base::showpos). + inline ios_base& + showpos(ios_base& __base) + { + __base.setf(ios_base::showpos); + return __base; + } + + /// Calls base.unsetf(ios_base::showpos). + inline ios_base& + noshowpos(ios_base& __base) + { + __base.unsetf(ios_base::showpos); + return __base; + } + + /// Calls base.setf(ios_base::skipws). + inline ios_base& + skipws(ios_base& __base) + { + __base.setf(ios_base::skipws); + return __base; + } + + /// Calls base.unsetf(ios_base::skipws). + inline ios_base& + noskipws(ios_base& __base) + { + __base.unsetf(ios_base::skipws); + return __base; + } + + /// Calls base.setf(ios_base::uppercase). + inline ios_base& + uppercase(ios_base& __base) + { + __base.setf(ios_base::uppercase); + return __base; + } + + /// Calls base.unsetf(ios_base::uppercase). + inline ios_base& + nouppercase(ios_base& __base) + { + __base.unsetf(ios_base::uppercase); + return __base; + } + + /// Calls base.setf(ios_base::unitbuf). + inline ios_base& + unitbuf(ios_base& __base) + { + __base.setf(ios_base::unitbuf); + return __base; + } + + /// Calls base.unsetf(ios_base::unitbuf). + inline ios_base& + nounitbuf(ios_base& __base) + { + __base.unsetf(ios_base::unitbuf); + return __base; + } + + // [27.4.5.2] adjustfield anipulators + /// Calls base.setf(ios_base::internal, ios_base::adjustfield). + inline ios_base& + internal(ios_base& __base) + { + __base.setf(ios_base::internal, ios_base::adjustfield); + return __base; + } + + /// Calls base.setf(ios_base::left, ios_base::adjustfield). + inline ios_base& + left(ios_base& __base) + { + __base.setf(ios_base::left, ios_base::adjustfield); + return __base; + } + + /// Calls base.setf(ios_base::right, ios_base::adjustfield). + inline ios_base& + right(ios_base& __base) + { + __base.setf(ios_base::right, ios_base::adjustfield); + return __base; + } + + // [27.4.5.3] basefield anipulators + /// Calls base.setf(ios_base::dec, ios_base::basefield). + inline ios_base& + dec(ios_base& __base) + { + __base.setf(ios_base::dec, ios_base::basefield); + return __base; + } + + /// Calls base.setf(ios_base::hex, ios_base::basefield). + inline ios_base& + hex(ios_base& __base) + { + __base.setf(ios_base::hex, ios_base::basefield); + return __base; + } + + /// Calls base.setf(ios_base::oct, ios_base::basefield). + inline ios_base& + oct(ios_base& __base) + { + __base.setf(ios_base::oct, ios_base::basefield); + return __base; + } + + // [27.4.5.4] floatfield anipulators + /// Calls base.setf(ios_base::fixed, ios_base::floatfield). + inline ios_base& + fixed(ios_base& __base) + { + __base.setf(ios_base::fixed, ios_base::floatfield); + return __base; + } + + /// Calls base.setf(ios_base::scientific, ios_base::floatfield). + inline ios_base& + scientific(ios_base& __base) + { + __base.setf(ios_base::scientific, ios_base::floatfield); + return __base; + } +} // namespace std + +#endif /* _IOS_BASE_H */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/istream.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/istream.tcc new file mode 100644 index 00000000000..9decce32d24 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/istream.tcc @@ -0,0 +1,1192 @@ +// istream classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#ifndef _ISTREAM_TCC +#define _ISTREAM_TCC 1 + +#pragma GCC system_header + +#include +#include // For flush() + +namespace std +{ + template + basic_istream<_CharT, _Traits>::sentry:: + sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + if (__in.good()) + { + if (__in.tie()) + __in.tie()->flush(); + if (!__noskip && (__in.flags() & ios_base::skipws)) + { + const __int_type __eof = traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + const __ctype_type& __ct = __check_facet(__in._M_ctype); + while (!traits_type::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, + traits_type::to_char_type(__c))) + __c = __sb->snextc(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 195. Should basic_istream::sentry's constructor ever + // set eofbit? + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + } + + if (__in.good() && __err == ios_base::goodbit) + _M_ok = true; + else + { + __err |= ios_base::failbit; + __in.setstate(__err); + } + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__istream_type& (*__pf)(__istream_type&)) + { return __pf(*this); } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__ios_type& (*__pf)(__ios_type&)) + { + __pf(*this); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(ios_base& (*__pf)(ios_base&)) + { + __pf(*this); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(bool& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(short& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + long __l; + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 118. basic_istream uses nonexistent num_get member functions. + if (!(__err & ios_base::failbit) + && (numeric_limits::min() <= __l + && __l <= numeric_limits::max())) + __n = __l; + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned short& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(int& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + long __l; + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 118. basic_istream uses nonexistent num_get member functions. + if (!(__err & ios_base::failbit) + && (numeric_limits::min() <= __l + && __l <= numeric_limits::max())) + __n = __l; + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned int& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(unsigned long long& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } +#endif + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(float& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(double& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(long double& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(void*& __n) + { + sentry __cerb(*this, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + operator>>(__streambuf_type* __sbout) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, false); + if (__cerb && __sbout) + { + try + { + if (!__copy_streambufs(this->rdbuf(), __sbout)) + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbout) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + get(void) + { + const int_type __eof = traits_type::eof(); + int_type __c = __eof; + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + __c = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (!traits_type::eq_int_type(__c, __eof)) + _M_gcount = 1; + else + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return __c; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type& __c) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __cb = this->rdbuf()->sbumpc(); + // 27.6.1.1 paragraph 3 + if (!traits_type::eq_int_type(__cb, traits_type::eof())) + { + _M_gcount = 1; + __c = traits_type::to_char_type(__cb); + } + else + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + get(__streambuf_type& __sb, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __this_sb = this->rdbuf(); + int_type __c = __this_sb->sgetc(); + char_type __c2 = traits_type::to_char_type(__c); + + while (!traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim) + && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) + { + ++_M_gcount; + __c = __this_sb->snextc(); + __c2 = traits_type::to_char_type(__c); + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + getline(char_type* __s, streamsize __n, char_type __delim) + { + _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, true); + if (__cerb) + { + try + { + const int_type __idelim = traits_type::to_int_type(__delim); + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim)) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + __n - _M_gcount - 1); + if (__size > 1) + { + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + traits_type::copy(__s, __sb->gptr(), __size); + __s += __size; + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); + } + else + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } + } + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __idelim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + } + *__s = char_type(); + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + ignore(streamsize __n, int_type __delim) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb && __n > 0) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + int_type __c; + + if (__n != numeric_limits::max()) + --__n; + while (_M_gcount <= __n + && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof)) + { + ++_M_gcount; + if (traits_type::eq_int_type(__c, __delim)) + break; + } + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + typename basic_istream<_CharT, _Traits>::int_type + basic_istream<_CharT, _Traits>:: + peek(void) + { + int_type __c = traits_type::eof(); + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + __c = this->rdbuf()->sgetc(); + if (traits_type::eq_int_type(__c, traits_type::eof())) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __c; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + read(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + _M_gcount = this->rdbuf()->sgetn(__s, __n); + if (_M_gcount != __n) + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + streamsize + basic_istream<_CharT, _Traits>:: + readsome(char_type* __s, streamsize __n) + { + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + // Cannot compare int_type with streamsize generically. + const streamsize __num = this->rdbuf()->in_avail(); + if (__num > 0) + _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); + else if (__num == -1) + __err |= ios_base::eofbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return _M_gcount; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + putback(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + unget(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? + _M_gcount = 0; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __eof = traits_type::eof(); + __streambuf_type* __sb = this->rdbuf(); + if (!__sb + || traits_type::eq_int_type(__sb->sungetc(), __eof)) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + int + basic_istream<_CharT, _Traits>:: + sync(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + int __ret = -1; + sentry __cerb(*this, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + __streambuf_type* __sb = this->rdbuf(); + if (__sb) + { + if (__sb->pubsync() == -1) + __err |= ios_base::badbit; + else + __ret = 0; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return __ret; + } + + template + typename basic_istream<_CharT, _Traits>::pos_type + basic_istream<_CharT, _Traits>:: + tellg(void) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(pos_type __pos) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>:: + seekg(off_type __off, ios_base::seekdir __dir) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR60. Do not change _M_gcount. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + // 27.6.1.2.3 Character extraction templates + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __int_type __cb = __in.rdbuf()->sbumpc(); + if (!_Traits::eq_int_type(__cb, _Traits::eof())) + __c = _Traits::to_char_type(__cb); + else + __err |= (ios_base::eofbit | ios_base::failbit); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + if (__err) + __in.setstate(__err); + } + return __in; + } + + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename _Traits::int_type int_type; + typedef _CharT char_type; + typedef ctype<_CharT> __ctype_type; + + streamsize __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Figure out how many characters to extract. + streamsize __num = __in.width(); + if (__num <= 0) + __num = numeric_limits::max(); + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + + const int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + int_type __c = __sb->sgetc(); + + while (__extracted < __num - 1 + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + _Traits::to_char_type(__c))) + { + *__s++ = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 68. Extractors for char* should store null at end + *__s = char_type(); + __in.width(0); + } + catch(...) + { __in._M_setstate(ios_base::badbit); } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + // 27.6.1.4 Standard basic_istream manipulators + template + basic_istream<_CharT,_Traits>& + ws(basic_istream<_CharT,_Traits>& __in) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename __istream_type::int_type __int_type; + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (!_Traits::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) + __c = __sb->snextc(); + + if (_Traits::eq_int_type(__c, __eof)) + __in.setstate(ios_base::eofbit); + return __in; + } + + // 21.3.7.9 basic_string::getline and operators + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + // 211. operator>>(istream&, string&) doesn't set failbit + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template + inline basic_istream<_CharT,_Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + basic_string<_CharT,_Traits,_Alloc>& __str) + { return getline(__in, __str, __in.widen('\n')); } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_istream; + extern template istream& ws(istream&); + extern template istream& operator>>(istream&, char&); + extern template istream& operator>>(istream&, char*); + extern template istream& operator>>(istream&, unsigned char&); + extern template istream& operator>>(istream&, signed char&); + extern template istream& operator>>(istream&, unsigned char*); + extern template istream& operator>>(istream&, signed char*); + + extern template class basic_iostream; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_istream; + extern template wistream& ws(wistream&); + extern template wistream& operator>>(wistream&, wchar_t&); + extern template wistream& operator>>(wistream&, wchar_t*); + + extern template class basic_iostream; +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/list.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/list.tcc new file mode 100644 index 00000000000..aaaa8c364bd --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/list.tcc @@ -0,0 +1,377 @@ +// List implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file list.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LIST_TCC +#define _LIST_TCC 1 + +namespace _GLIBCXX_STD +{ + template + void + _List_base<_Tp,_Alloc>:: + _M_clear() + { + typedef _List_node<_Tp> _Node; + _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next); + while (__cur != &this->_M_impl._M_node) + { + _Node* __tmp = __cur; + __cur = static_cast<_Node*>(__cur->_M_next); + std::_Destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + } + + template + typename list<_Tp,_Alloc>::iterator + list<_Tp,_Alloc>:: + insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); + return __tmp; + } + + template + typename list<_Tp,_Alloc>::iterator + list<_Tp,_Alloc>:: + erase(iterator __position) + { + iterator __ret = __position._M_node->_M_next; + _M_erase(__position); + return __ret; + } + + template + void + list<_Tp,_Alloc>:: + resize(size_type __new_size, const value_type& __x) + { + iterator __i = begin(); + size_type __len = 0; + for ( ; __i != end() && __len < __new_size; ++__i, ++__len) + ; + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); + } + + template + list<_Tp,_Alloc>& + list<_Tp,_Alloc>:: + operator=(const list& __x) + { + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + return *this; + } + + template + void + list<_Tp,_Alloc>:: + _M_fill_assign(size_type __n, const value_type& __val) + { + iterator __i = begin(); + for ( ; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); + } + + template + template + void + list<_Tp,_Alloc>:: + _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, + __false_type) + { + iterator __first1 = begin(); + iterator __last1 = end(); + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + + template + void + list<_Tp,_Alloc>:: + remove(const value_type& __value) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (*__first == __value) + _M_erase(__first); + __first = __next; + } + } + + template + void + list<_Tp,_Alloc>:: + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + void + list<_Tp,_Alloc>:: + merge(list& __x) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template + void + list<_Tp,_Alloc>:: + sort() + { + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1) ); + swap( *(__fill-1) ); + } + } + + template + template + void + list<_Tp,_Alloc>:: + remove_if(_Predicate __pred) + { + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) + { + iterator __next = __first; + ++__next; + if (__pred(*__first)) + _M_erase(__first); + __first = __next; + } + } + + template + template + void + list<_Tp,_Alloc>:: + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + _M_erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + template + void + list<_Tp,_Alloc>:: + merge(list& __x, _StrictWeakOrdering __comp) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + { + iterator __next = __first2; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } + } + + template + template + void + list<_Tp,_Alloc>:: + sort(_StrictWeakOrdering __comp) + { + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry, __comp); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1), __comp ); + swap( *(__fill-1) ); + } + } +} // namespace std + +#endif /* _LIST_TCC */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_classes.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_classes.h new file mode 100644 index 00000000000..95d9c0366a0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_classes.h @@ -0,0 +1,599 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file localefwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_CLASSES_H +#define _LOCALE_CLASSES_H 1 + +#pragma GCC system_header + +#include +#include // For strcmp. +#include +#include +#include + +namespace std +{ + // 22.1.1 Class locale + /** + * @brief Container class for localization functionality. + * + * The locale class is first a class wrapper for C library locales. It is + * also an extensible container for user-defined localization. A locale is + * a collection of facets that implement various localization features such + * as money, time, and number printing. + * + * Constructing C++ locales does not change the C library locale. + * + * This library supports efficient construction and copying of locales + * through a reference counting implementation of the locale class. + */ + class locale + { + public: + // Types: + /// Definition of locale::category. + typedef int category; + + // Forward decls and friends: + class facet; + class id; + class _Impl; + + friend class facet; + friend class _Impl; + + template + friend bool + has_facet(const locale&) throw(); + + template + friend const _Facet& + use_facet(const locale&); + + template + friend struct __use_cache; + + //@{ + /** + * @brief Category values. + * + * The standard category values are none, ctype, numeric, collate, time, + * monetary, and messages. They form a bitmask that supports union and + * intersection. The category all is the union of these values. + * + * @if maint + * NB: Order must match _S_facet_categories definition in locale.cc + * @endif + */ + static const category none = 0; + static const category ctype = 1L << 0; + static const category numeric = 1L << 1; + static const category collate = 1L << 2; + static const category time = 1L << 3; + static const category monetary = 1L << 4; + static const category messages = 1L << 5; + static const category all = (ctype | numeric | collate | + time | monetary | messages); + //@} + + // Construct/copy/destroy: + + /** + * @brief Default constructor. + * + * Constructs a copy of the global locale. If no locale has been + * explicitly set, this is the "C" locale. + */ + locale() throw(); + + /** + * @brief Copy constructor. + * + * Constructs a copy of @a other. + * + * @param other The locale to copy. + */ + locale(const locale& __other) throw(); + + /** + * @brief Named locale constructor. + * + * Constructs a copy of the named C library locale. + * + * @param s Name of the locale to construct. + * @throw std::runtime_error if s is null or an undefined locale. + */ + explicit + locale(const char* __s); + + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale named by @a s. If base is + * named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param s Name of the locale to use facets from. + * @param cat Set of categories defining the facets to use from s. + * @throw std::runtime_error if s is null or an undefined locale. + */ + locale(const locale& __base, const char* __s, category __cat); + + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale @a add. If @a base and @a + * add are named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param add The locale to use facets from. + * @param cat Set of categories defining the facets to use from add. + */ + locale(const locale& __base, const locale& __add, category __cat); + + /** + * @brief Construct locale with another facet. + * + * Constructs a copy of the locale @a other. The facet @f is added to + * @other, replacing an existing facet of type Facet if there is one. If + * @f is null, this locale is a copy of @a other. + * + * @param other The locale to copy. + * @param f The facet to add in. + */ + template + locale(const locale& __other, _Facet* __f); + + /// Locale destructor. + ~locale() throw(); + + /** + * @brief Assignment operator. + * + * Set this locale to be a copy of @a other. + * + * @param other The locale to copy. + * @return A reference to this locale. + */ + const locale& + operator=(const locale& __other) throw(); + + /** + * @brief Construct locale with another facet. + * + * Constructs and returns a new copy of this locale. Adds or replaces an + * existing facet of type Facet from the locale @a other into the new + * locale. + * + * @param Facet The facet type to copy from other + * @param other The locale to copy from. + * @return Newly constructed locale. + * @throw std::runtime_error if other has no facet of type Facet. + */ + template + locale + combine(const locale& __other) const; + + // Locale operations: + /** + * @brief Return locale name. + * @return Locale name or "*" if unnamed. + */ + string + name() const; + + /** + * @brief Locale equality. + * + * @param other The locale to compare against. + * @return True if other and this refer to the same locale instance, are + * copies, or have the same name. False otherwise. + */ + bool + operator==(const locale& __other) const throw (); + + /** + * @brief Locale inequality. + * + * @param other The locale to compare against. + * @return ! (*this == other) + */ + inline bool + operator!=(const locale& __other) const throw () + { return !(this->operator==(__other)); } + + /** + * @brief Compare two strings according to collate. + * + * Template operator to compare two strings using the compare function of + * the collate facet in this locale. One use is to provide the locale to + * the sort function. For example, a vector v of strings could be sorted + * according to locale loc by doing: + * @code + * std::sort(v.begin(), v.end(), loc); + * @endcode + * + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return True if collate facet compares s1 < s2, else false. + */ + template + bool + operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, + const basic_string<_Char, _Traits, _Alloc>& __s2) const; + + // Global locale objects: + /** + * @brief Set global locale + * + * This function sets the global locale to the argument and returns a + * copy of the previous global locale. If the argument has a name, it + * will also call std::setlocale(LC_ALL, loc.name()). + * + * @param locale The new locale to make global. + * @return Copy of the old global locale. + */ + static locale + global(const locale&); + + /** + * @brief Return reference to the "C" locale. + */ + static const locale& + classic(); + + private: + // The (shared) implementation + _Impl* _M_impl; + + // The "C" reference locale + static _Impl* _S_classic; + + // Current global locale + static _Impl* _S_global; + + // Names of underlying locale categories. + // NB: locale::global() has to know how to modify all the + // underlying categories, not just the ones required by the C++ + // standard. + static const char* const* const _S_categories; + + // Number of standard categories. For C++, these categories are + // collate, ctype, monetary, numeric, time, and messages. These + // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, + // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE + // 1003.1-2001) specifies LC_MESSAGES. + // In addition to the standard categories, the underlying + // operating system is allowed to define extra LC_* + // macros. For GNU systems, the following are also valid: + // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, + // and LC_IDENTIFICATION. + static const size_t _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + explicit + locale(_Impl*) throw(); + + static void + _S_initialize(); + + static void + _S_initialize_once(); + + static category + _S_normalize_category(category); + + void + _M_coalesce(const locale& __base, const locale& __add, category __cat); + }; + + + // 22.1.1.1.2 Class locale::facet + /** + * @brief Localization functionality base class. + * + * The facet class is the base class for a localization feature, such as + * money, time, and number printing. It provides common support for facets + * and reference management. + * + * Facets may not be copied or assigned. + */ + class locale::facet + { + private: + friend class locale; + friend class locale::_Impl; + + mutable _Atomic_word _M_refcount; + + // Contains data from the underlying "C" library for the classic locale. + static __c_locale _S_c_locale; + + // String literal for the name of the classic locale. + static const char _S_c_name[2]; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + static void + _S_initialize_once(); + + protected: + /** + * @brief Facet constructor. + * + * This is the constructor provided by the standard. If refs is 0, the + * facet is destroyed when the last referencing locale is destroyed. + * Otherwise the facet will never be destroyed. + * + * @param refs The initial value for reference count. + */ + explicit + facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0) + { } + + /// Facet destructor. + virtual + ~facet(); + + static void + _S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old = 0); + + static __c_locale + _S_clone_c_locale(__c_locale& __cloc); + + static void + _S_destroy_c_locale(__c_locale& __cloc); + + // Returns data from the underlying "C" library data for the + // classic locale. + static __c_locale + _S_get_c_locale(); + + static const char* + _S_get_c_name(); + + private: + inline void + _M_add_reference() const throw() + { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + inline void + _M_remove_reference() const throw() + { + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch (...) + { } + } + } + + facet(const facet&); // Not defined. + + facet& + operator=(const facet&); // Not defined. + }; + + + // 22.1.1.1.3 Class locale::id + /** + * @brief Facet ID class. + * + * The ID class provides facets with an index used to identify them. + * Every facet class must define a public static member locale::id, or be + * derived from a facet that provides this member, otherwise the facet + * cannot be used in a locale. The locale::id ensures that each class + * type gets a unique identifier. + */ + class locale::id + { + private: + friend class locale; + friend class locale::_Impl; + + template + friend const _Facet& + use_facet(const locale&); + + template + friend bool + has_facet(const locale&) throw (); + + // NB: There is no accessor for _M_index because it may be used + // before the constructor is run; the effect of calling a member + // function (even an inline) would be undefined. + mutable size_t _M_index; + + // Last id number assigned. + static _Atomic_word _S_refcount; + + void + operator=(const id&); // Not defined. + + id(const id&); // Not defined. + + public: + // NB: This class is always a static data member, and thus can be + // counted on to be zero-initialized. + /// Constructor. + id() { } + + size_t + _M_id() const; + }; + + + // Implementation object for locale. + class locale::_Impl + { + public: + // Friends. + friend class locale; + friend class locale::facet; + + template + friend bool + has_facet(const locale&) throw(); + + template + friend const _Facet& + use_facet(const locale&); + + template + friend struct __use_cache; + + private: + // Data Members. + _Atomic_word _M_refcount; + const facet** _M_facets; + size_t _M_facets_size; + const facet** _M_caches; + char** _M_names; + static const locale::id* const _S_id_ctype[]; + static const locale::id* const _S_id_numeric[]; + static const locale::id* const _S_id_collate[]; + static const locale::id* const _S_id_time[]; + static const locale::id* const _S_id_monetary[]; + static const locale::id* const _S_id_messages[]; + static const locale::id* const* const _S_facet_categories[]; + + inline void + _M_add_reference() throw() + { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + inline void + _M_remove_reference() throw() + { + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch(...) + { } + } + } + + _Impl(const _Impl&, size_t); + _Impl(const char*, size_t); + _Impl(size_t) throw(); + + ~_Impl() throw(); + + _Impl(const _Impl&); // Not defined. + + void + operator=(const _Impl&); // Not defined. + + inline bool + _M_check_same_name() + { + bool __ret = true; + for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i) + __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0; + return __ret; + } + + void + _M_replace_categories(const _Impl*, category); + + void + _M_replace_category(const _Impl*, const locale::id* const*); + + void + _M_replace_facet(const _Impl*, const locale::id*); + + void + _M_install_facet(const locale::id*, const facet*); + + template + inline void + _M_init_facet(_Facet* __facet) + { _M_install_facet(&_Facet::id, __facet); } + + void + _M_install_cache(const facet* __cache, size_t __index) throw() + { + __cache->_M_add_reference(); + _M_caches[__index] = __cache; + } + }; + + template + locale::locale(const locale& __other, _Facet* __f) + { + _M_impl = new _Impl(*__other._M_impl, 1); + + char* _M_tmp_names[_S_categories_size]; + size_t __i = 0; + try + { + for (; __i < _S_categories_size; ++__i) + { + _M_tmp_names[__i] = new char[2]; + std::strcpy(_M_tmp_names[__i], "*"); + } + _M_impl->_M_install_facet(&_Facet::id, __f); + } + catch(...) + { + _M_impl->_M_remove_reference(); + for (size_t __j = 0; __j < __i; ++__j) + delete [] _M_tmp_names[__j]; + __throw_exception_again; + } + + for (size_t __k = 0; __k < _S_categories_size; ++__k) + { + delete [] _M_impl->_M_names[__k]; + _M_impl->_M_names[__k] = _M_tmp_names[__k]; + } + } +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.h new file mode 100644 index 00000000000..db0e9514623 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.h @@ -0,0 +1,4558 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file locale_facets.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_FACETS_H +#define _LOCALE_FACETS_H 1 + +#pragma GCC system_header + +#include // For struct tm +#include // For wctype_t +#include +#include // For ios_base, ios_base::iostate +#include + +namespace std +{ + // NB: Don't instantiate required wchar_t facets if no wchar_t support. +#ifdef _GLIBCXX_USE_WCHAR_T +# define _GLIBCXX_NUM_FACETS 28 +#else +# define _GLIBCXX_NUM_FACETS 14 +#endif + + // Convert string to numeric value of type _Tv and store results. + // NB: This is specialized for all required types, there is no + // generic definition. + template + void + __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, + const __c_locale& __cloc); + + // Explicit specializations for required types. + template<> + void + __convert_to_v(const char*, float&, ios_base::iostate&, + const __c_locale&); + + template<> + void + __convert_to_v(const char*, double&, ios_base::iostate&, + const __c_locale&); + + template<> + void + __convert_to_v(const char*, long double&, ios_base::iostate&, + const __c_locale&); + + // NB: __pad is a struct, rather than a function, so it can be + // partially-specialized. + template + struct __pad + { + static void + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, const streamsize __newlen, + const streamsize __oldlen, const bool __num); + }; + + // Used by both numeric and monetary facets. + // Inserts "group separator" characters into an array of characters. + // It's recursive, one iteration per group. It moves the characters + // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this + // only with __glen != 0. + template + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last); + + // This template permits specializing facet output code for + // ostreambuf_iterator. For ostreambuf_iterator, sputn is + // significantly more efficient than incrementing iterators. + template + inline + ostreambuf_iterator<_CharT> + __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) + { + __s._M_put(__ws, __len); + return __s; + } + + // This is the unspecialized form of the template. + template + inline + _OutIter + __write(_OutIter __s, const _CharT* __ws, int __len) + { + for (int __j = 0; __j < __len; __j++, ++__s) + *__s = __ws[__j]; + return __s; + } + + + // 22.2.1.1 Template class ctype + // Include host and configuration specific ctype enums for ctype_base. + #include + + // Common base for ctype<_CharT>. + /** + * @brief Common base for ctype facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abtract stubs for the protected virtual + * functions. + */ + template + class __ctype_abstract_base : public locale::facet, public ctype_base + { + public: + // Types: + /// Typedef for the template parameter + typedef _CharT char_type; + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * It does so by returning the value of ctype::do_is(). + * + * @param c The char_type to compare the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + bool + is(mask __m, char_type __c) const + { return this->do_is(__m, __c); } + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the char array. It does so by returning the value of + * ctype::do_is(). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + const char_type* + is(const char_type *__lo, const char_type *__hi, mask *__vec) const + { return this->do_is(__lo, __hi, __vec); } + + /** + * @brief Find char_type matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. It does so by returning + * ctype::do_scan_is(). + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to matching char_type if found, else @a hi. + */ + const char_type* + scan_is(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_is(__m, __lo, __hi); } + + /** + * @brief Find char_type not matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is false. It does so by returning + * ctype::do_scan_not(). + * + * @param m The mask to compare against. + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return Pointer to non-matching char if found, else @a hi. + */ + const char_type* + scan_not(mask __m, const char_type* __lo, const char_type* __hi) const + { return this->do_scan_not(__m, __lo, __hi); } + + /** + * @brief Convert to uppercase. + * + * This function converts the argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. It does + * so by returning ctype::do_toupper(). + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char_type in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. It does so + * by returning ctype:: do_toupper(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the argument to lowercase if possible. If + * not possible (for example, '2'), returns the argument. It does so + * by returning ctype::do_tolower(c). + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char_type in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. It does so + * by returning ctype:: do_tolower(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char to char_type + * + * This function converts the char argument to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type. + */ + char_type + widen(char __c) const + { return this->do_widen(__c); } + + /** + * @brief Widen array to char_type + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { return this->do_widen(__lo, __hi, __to); } + + /** + * @brief Narrow char_type to char + * + * This function converts the char_type to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. It does so by returning + * ctype::do_narrow(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + char + narrow(char_type __c, char __dfault) const + { return this->do_narrow(__c, __dfault); } + + /** + * @brief Narrow array to char array + * + * This function converts each char_type in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char_type in the input that cannot be + * converted, @a dfault is used instead. It does so by returning + * ctype::do_narrow(lo, hi, dfault, to). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { return this->do_narrow(__lo, __hi, __dfault, __to); } + + protected: + explicit + __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } + + virtual + ~__ctype_abstract_base() { } + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The char_type to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool + do_is(mask __m, char_type __c) const = 0; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, + mask* __vec) const = 0; + + /** + * @brief Find char_type matching mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char_type if found, else @a hi. + */ + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + /** + * @brief Find char_type not matching mask + * + * This function searches for and returns a pointer to the first + * char_type c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char_type if found, else @a hi. + */ + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const = 0; + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char_type argument to uppercase + * if possible. If not possible (for example, '2'), returns the + * argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const = 0; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const = 0; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const = 0; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const = 0; + + /** + * @brief Widen char + * + * This virtual function converts the char to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type + */ + virtual char_type + do_widen(char) const = 0; + + /** + * @brief Widen char array + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, + char_type* __dest) const = 0; + + /** + * @brief Narrow char_type to char + * + * This virtual function converts the argument to char using the + * simplest reasonable transformation. If the conversion fails, dfault + * is returned instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type, char __dfault) const = 0; + + /** + * @brief Narrow char_type array to char + * + * This virtual function converts each char_type in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any element in the input that + * cannot be converted, @a dfault is used instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const = 0; + }; + + // NB: Generic, mostly useless implementation. + /** + * @brief Template ctype facet + * + * This template class defines classification and conversion functions for + * character sets. It wraps functionality. Ctype gets used by + * streams for many I/O operations. + * + * This template provides the protected virtual functions the developer + * will have to replace in a derived class or specialization to make a + * working facet. The public functions that access them are defined in + * __ctype_abstract_base, to allow for implementation flexibility. See + * ctype for an example. The functions are documented in + * __ctype_abstract_base. + * + * Note: implementations are provided for all the protected virtual + * functions, but will likely not be useful. + */ + template + class ctype : public __ctype_abstract_base<_CharT> + { + public: + // Types: + typedef _CharT char_type; + typedef typename __ctype_abstract_base<_CharT>::mask mask; + + /// The facet id for ctype + static locale::id id; + + explicit + ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } + + protected: + virtual + ~ctype(); + + virtual bool + do_is(mask __m, char_type __c) const; + + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + virtual char_type + do_toupper(char_type __c) const; + + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_tolower(char_type __c) const; + + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + virtual char_type + do_widen(char __c) const; + + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + virtual char + do_narrow(char_type, char __dfault) const; + + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const; + }; + + template + locale::id ctype<_CharT>::id; + + // 22.2.1.3 ctype specialization. + /** + * @brief The ctype specialization. + * + * This class defines classification and conversion functions for + * the char type. It gets used by char streams for many I/O + * operations. The char specialization provides a number of + * optimizations as well. + */ + template<> + class ctype : public locale::facet, public ctype_base + { + public: + // Types: + /// Typedef for the template parameter char. + typedef char char_type; + + protected: + // Data Members: + __c_locale _M_c_locale_ctype; + bool _M_del; + __to_type _M_toupper; + __to_type _M_tolower; + const mask* _M_table; + mutable char _M_widen_ok; + mutable char _M_widen[1 + static_cast(-1)]; + mutable char _M_narrow[1 + static_cast(-1)]; + mutable char _M_narrow_ok; // 0 uninitialized, 1 init, + // 2 memcpy can't be used + + public: + /// The facet id for ctype + static locale::id id; + /// The size of the mask table. It is SCHAR_MAX + 1. + static const size_t table_size = 1 + static_cast(-1); + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param table If non-zero, table is used as the per-char mask. + * Else classic_table() is used. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); + + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param table If non-zero, table is used as the per-char mask. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, + size_t __refs = 0); + + /** + * @brief Test char classification. + * + * This function compares the mask table[c] to @a m. + * + * @param c The char to compare the mask of. + * @param m The mask to compare against. + * @return True if m & table[c] is true, false otherwise. + */ + inline bool + is(mask __m, char __c) const; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char in the range [lo, hi) and + * successively writes it to vec. vec must have as many elements as + * the char array. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + inline const char* + is(const char* __lo, const char* __hi, mask* __vec) const; + + /** + * @brief Find char matching a mask + * + * This function searches for and returns the first char in [lo,hi) for + * which is(m,char) is true. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char if found, else @a hi. + */ + inline const char* + scan_is(mask __m, const char* __lo, const char* __hi) const; + + /** + * @brief Find char not matching a mask + * + * This function searches for and returns a pointer to the first char + * in [lo,hi) for which is(m,char) is false. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char if found, else @a hi. + */ + inline const char* + scan_not(mask __m, const char* __lo, const char* __hi) const; + + /** + * @brief Convert to uppercase. + * + * This function converts the char argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * toupper() acts as if it returns ctype::do_toupper(c). + * do_toupper() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char in the range [lo,hi) to uppercase + * if possible. Other chars remain untouched. + * + * toupper() acts as if it returns ctype:: do_toupper(lo, hi). + * do_toupper() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the char argument to lowercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * tolower() acts as if it returns ctype::do_tolower(c). + * do_tolower() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char in the range [lo,hi) to lowercase + * if possible. Other chars remain untouched. + * + * tolower() acts as if it returns ctype:: do_tolower(lo, hi). + * do_tolower() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char + * + * This function converts the char to char_type using the simplest + * reasonable transformation. For an underived ctype facet, the + * argument will be returned unchanged. + * + * This function works as if it returns ctype::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + char_type + widen(char __c) const + { + if (_M_widen_ok) + return _M_widen[static_cast(__c)]; + this->_M_widen_init(); + return this->do_widen(__c); + } + + /** + * @brief Widen char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation. For an underived ctype + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { + if (_M_widen_ok == 1) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_widen_ok) + _M_widen_init(); + return this->do_widen(__lo, __hi, __to); + } + + /** + * @brief Narrow char + * + * This function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype facet, @a c + * will be returned unchanged. + * + * This function works as if it returns ctype::do_narrow(c). + * do_narrow() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted character. + */ + char + narrow(char_type __c, char __dfault) const + { + if (_M_narrow[static_cast(__c)]) + return _M_narrow[static_cast(__c)]; + const char __t = do_narrow(__c, __dfault); + if (__t != __dfault) + _M_narrow[static_cast(__c)] = __t; + return __t; + } + + /** + * @brief Narrow char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char in the input that cannot be + * converted, @a dfault is used instead. For an underived ctype + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype::do_narrow(lo, hi, + * dfault, to). do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { + if (__builtin_expect(_M_narrow_ok == 1, true)) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_narrow_ok) + _M_narrow_init(); + return this->do_narrow(__lo, __hi, __dfault, __to); + } + + protected: + /// Returns a pointer to the mask table provided to the constructor, or + /// the default from classic_table() if none was provided. + const mask* + table() const throw() + { return _M_table; } + + /// Returns a pointer to the C locale mask table. + static const mask* + classic_table() throw(); + + /** + * @brief Destructor. + * + * This function deletes table() if @a del was true in the + * constructor. + */ + virtual + ~ctype(); + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char in the range [lo,hi) to + * uppercase if possible. Other chars remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the char argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char in the range [lo,hi) to + * lowercase if possible. Other chars remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Widen char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. For an underived ctype facet, the + * argument will be returned unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + virtual char_type + do_widen(char __c) const + { return __c; } + + /** + * @brief Widen char array + * + * This function converts each char in the range [lo,hi) to char using + * the simplest reasonable transformation. For an underived + * ctype facet, the argument will be copied unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + /** + * @brief Narrow char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype facet, @a c will be + * returned unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type __c, char) const + { return __c; } + + /** + * @brief Narrow char array to char array + * + * This virtual function converts each char in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any char in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype facet, the argument will be copied unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char, char* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + private: + + void _M_widen_init() const + { + char __tmp[sizeof(_M_widen)]; + for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) + __tmp[__i] = __i; + do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); + + _M_widen_ok = 1; + // Set _M_widen_ok to 2 if memcpy can't be used. + if (memcmp(__tmp, _M_widen, sizeof(_M_widen))) + _M_widen_ok = 2; + } + + // Fill in the narrowing cache and flag whether all values are + // valid or not. _M_narrow_ok is set to 2 if memcpy can't + // be used. + void _M_narrow_init() const + { + char __tmp[sizeof(_M_narrow)]; + for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) + __tmp[__i] = __i; + do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); + + _M_narrow_ok = 1; + if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow))) + _M_narrow_ok = 2; + else + { + // Deal with the special case of zero: renarrow with a + // different default and compare. + char __c; + do_narrow(__tmp, __tmp + 1, 1, &__c); + if (__c == 1) + _M_narrow_ok = 2; + } + } + }; + + template<> + const ctype& + use_facet >(const locale& __loc); + +#ifdef _GLIBCXX_USE_WCHAR_T + // 22.2.1.3 ctype specialization + /** + * @brief The ctype specialization. + * + * This class defines classification and conversion functions for the + * wchar_t type. It gets used by wchar_t streams for many I/O operations. + * The wchar_t specialization provides a number of optimizations as well. + * + * ctype inherits its public methods from + * __ctype_abstract_base. + */ + template<> + class ctype : public __ctype_abstract_base + { + public: + // Types: + /// Typedef for the template parameter wchar_t. + typedef wchar_t char_type; + typedef wctype_t __wmask_type; + + protected: + __c_locale _M_c_locale_ctype; + + // Pre-computed narrowed and widened chars. + bool _M_narrow_ok; + char _M_narrow[128]; + wint_t _M_widen[1 + static_cast(-1)]; + + // Pre-computed elements for do_is. + mask _M_bit[16]; + __wmask_type _M_wmask[16]; + + public: + // Data Members: + /// The facet id for ctype + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + ctype(size_t __refs = 0); + + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, size_t __refs = 0); + + protected: + __wmask_type + _M_convert_to_wmask(const mask __m) const; + + /// Destructor + virtual + ~ctype(); + + /** + * @brief Test wchar_t classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The wchar_t to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool + do_is(mask __m, char_type __c) const; + + /** + * @brief Return a mask array. + * + * This function finds the mask for each wchar_t in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ + virtual const char_type* + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + + /** + * @brief Find wchar_t matching mask + * + * This function searches for and returns the first wchar_t c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching wchar_t if found, else @a hi. + */ + virtual const char_type* + do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + + /** + * @brief Find wchar_t not matching mask + * + * This function searches for and returns a pointer to the first + * wchar_t c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching wchar_t if found, else @a hi. + */ + virtual const char_type* + do_scan_not(mask __m, const char_type* __lo, + const char_type* __hi) const; + + /** + * @brief Convert to uppercase. + * + * This virtual function converts the wchar_t argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The uppercase wchar_t if convertible, else @a c. + */ + virtual char_type + do_toupper(char_type) const; + + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_toupper(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The lowercase wchar_t if convertible, else @a c. + */ + virtual char_type + do_tolower(char_type) const; + + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + virtual const char_type* + do_tolower(char_type* __lo, const char_type* __hi) const; + + /** + * @brief Widen char to wchar_t + * + * This virtual function converts the char to wchar_t using the + * simplest reasonable transformation. For an underived ctype + * facet, the argument will be cast to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted wchar_t. + */ + virtual char_type + do_widen(char) const; + + /** + * @brief Widen char array to wchar_t array + * + * This function converts each char in the input to wchar_t using the + * simplest reasonable transformation. For an underived ctype + * facet, the argument will be copied, casting each element to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char* + do_widen(const char* __lo, const char* __hi, char_type* __dest) const; + + /** + * @brief Narrow wchar_t to char + * + * This virtual function converts the argument to char using + * the simplest reasonable transformation. If the conversion + * fails, dfault is returned instead. For an underived + * ctype facet, @a c will be cast to char and + * returned. + * + * do_narrow() is a hook for a derived facet to change the + * behavior of narrowing. do_narrow() must always return the + * same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The wchar_t to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type, char __dfault) const; + + /** + * @brief Narrow wchar_t array to char array + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any wchar_t in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype facet, the argument will be copied, casting each + * element to char. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + virtual const char_type* + do_narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char* __dest) const; + + // For use at construction time only. + void + _M_initialize_ctype(); + }; + + template<> + const ctype& + use_facet >(const locale& __loc); +#endif //_GLIBCXX_USE_WCHAR_T + + // Include host and configuration specific ctype inlines. + #include + + // 22.2.1.2 Template class ctype_byname + template + class ctype_byname : public ctype<_CharT> + { + public: + typedef _CharT char_type; + + explicit + ctype_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~ctype_byname() { }; + }; + + // 22.2.1.4 Class ctype_byname specializations. + template<> + ctype_byname::ctype_byname(const char*, size_t refs); + + template<> + ctype_byname::ctype_byname(const char*, size_t refs); + + // 22.2.1.5 Template class codecvt + #include + + // 22.2.2 The numeric category. + class __num_base + { + public: + // NB: Code depends on the order of _S_atoms_out elements. + // Below are the indices into _S_atoms_out. + enum + { + _S_ominus, + _S_oplus, + _S_ox, + _S_oX, + _S_odigits, + _S_odigits_end = _S_odigits + 16, + _S_oudigits = _S_odigits_end, + _S_oudigits_end = _S_oudigits + 16, + _S_oe = _S_odigits + 14, // For scientific notation, 'e' + _S_oE = _S_oudigits + 14, // For scientific notation, 'E' + _S_oend = _S_oudigits_end + }; + + // A list of valid numeric literals for output. This array + // contains chars that will be passed through the current locale's + // ctype<_CharT>.widen() and then used to render numbers. + // For the standard "C" locale, this is + // "-+xX0123456789abcdef0123456789ABCDEF". + static const char* _S_atoms_out; + + // String literal of acceptable (narrow) input, for num_get. + // "-+xX0123456789abcdefABCDEF" + static const char* _S_atoms_in; + + enum + { + _S_iminus, + _S_iplus, + _S_ix, + _S_iX, + _S_izero, + _S_ie = _S_izero + 14, + _S_iE = _S_izero + 20, + _S_iend = 26 + }; + + // num_put + // Construct and return valid scanf format for floating point types. + static void + _S_format_float(const ios_base& __io, char* __fptr, char __mod); + }; + + template + struct __numpunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + const _CharT* _M_truename; + size_t _M_truename_size; + const _CharT* _M_falsename; + size_t _M_falsename_size; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + + // A list of valid numeric literals for output: in the standard + // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_out[__num_base::_S_oend]; + + // A list of valid numeric literals for input: in the standard + // "C" locale, this is "-+xX0123456789abcdefABCDEF" + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_in[__num_base::_S_iend]; + + bool _M_allocated; + + __numpunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), + _M_falsename_size(0), _M_decimal_point(_CharT()), + _M_thousands_sep(_CharT()), _M_allocated(false) + { } + + ~__numpunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __numpunct_cache& + operator=(const __numpunct_cache&); + + explicit + __numpunct_cache(const __numpunct_cache&); + }; + + template + __numpunct_cache<_CharT>::~__numpunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_truename; + delete [] _M_falsename; + } + } + + /** + * @brief Numpunct facet. + * + * This facet stores several pieces of information related to printing and + * scanning numbers, such as the decimal point character. It takes a + * template parameter specifying the char type. The numpunct facet is + * used by streams for many I/O operations involving numbers. + * + * The numpunct template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from a numpunct facet. + */ + template + class numpunct : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __numpunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Numpunct constructor. + * + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up the + * predefined locale facets. + * + * @param cache __numpunct_cache object. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(__cloc); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * numpunct::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * numpunct::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of a number. Groupings indicate where thousands + * separators should be inserted in the integer part of a number. + * + * Each char in the return string is interpret as an integer + * rather than a character. These numbers represent the number + * of digits in a group. The first char in the string + * represents the number of digits in the least significant + * group. If a char is negative, it indicates an unlimited + * number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is + * applied to the number 123456789, this corresponds to + * 12,34,56,789. Note that if the string was "32", this would + * put more than 50 digits into the least significant group if + * the character set is ASCII. + * + * The string is returned by calling + * numpunct::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return string representation of bool true. + * + * This function returns a string_type containing the text + * representation for true bool variables. It does so by calling + * numpunct::do_truename(). + * + * @return string_type representing printed form of true. + */ + string_type + truename() const + { return this->do_truename(); } + + /** + * @brief Return string representation of bool false. + * + * This function returns a string_type containing the text + * representation for false bool variables. It does so by calling + * numpunct::do_falsename(). + * + * @return string_type representing printed form of false. + */ + string_type + falsename() const + { return this->do_falsename(); } + + protected: + /// Destructor. + virtual + ~numpunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return string representation of bool true. + * + * Returns a string_type containing the text representation for true + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of true. + */ + virtual string_type + do_truename() const + { return _M_data->_M_truename; } + + /** + * @brief Return string representation of bool false. + * + * Returns a string_type containing the text representation for false + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of false. + */ + virtual string_type + do_falsename() const + { return _M_data->_M_falsename; } + + // For use at construction time only. + void + _M_initialize_numpunct(__c_locale __cloc = NULL); + }; + + template + locale::id numpunct<_CharT>::id; + + template<> + numpunct::~numpunct(); + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale __cloc); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + numpunct::~numpunct(); + + template<> + void + numpunct::_M_initialize_numpunct(__c_locale __cloc); +#endif + + template + class numpunct_byname : public numpunct<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + numpunct_byname(const char* __s, size_t __refs = 0) + : numpunct<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_numpunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~numpunct_byname() { } + }; + + /** + * @brief Facet for parsing number strings. + * + * This facet encapsulates the code to parse and return a number + * from a string. It is used by the istream numeric extraction + * operators. + * + * The num_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_get facet. + */ + template + class num_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the bool @a v. It does so by calling + * num_put::do_put(). + * + * If ios_base::boolalpha is set, attempts to read + * ctype::truename() or ctype::falsename(). Sets + * @a v to true or false if successful. Sets err to + * ios_base::failbit if reading the string fails. Sets err to + * ios_base::eofbit if the stream is emptied. + * + * If ios_base::boolalpha is not set, proceeds as with reading a long, + * except if the value is 1, sets @a v to true, if the value is 0, sets + * @a v to false, and otherwise set err to ios_base::failbit. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_put::do_put(). + * + * Parsing is affected by the flag settings in @a io. + * + * The basic parse is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, parses like the + * scanf %o specifier. Else if equal to ios_base::hex, parses like %X + * specifier. Else if basefield equal to 0, parses like the %i + * specifier. Otherwise, parses like %d for signed and %u for unsigned + * types. The matching type length modifier is also used. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } +#endif + //@} + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_put::do_put(). + * + * The input characters are parsed like the scanf %g specifier. The + * matching type length modifier is also used. + * + * The decimal point character used is numpunct::decimal_point(). + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + //@} + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the pointer variable @a v. It does so + * by calling num_put::do_put(). + * + * The input characters are parsed like the scanf %p specifier. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * Note that the digit grouping effect for pointers is a bit ambiguous + * in the standard and shouldn't be relied on. See DR 344. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type + get(iter_type __in, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { return this->do_get(__in, __end, __io, __err, __v); } + + protected: + /// Destructor. + virtual ~num_get() { } + + iter_type + _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, + string& __xtrc) const; + + template + iter_type + _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, + _ValueT& __v) const; + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the variable @a v. This function is a + * hook for derived classes to change the value returned. @see get() + * for more details. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; + + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned short&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned int&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned long&) const; + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long long&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + unsigned long long&) const; +#endif + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + float&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + double&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + long double&) const; + + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + void*&) const; + //@} + }; + + template + locale::id num_get<_CharT, _InIter>::id; + + + /** + * @brief Facet for converting numbers to strings. + * + * This facet encapsulates the code to convert a number to a string. It is + * used by the ostream numeric insertion operators. + * + * The num_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_put facet. + */ + template + class num_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric formatting. + * + * Formats the boolean @a v and inserts it into a stream. It does so + * by calling num_put::do_put(). + * + * If ios_base::boolalpha is set, writes ctype::truename() or + * ctype::falsename(). Otherwise formats @a v as an int. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const + { return this->do_put(__s, __f, __fill, __v); } + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the integral value @a v and inserts it into a + * stream. It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, formats like the + * printf %o specifier. Else if equal to ios_base::hex, formats like + * %x or %X with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu + * for unsigned values. Note that if both oct and hex are set, neither + * will take effect. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showbase is set, '0' precedes octal values (except 0) + * and '0[xX]' precedes hex values. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long __v) const + { return this->do_put(__s, __f, __fill, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + unsigned long long __v) const + { return this->do_put(__s, __f, __fill, __v); } +#endif + //@} + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the floating point value @a v and inserts it into a stream. + * It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::floatfield. If equal to ios_base::fixed, formats like the + * printf %f specifier. Else if equal to ios_base::scientific, formats + * like %e or %E with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %g or %G depending on uppercase. Note that + * if both fixed and scientific are set, the effect will also be like + * %g or %G. + * + * The output precision is given by io.precision(). This precision is + * capped at numeric_limits::digits10 + 2 (different for double and + * long double). The default precision is 6. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showpoint is set, a decimal point will always be + * output. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, double __v) const + { return this->do_put(__s, __f, __fill, __v); } + + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + long double __v) const + { return this->do_put(__s, __f, __fill, __v); } + //@} + + /** + * @brief Numeric formatting. + * + * Formats the pointer value @a v and inserts it into a stream. It + * does so by calling num_put::do_put(). + * + * This function formats @a v as an unsigned long with ios_base::hex + * and ios_base::showbase set. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, + const void* __v) const + { return this->do_put(__s, __f, __fill, __v); } + + protected: + template + iter_type + _M_insert_float(iter_type, ios_base& __io, char_type __fill, + char __mod, _ValueT __v) const; + + void + _M_group_float(const char* __grouping, size_t __grouping_size, + char_type __sep, const char_type* __p, char_type* __new, + char_type* __cs, int& __len) const; + + template + iter_type + _M_insert_int(iter_type, ios_base& __io, char_type __fill, + _ValueT __v) const; + + void + _M_group_int(const char* __grouping, size_t __grouping_size, + char_type __sep, ios_base& __io, char_type* __new, + char_type* __cs, int& __len) const; + + void + _M_pad(char_type __fill, streamsize __w, ios_base& __io, + char_type* __new, const char_type* __cs, int& __len) const; + + /// Destructor. + virtual + ~num_put() { }; + + //@{ + /** + * @brief Numeric formatting. + * + * These functions do the work of formatting numeric values and + * inserting them into a stream. This function is a hook for derived + * classes to change the value returned. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, bool __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; + +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long long __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; +#endif + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, double __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, long double __v) const; + + virtual iter_type + do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; + //@} + }; + + template + locale::id num_put<_CharT, _OutIter>::id; + + + /** + * @brief Facet for localized string comparison. + * + * This facet encapsulates the code to compare strings in a localized + * manner. + * + * The collate template uses protected virtual functions to provide + * the actual results. The public accessors forward the call to + * the virtual functions. These virtual functions are hooks for + * developers to implement the behavior they require from the + * collate facet. + */ + template + class collate : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by collate_byname as well. + __c_locale _M_c_locale_collate; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + collate(size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) + { } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Passed to the base facet class. + */ + explicit + collate(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) + { } + + /** + * @brief Compare two strings. + * + * This function compares two strings and returns the result by calling + * collate::do_compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + int + compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } + + /** + * @brief Transform string to comparable form. + * + * This function is a wrapper for strxfrm functionality. It takes the + * input string and returns a modified string that can be directly + * compared to other transformed strings. In the "C" locale, this + * function just returns a copy of the input string. In some other + * locales, it may replace two chars with one, change a char for + * another, etc. It does so by returning collate::do_transform(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Transformed string_type. + */ + string_type + transform(const _CharT* __lo, const _CharT* __hi) const + { return this->do_transform(__lo, __hi); } + + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. It + * does so by returning collate::do_hash(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + long + hash(const _CharT* __lo, const _CharT* __hi) const + { return this->do_hash(__lo, __hi); } + + // Used to abstract out _CharT bits in virtual member functions, below. + int + _M_compare(const _CharT*, const _CharT*) const; + + size_t + _M_transform(_CharT*, const _CharT*, size_t) const; + + protected: + /// Destructor. + virtual + ~collate() + { _S_destroy_c_locale(_M_c_locale_collate); } + + /** + * @brief Compare two strings. + * + * This function is a hook for derived classes to change the value + * returned. @see compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual int + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const; + + /** + * @brief Transform string to comparable form. + * + * This function is a hook for derived classes to change the value + * returned. + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual string_type + do_transform(const _CharT* __lo, const _CharT* __hi) const; + + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. This + * function is a hook for derived classes to change the value returned. + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + virtual long + do_hash(const _CharT* __lo, const _CharT* __hi) const; + }; + + template + locale::id collate<_CharT>::id; + + // Specializations. + template<> + int + collate::_M_compare(const char*, const char*) const; + + template<> + size_t + collate::_M_transform(char*, const char*, size_t) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + int + collate::_M_compare(const wchar_t*, const wchar_t*) const; + + template<> + size_t + collate::_M_transform(wchar_t*, const wchar_t*, size_t) const; +#endif + + template + class collate_byname : public collate<_CharT> + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + explicit + collate_byname(const char* __s, size_t __refs = 0) + : collate<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_collate); + this->_S_create_c_locale(this->_M_c_locale_collate, __s); + } + } + + protected: + virtual + ~collate_byname() { } + }; + + + /** + * @brief Time format ordering data. + * + * This class provides an enum representing different orderings of day, + * month, and year. + */ + class time_base + { + public: + enum dateorder { no_order, dmy, mdy, ymd, ydm }; + }; + + template + struct __timepunct_cache : public locale::facet + { + // List of all known timezones, with GMT first. + static const _CharT* _S_timezones[14]; + + const _CharT* _M_date_format; + const _CharT* _M_date_era_format; + const _CharT* _M_time_format; + const _CharT* _M_time_era_format; + const _CharT* _M_date_time_format; + const _CharT* _M_date_time_era_format; + const _CharT* _M_am; + const _CharT* _M_pm; + const _CharT* _M_am_pm_format; + + // Day names, starting with "C"'s Sunday. + const _CharT* _M_day1; + const _CharT* _M_day2; + const _CharT* _M_day3; + const _CharT* _M_day4; + const _CharT* _M_day5; + const _CharT* _M_day6; + const _CharT* _M_day7; + + // Abbreviated day names, starting with "C"'s Sun. + const _CharT* _M_aday1; + const _CharT* _M_aday2; + const _CharT* _M_aday3; + const _CharT* _M_aday4; + const _CharT* _M_aday5; + const _CharT* _M_aday6; + const _CharT* _M_aday7; + + // Month names, starting with "C"'s January. + const _CharT* _M_month01; + const _CharT* _M_month02; + const _CharT* _M_month03; + const _CharT* _M_month04; + const _CharT* _M_month05; + const _CharT* _M_month06; + const _CharT* _M_month07; + const _CharT* _M_month08; + const _CharT* _M_month09; + const _CharT* _M_month10; + const _CharT* _M_month11; + const _CharT* _M_month12; + + // Abbreviated month names, starting with "C"'s Jan. + const _CharT* _M_amonth01; + const _CharT* _M_amonth02; + const _CharT* _M_amonth03; + const _CharT* _M_amonth04; + const _CharT* _M_amonth05; + const _CharT* _M_amonth06; + const _CharT* _M_amonth07; + const _CharT* _M_amonth08; + const _CharT* _M_amonth09; + const _CharT* _M_amonth10; + const _CharT* _M_amonth11; + const _CharT* _M_amonth12; + + bool _M_allocated; + + __timepunct_cache(size_t __refs = 0) : facet(__refs), + _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), + _M_time_era_format(NULL), _M_date_time_format(NULL), + _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), + _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), + _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), + _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), + _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), + _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), + _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), + _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), + _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), + _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), + _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), + _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) + { } + + ~__timepunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __timepunct_cache& + operator=(const __timepunct_cache&); + + explicit + __timepunct_cache(const __timepunct_cache&); + }; + + template + __timepunct_cache<_CharT>::~__timepunct_cache() + { + if (_M_allocated) + { + // Unused. + } + } + + // Specializations. + template<> + const char* + __timepunct_cache::_S_timezones[14]; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + const wchar_t* + __timepunct_cache::_S_timezones[14]; +#endif + + // Generic. + template + const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; + + template + class __timepunct : public locale::facet + { + public: + // Types: + typedef _CharT __char_type; + typedef basic_string<_CharT> __string_type; + typedef __timepunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + __c_locale _M_c_locale_timepunct; + const char* _M_name_timepunct; + + public: + /// Numpunct facet id. + static locale::id id; + + explicit + __timepunct(size_t __refs = 0); + + explicit + __timepunct(__cache_type* __cache, size_t __refs = 0); + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); + + void + _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, + const tm* __tm) const; + + void + _M_date_formats(const _CharT** __date) const + { + // Always have default first. + __date[0] = _M_data->_M_date_format; + __date[1] = _M_data->_M_date_era_format; + } + + void + _M_time_formats(const _CharT** __time) const + { + // Always have default first. + __time[0] = _M_data->_M_time_format; + __time[1] = _M_data->_M_time_era_format; + } + + void + _M_date_time_formats(const _CharT** __dt) const + { + // Always have default first. + __dt[0] = _M_data->_M_date_time_format; + __dt[1] = _M_data->_M_date_time_era_format; + } + + void + _M_am_pm_format(const _CharT* __ampm) const + { __ampm = _M_data->_M_am_pm_format; } + + void + _M_am_pm(const _CharT** __ampm) const + { + __ampm[0] = _M_data->_M_am; + __ampm[1] = _M_data->_M_pm; + } + + void + _M_days(const _CharT** __days) const + { + __days[0] = _M_data->_M_day1; + __days[1] = _M_data->_M_day2; + __days[2] = _M_data->_M_day3; + __days[3] = _M_data->_M_day4; + __days[4] = _M_data->_M_day5; + __days[5] = _M_data->_M_day6; + __days[6] = _M_data->_M_day7; + } + + void + _M_days_abbreviated(const _CharT** __days) const + { + __days[0] = _M_data->_M_aday1; + __days[1] = _M_data->_M_aday2; + __days[2] = _M_data->_M_aday3; + __days[3] = _M_data->_M_aday4; + __days[4] = _M_data->_M_aday5; + __days[5] = _M_data->_M_aday6; + __days[6] = _M_data->_M_aday7; + } + + void + _M_months(const _CharT** __months) const + { + __months[0] = _M_data->_M_month01; + __months[1] = _M_data->_M_month02; + __months[2] = _M_data->_M_month03; + __months[3] = _M_data->_M_month04; + __months[4] = _M_data->_M_month05; + __months[5] = _M_data->_M_month06; + __months[6] = _M_data->_M_month07; + __months[7] = _M_data->_M_month08; + __months[8] = _M_data->_M_month09; + __months[9] = _M_data->_M_month10; + __months[10] = _M_data->_M_month11; + __months[11] = _M_data->_M_month12; + } + + void + _M_months_abbreviated(const _CharT** __months) const + { + __months[0] = _M_data->_M_amonth01; + __months[1] = _M_data->_M_amonth02; + __months[2] = _M_data->_M_amonth03; + __months[3] = _M_data->_M_amonth04; + __months[4] = _M_data->_M_amonth05; + __months[5] = _M_data->_M_amonth06; + __months[6] = _M_data->_M_amonth07; + __months[7] = _M_data->_M_amonth08; + __months[8] = _M_data->_M_amonth09; + __months[9] = _M_data->_M_amonth10; + __months[10] = _M_data->_M_amonth11; + __months[11] = _M_data->_M_amonth12; + } + + protected: + virtual + ~__timepunct(); + + // For use at construction time only. + void + _M_initialize_timepunct(__c_locale __cloc = NULL); + }; + + template + locale::id __timepunct<_CharT>::id; + + // Specializations. + template<> + void + __timepunct::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct::_M_put(char*, size_t, const char*, const tm*) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + void + __timepunct::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct::_M_put(wchar_t*, size_t, const wchar_t*, + const tm*) const; +#endif + + // Include host and configuration specific timepunct functions. + #include + + /** + * @brief Facet for parsing dates and times. + * + * This facet encapsulates the code to parse and return a date or + * time from a string. It is used by the istream numeric + * extraction operators. + * + * The time_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_get facet. + */ + template + class time_get : public locale::facet, public time_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + typedef basic_string<_CharT> __string_type; + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_get(size_t __refs = 0) + : facet (__refs) { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. If the format "x" for the associated + * locale uses other fields, this function returns + * timebase::dateorder::noorder. + * + * NOTE: The library always returns noorder at the moment. + * + * @return A member of timebase::dateorder. + */ + dateorder + date_order() const + { return this->do_date_order(); } + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_time(). + * + * If there is a valid time string according to format "x", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the time string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + iter_type + get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_time(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_date(). + * + * If there is a valid date string according to format "X", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the date string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + iter_type + get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_date(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_weekday(). + * + * Parsing starts by parsing an abbreviated weekday name. If a valid + * abbreviation is followed by a character that would lead to the full + * weekday name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + iter_type + get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_monthname(). + * + * Parsing starts by parsing an abbreviated month name. If a valid + * abbreviation is followed by a character that would lead to the full + * month name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= + * ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + iter_type + get_monthname(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. The result is + * returned by calling time_get::do_get_year(). + * + * 4 consecutive digits are interpreted as a full year. If there are + * exactly 2 consecutive digits, the library interprets this as the + * number of years since 1900. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + iter_type + get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_year(__beg, __end, __io, __err, __tm); } + + protected: + /// Destructor. + virtual + ~time_get() { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. This function is a hook for derived + * classes to change the value returned. + * + * @return A member of timebase::dateorder. + */ + virtual dateorder + do_date_order() const; + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_time() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + virtual iter_type + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_date() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + virtual iter_type + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_weekday() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + virtual iter_type + do_get_weekday(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_monthname() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + virtual iter_type + do_get_monthname(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. This function is a + * hook for derived classes to change the value returned. @see + * get_year() for details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + virtual iter_type + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + // Extract numeric component of length __len. + iter_type + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract day or month name, or any unique array of string + // literals in a const _CharT* array. + iter_type + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract on a component-by-component basis, via __format argument. + iter_type + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const; + }; + + template + locale::id time_get<_CharT, _InIter>::id; + + template + class time_get_byname : public time_get<_CharT, _InIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + + explicit + time_get_byname(const char*, size_t __refs = 0) + : time_get<_CharT, _InIter>(__refs) { } + + protected: + virtual + ~time_get_byname() { } + }; + + /** + * @brief Facet for outputting dates and times. + * + * This facet encapsulates the code to format and output dates and times + * according to formats used by strftime(). + * + * The time_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_put facet. + */ + template + class time_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_put(size_t __refs = 0) + : facet(__refs) { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format string. The format string is interpreted as by + * strftime(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param beg Start of format string. + * @param end End of format string. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const; + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. The format and modifier + * are interpreted as by strftime(). It does so by returning + * time_put::do_put(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + const tm* __tm, char __format, char __mod = 0) const + { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } + + protected: + /// Destructor. + virtual + ~time_put() + { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. This function is a hook + * for derived classes to change the value returned. @see put() for + * more details. + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + char __format, char __mod) const; + }; + + template + locale::id time_put<_CharT, _OutIter>::id; + + template + class time_put_byname : public time_put<_CharT, _OutIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _OutIter iter_type; + + explicit + time_put_byname(const char*, size_t __refs = 0) + : time_put<_CharT, _OutIter>(__refs) + { }; + + protected: + virtual + ~time_put_byname() { } + }; + + + /** + * @brief Money format ordering data. + * + * This class contains an ordered array of 4 fields to represent the + * pattern for formatting a money amount. Each field may contain one entry + * from the part enum. symbol, sign, and value must be present and the + * remaining field must contain either none or space. @see + * moneypunct::pos_format() and moneypunct::neg_format() for details of how + * these fields are interpreted. + */ + class money_base + { + public: + enum part { none, space, symbol, sign, value }; + struct pattern { char field[4]; }; + + static const pattern _S_default_pattern; + + enum + { + _S_minus, + _S_zero, + _S_end = 11 + }; + + // String literal of acceptable (narrow) input/output, for + // money_get/money_put. "-0123456789" + static const char* _S_atoms; + + // Construct and return valid pattern consisting of some combination of: + // space none symbol sign value + static pattern + _S_construct_pattern(char __precedes, char __space, char __posn); + }; + + template + struct __moneypunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + const _CharT* _M_curr_symbol; + size_t _M_curr_symbol_size; + const _CharT* _M_positive_sign; + size_t _M_positive_sign_size; + const _CharT* _M_negative_sign; + size_t _M_negative_sign_size; + int _M_frac_digits; + money_base::pattern _M_pos_format; + money_base::pattern _M_neg_format; + + // A list of valid numeric literals for input and output: in the standard + // "C" locale, this is "-0123456789". This array contains the chars after + // having been passed through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms[money_base::_S_end]; + + bool _M_allocated; + + __moneypunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), + _M_curr_symbol(NULL), _M_curr_symbol_size(0), + _M_positive_sign(NULL), _M_positive_sign_size(0), + _M_negative_sign(NULL), _M_negative_sign_size(0), + _M_frac_digits(0), + _M_pos_format(money_base::pattern()), + _M_neg_format(money_base::pattern()), _M_allocated(false) + { } + + ~__moneypunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __moneypunct_cache& + operator=(const __moneypunct_cache&); + + explicit + __moneypunct_cache(const __moneypunct_cache&); + }; + + template + __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_curr_symbol; + delete [] _M_positive_sign; + delete [] _M_negative_sign; + } + } + + /** + * @brief Facet for formatting data for money amounts. + * + * This facet encapsulates the punctuation, grouping and other formatting + * features of money amount string representations. + */ + template + class moneypunct : public locale::facet, public money_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + private: + __cache_type* _M_data; + + public: + /// This value is provided by the standard, but no reason for its + /// existence. + static const bool intl = _Intl; + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(); } + + /** + * @brief Constructor performs initialization. + * + * This is an internal constructor. + * + * @param cache Cache for optimization. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_moneypunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(__cloc, __s); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * moneypunct::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * moneypunct::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of an amount. Groupings indicate where thousands + * separators should be inserted. + * + * Each char in the return string is interpret as an integer rather + * than a character. These numbers represent the number of digits in a + * group. The first char in the string represents the number of digits + * in the least significant group. If a char is negative, it indicates + * an unlimited number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is applied to + * the number 123456789, this corresponds to 12,34,56,789. Note that + * if the string was "32", this would put more than 50 digits into the + * least significant group if the character set is ASCII. + * + * The string is returned by calling + * moneypunct::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. It + * does so by returning returning + * moneypunct::do_curr_symbol(). + * + * @return @a string_type representing a currency symbol. + */ + string_type + curr_symbol() const + { return this->do_curr_symbol(); } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. It does so by returning returning + * moneypunct::do_positive_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by pos_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a positive sign. + */ + string_type + positive_sign() const + { return this->do_positive_sign(); } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. It does so by returning returning + * moneypunct::do_negative_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by neg_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a negative sign. + */ + string_type + negative_sign() const + { return this->do_negative_sign(); } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. It does so by returning + * returning moneypunct::do_frac_digits(). + * + * The fractional part of a money amount is optional. But if it is + * present, there must be frac_digits() digits. + * + * @return Number of digits in amount fraction. + */ + int + frac_digits() const + { return this->do_frac_digits(); } + + //@{ + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive or negative valued money amount. It does so by returning + * returning moneypunct::do_pos_format() or + * moneypunct::do_neg_format(). + * + * The pattern has 4 fields describing the ordering of symbol, sign, + * value, and none or space. There must be one of each in the pattern. + * The none and space enums may not appear in the first field and space + * may not appear in the final field. + * + * The parts of a money string must appear in the order indicated by + * the fields of the pattern. The symbol field indicates that the + * value of curr_symbol() may be present. The sign field indicates + * that the value of positive_sign() or negative_sign() must be + * present. The value field indicates that the absolute value of the + * money amount is present. none indicates 0 or more whitespace + * characters, except at the end, where it permits no whitespace. + * space indicates that 1 or more whitespace characters must be + * present. + * + * For example, for the US locale and pos_format() pattern + * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == + * '+', and value 10.01, and options set to force the symbol, the + * corresponding string is "$+10.01". + * + * @return Pattern for money values. + */ + pattern + pos_format() const + { return this->do_pos_format(); } + + pattern + neg_format() const + { return this->do_neg_format(); } + //@} + + protected: + /// Destructor. + virtual + ~moneypunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. + * This function is a hook for derived classes to change the value + * returned. @see curr_symbol() for details. + * + * @return @a string_type representing a currency symbol. + */ + virtual string_type + do_curr_symbol() const + { return _M_data->_M_curr_symbol; } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. This function is a hook for derived classes to change the + * value returned. @see positive_sign() for details. + * + * @return @a string_type representing a positive sign. + */ + virtual string_type + do_positive_sign() const + { return _M_data->_M_positive_sign; } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. This function is a hook for derived classes to change the + * value returned. @see negative_sign() for details. + * + * @return @a string_type representing a negative sign. + */ + virtual string_type + do_negative_sign() const + { return _M_data->_M_negative_sign; } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. This function is a hook for + * derived classes to change the value returned. @see frac_digits() + * for details. + * + * @return Number of digits in amount fraction. + */ + virtual int + do_frac_digits() const + { return _M_data->_M_frac_digits; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive valued money amount. This function is a hook for derived + * classes to change the value returned. @see pos_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_pos_format() const + { return _M_data->_M_pos_format; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * negative valued money amount. This function is a hook for derived + * classes to change the value returned. @see neg_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_neg_format() const + { return _M_data->_M_neg_format; } + + // For use at construction time only. + void + _M_initialize_moneypunct(__c_locale __cloc = NULL, + const char* __name = NULL); + }; + + template + locale::id moneypunct<_CharT, _Intl>::id; + + template + const bool moneypunct<_CharT, _Intl>::intl; + + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); +#endif + + template + class moneypunct_byname : public moneypunct<_CharT, _Intl> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + static const bool intl = _Intl; + + explicit + moneypunct_byname(const char* __s, size_t __refs = 0) + : moneypunct<_CharT, _Intl>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_moneypunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~moneypunct_byname() { } + }; + + template + const bool moneypunct_byname<_CharT, _Intl>::intl; + + /** + * @brief Facet for parsing monetary amounts. + * + * This facet encapsulates the code to parse and return a monetary + * amount from a string. + * + * The money_get template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_get facet. + */ + template + class money_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a units as an integral + * value moneypunct::frac_digits() * the actual amount. For example, + * the string $10.01 in a US locale would store 1001 in @a units. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). @a units is + * unchanged if parsing fails. + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param units Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { return this->do_get(__s, __end, __intl, __io, __err, __units); } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a digits. For example, + * the string $10.01 in a US locale would store "1001" in @a digits. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param digits Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const + { return this->do_get(__s, __end, __intl, __io, __err, __digits); } + + protected: + /// Destructor. + virtual + ~money_get() { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const; + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const; + + template + iter_type + _M_extract(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __digits) const; + }; + + template + locale::id money_get<_CharT, _InIter>::id; + + /** + * @brief Facet for outputting monetary amounts. + * + * This facet encapsulates the code to format and output a monetary + * amount. + * + * The money_put template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_put facet. + */ + template + class money_put : public locale::facet + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, long double __units) const + { return this->do_put(__s, __intl, __io, __fill, __units); } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, const string_type& __digits) const + { return this->do_put(__s, __intl, __io, __fill, __digits); } + + protected: + /// Destructor. + virtual + ~money_put() { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const; + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const; + + template + iter_type + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const; + }; + + template + locale::id money_put<_CharT, _OutIter>::id; + + /** + * @brief Messages facet base class providing catalog typedef. + */ + struct messages_base + { + typedef int catalog; + }; + + /** + * @brief Facet for handling message catalogs + * + * This facet encapsulates the code to retrieve messages from + * message catalogs. The only thing defined by the standard for this facet + * is the interface. All underlying functionality is + * implementation-defined. + * + * This library currently implements 3 versions of the message facet. The + * first version (gnu) is a wrapper around gettext, provided by libintl. + * The second version (ieee) is a wrapper around catgets. The final + * version (default) does no actual translation. These implementations are + * only provided for char and wchar_t instantiations. + * + * The messages template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the messages facet. + */ + template + class messages : public locale::facet, public messages_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by messages_byname as well. + __c_locale _M_c_locale_messages; + const char* _M_name_messages; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + messages(size_t __refs = 0); + + // Non-standard. + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Refcount to pass to the base class. + */ + explicit + messages(__c_locale __cloc, const char* __s, size_t __refs = 0); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog by + * returning do_open(s, loc). + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string& __s, const locale& __loc) const + { return this->do_open(__s, __loc); } + + // Non-standard and unorthodox, yet effective. + /* + * @brief Open a message catalog. + * + * This non-standard function opens and returns a handle to a message + * catalog by returning do_open(s, loc). The third argument provides a + * message catalog root directory for gnu gettext and is ignored + * otherwise. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @param dir Message catalog root directory. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string&, const locale&, const char*) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog by + * returning do_get(c, set, msgid, s). + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + string_type + get(catalog __c, int __set, int __msgid, const string_type& __s) const + { return this->do_get(__c, __set, __msgid, __s); } + + /* + * @brief Close a message catalog. + * + * Closes catalog @a c by calling do_close(c). + * + * @param c The catalog to close. + */ + void + close(catalog __c) const + { return this->do_close(__c); } + + protected: + /// Destructor. + virtual + ~messages(); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the opened catalog, value < 0 if open failed. + */ + virtual catalog + do_open(const basic_string&, const locale&) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + virtual string_type + do_get(catalog, int, int, const string_type& __dfault) const; + + /* + * @brief Close a message catalog. + * + * @param c The catalog to close. + */ + virtual void + do_close(catalog) const; + + // Returns a locale and codeset-converted string, given a char* message. + char* + _M_convert_to_char(const string_type& __msg) const + { + // XXX + return reinterpret_cast(const_cast<_CharT*>(__msg.c_str())); + } + + // Returns a locale and codeset-converted string, given a char* message. + string_type + _M_convert_from_char(char*) const + { +#if 0 + // Length of message string without terminating null. + size_t __len = char_traits::length(__msg) - 1; + + // "everybody can easily convert the string using + // mbsrtowcs/wcsrtombs or with iconv()" + + // Convert char* to _CharT in locale used to open catalog. + // XXX need additional template parameter on messages class for this.. + // typedef typename codecvt __codecvt_type; + typedef typename codecvt __codecvt_type; + + __codecvt_type::state_type __state; + // XXX may need to initialize state. + //initialize_state(__state._M_init()); + + char* __from_next; + // XXX what size for this string? + _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); + __cvt.out(__state, __msg, __msg + __len, __from_next, + __to, __to + __len + 1, __to_next); + return string_type(__to); +#endif +#if 0 + typedef ctype<_CharT> __ctype_type; + // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); + const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); + // XXX Again, proper length of converted string an issue here. + // For now, assume the converted length is not larger. + _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + __cvt.widen(__msg, __msg + __len, __dest); + return basic_string<_CharT>(__dest); +#endif + return string_type(); + } + }; + + template + locale::id messages<_CharT>::id; + + // Specializations for required instantiations. + template<> + string + messages::do_get(catalog, int, int, const string&) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + wstring + messages::do_get(catalog, int, int, const wstring&) const; +#endif + + template + class messages_byname : public messages<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + messages_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~messages_byname() + { } + }; + + // Include host and configuration specific messages functions. + #include + + + // Subclause convenience interfaces, inlines. + // NB: These are inline because, when used in a loop, some compilers + // can hoist the body out of the loop; then it's just as fast as the + // C is*() function. + //@{ + /// Convenience interface to ctype.is(). + template + inline bool + isspace(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::space, __c); } + + template + inline bool + isprint(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::print, __c); } + + template + inline bool + iscntrl(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::cntrl, __c); } + + template + inline bool + isupper(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::upper, __c); } + + template + inline bool islower(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::lower, __c); } + + template + inline bool + isalpha(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::alpha, __c); } + + template + inline bool + isdigit(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::digit, __c); } + + template + inline bool + ispunct(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::punct, __c); } + + template + inline bool + isxdigit(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::xdigit, __c); } + + template + inline bool + isalnum(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::alnum, __c); } + + template + inline bool + isgraph(_CharT __c, const locale& __loc) + { return use_facet >(__loc).is(ctype_base::graph, __c); } + + template + inline _CharT + toupper(_CharT __c, const locale& __loc) + { return use_facet >(__loc).toupper(__c); } + + template + inline _CharT + tolower(_CharT __c, const locale& __loc) + { return use_facet >(__loc).tolower(__c); } + //@} +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.tcc new file mode 100644 index 00000000000..4f6584432fa --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/locale_facets.tcc @@ -0,0 +1,2744 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Warning: this file is not meant for user inclusion. Use . + +#ifndef _LOCALE_FACETS_TCC +#define _LOCALE_FACETS_TCC 1 + +#pragma GCC system_header + +#include // For numeric_limits +#include // For bad_cast. +#include + +namespace std +{ + template + locale + locale::combine(const locale& __other) const + { + _Impl* __tmp = new _Impl(*_M_impl, 1); + try + { + __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + } + catch(...) + { + __tmp->_M_remove_reference(); + __throw_exception_again; + } + return locale(__tmp); + } + + template + bool + locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, + const basic_string<_CharT, _Traits, _Alloc>& __s2) const + { + typedef std::collate<_CharT> __collate_type; + const __collate_type& __collate = use_facet<__collate_type>(*this); + return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), + __s2.data(), __s2.data() + __s2.length()) < 0); + } + + /** + * @brief Test for the presence of a facet. + * + * has_facet tests the locale argument for the presence of the facet type + * provided as the template parameter. Facets derived from the facet + * parameter will also return true. + * + * @param Facet The facet type to test the presence of. + * @param locale The locale to test. + * @return true if locale contains a facet of type Facet, else false. + */ + template + inline bool + has_facet(const locale& __loc) throw() + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); + } + + /** + * @brief Return a facet. + * + * use_facet looks for and returns a reference to a facet of type Facet + * where Facet is the template parameter. If has_facet(locale) is true, + * there is a suitable facet to return. It throws std::bad_cast if the + * locale doesn't contain a facet of type Facet. + * + * @param Facet The facet type to access. + * @param locale The locale to use. + * @return Reference to facet of type Facet. + * @throw std::bad_cast if locale doesn't contain a facet of type Facet. + */ + template + inline const _Facet& + use_facet(const locale& __loc) + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) + __throw_bad_cast(); + return static_cast(*__facets[__i]); + } + + // Routine to access a cache for the facet. If the cache didn't + // exist before, it gets constructed on the fly. + template + struct __use_cache + { + const _Facet* + operator() (const locale& __loc) const; + }; + + // Specializations. + template + struct __use_cache<__numpunct_cache<_CharT> > + { + const __numpunct_cache<_CharT>* + operator() (const locale& __loc) const + { + const size_t __i = numpunct<_CharT>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __numpunct_cache<_CharT>* __tmp = NULL; + try + { + __tmp = new __numpunct_cache<_CharT>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast*>(__caches[__i]); + } + }; + + template + struct __use_cache<__moneypunct_cache<_CharT, _Intl> > + { + const __moneypunct_cache<_CharT, _Intl>* + operator() (const locale& __loc) const + { + const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; + try + { + __tmp = new __moneypunct_cache<_CharT, _Intl>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast< + const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); + } + }; + + template + void + __numpunct_cache<_CharT>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const numpunct<_CharT>& __np = use_facet >(__loc); + + _M_grouping_size = __np.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __np.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0; + + _M_truename_size = __np.truename().size(); + _CharT* __truename = new _CharT[_M_truename_size]; + __np.truename().copy(__truename, _M_truename_size); + _M_truename = __truename; + + _M_falsename_size = __np.falsename().size(); + _CharT* __falsename = new _CharT[_M_falsename_size]; + __np.falsename().copy(__falsename, _M_falsename_size); + _M_falsename = __falsename; + + _M_decimal_point = __np.decimal_point(); + _M_thousands_sep = __np.thousands_sep(); + + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(__num_base::_S_atoms_out, + __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); + __ct.widen(__num_base::_S_atoms_in, + __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); + } + + template + void + __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const moneypunct<_CharT, _Intl>& __mp = + use_facet >(__loc); + + _M_grouping_size = __mp.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __mp.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0; + + _M_decimal_point = __mp.decimal_point(); + _M_thousands_sep = __mp.thousands_sep(); + _M_frac_digits = __mp.frac_digits(); + + _M_curr_symbol_size = __mp.curr_symbol().size(); + _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; + __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); + _M_curr_symbol = __curr_symbol; + + _M_positive_sign_size = __mp.positive_sign().size(); + _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; + __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); + _M_positive_sign = __positive_sign; + + _M_negative_sign_size = __mp.negative_sign().size(); + _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; + __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); + _M_negative_sign = __negative_sign; + + _M_pos_format = __mp.pos_format(); + _M_neg_format = __mp.neg_format(); + + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(money_base::_S_atoms, + money_base::_S_atoms + money_base::_S_end, _M_atoms); + } + + + // Used by both numeric and monetary facets. + // Check to make sure that the __grouping_tmp string constructed in + // money_get or num_get matches the canonical grouping for a given + // locale. + // __grouping_tmp is parsed L to R + // 1,222,444 == __grouping_tmp of "\1\3\3" + // __grouping is parsed R to L + // 1,222,444 == __grouping of "\3" == "\3\3\3" + static bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp); + + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, string& __xtrc) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // True if a mantissa is found. + bool __found_mantissa = false; + + // First check for sign. + if (__beg != __end) + { + const char_type __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } + } + + // Next, look for leading zeros. + while (__beg != __end) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero]) + { + if (!__found_mantissa) + { + __xtrc += '0'; + __found_mantissa = true; + } + ++__beg; + } + else + break; + } + + // Only need acceptable digits for floating point numbers. + bool __found_dec = false; + bool __found_sci = false; + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + int __sep_pos = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + const char_type* __q; + while (__beg != __end) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (!__found_dec && !__found_sci) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + ++__beg; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else + break; + } + else if (__c == __lc->_M_decimal_point) + { + if (!__found_dec && !__found_sci) + { + // If no grouping chars are seen, no grouping check + // is applied. Therefore __found_grouping is adjusted + // only if decimal_point comes after some thousands_sep. + if (__found_grouping.size()) + __found_grouping += static_cast(__sep_pos); + __xtrc += '.'; + __found_dec = true; + ++__beg; + } + else + break; + } + else if (__q = __traits_type::find(__lit_zero, 10, __c)) + { + __xtrc += __num_base::_S_atoms_in[__q - __lit]; + __found_mantissa = true; + ++__sep_pos; + ++__beg; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && __found_mantissa && !__found_sci) + { + // Scientific notation. + if (__found_grouping.size() && !__found_dec) + __found_grouping += static_cast(__sep_pos); + __xtrc += 'e'; + __found_sci = true; + + // Remove optional plus or minus sign, if they exist. + if (++__beg != __end) + { + const bool __plus = *__beg == __lit[__num_base::_S_iplus]; + if ((__plus || *__beg == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep) + && !(*__beg == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } + } + } + else + // Not a valid input item. + break; + } + + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__lc->_M_use_grouping && __found_grouping.size()) + { + // Add the ending grouping if a decimal or 'e'/'E' wasn't found. + if (!__found_dec && !__found_sci) + __found_grouping += static_cast(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } + + // Finish up. + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, _ValueT& __v) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // NB: Iff __basefield == 0, __base can change based on contents. + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + const bool __oct = __basefield == ios_base::oct; + int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); + + // True if numeric digits are found. + bool __found_num = false; + + // First check for sign. + bool __negative = false; + if (__beg != __end) + { + const char_type __c = *__beg; + if (numeric_limits<_ValueT>::is_signed) + __negative = __c == __lit[__num_base::_S_iminus]; + if ((__negative || __c == __lit[__num_base::_S_iplus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + ++__beg; + } + + // Next, look for leading zeros and check required digits + // for base formats. + while (__beg != __end) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero] + && (!__found_num || __base == 10)) + { + __found_num = true; + ++__beg; + } + else if (__found_num) + { + if (__c == __lit[__num_base::_S_ix] + || __c == __lit[__num_base::_S_iX]) + { + if (__basefield == 0) + __base = 16; + if (__base == 16) + { + __found_num = false; + ++__beg; + } + } + else if (__basefield == 0) + __base = 8; + break; + } + else + break; + } + + // At this point, base is determined. If not hex, only allow + // base digits as valid input. + const size_t __len = __base == 16 ? (__num_base::_S_iend + - __num_base::_S_izero) + : __base; + + // Extract. + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + int __sep_pos = 0; + bool __overflow = false; + _ValueT __result = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + const char_type* __q; + if (__negative) + { + const _ValueT __min = numeric_limits<_ValueT>::min() / __base; + for (; __beg != __end; ++__beg) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else if (__q = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result < __min) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + - __digit; + __overflow |= __new_result > __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + // Not a valid input item. + break; + } + } + else + { + const _ValueT __max = numeric_limits<_ValueT>::max() / __base; + for (; __beg != __end; ++__beg) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else if (__q = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __max) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + + __digit; + __overflow |= __new_result < __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + break; + } + } + + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__lc->_M_use_grouping && __found_grouping.size()) + { + // Add the ending grouping. + __found_grouping += static_cast(__sep_pos); + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } + + if (!(__err & ios_base::failbit) && !__overflow + && __found_num) + __v = __result; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 17. Bad bool parsing + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, bool& __v) const + { + if (!(__io.flags() & ios_base::boolalpha)) + { + // Parse bool values as long. + // NB: We can't just call do_get(long) here, as it might + // refer to a derived class. + long __l = -1; + __beg = _M_extract_int(__beg, __end, __io, __err, __l); + if (__l == 0 || __l == 1) + __v = __l; + else + __err |= ios_base::failbit; + } + else + { + // Parse bool values as alphanumeric. + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + bool __testf = true; + bool __testt = true; + size_t __n; + for (__n = 0; __beg != __end; ++__n, ++__beg) + { + if (__testf) + if (__n < __lc->_M_falsename_size) + __testf = *__beg == __lc->_M_falsename[__n]; + else + break; + + if (__testt) + if (__n < __lc->_M_truename_size) + __testt = *__beg == __lc->_M_truename[__n]; + else + break; + + if (!__testf && !__testt) + break; + } + if (__testf && __n == __lc->_M_falsename_size) + __v = 0; + else if (__testt && __n == __lc->_M_truename_size) + __v = 1; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + } + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned short& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned int& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, unsigned long long& __v) const + { return _M_extract_int(__beg, __end, __io, __err, __v); } +#endif + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, float& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, long double& __v) const + { + string __xtrc; + __xtrc.reserve(32); + __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + num_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, void*& __v) const + { + // Prepare for hex formatted input. + typedef ios_base::fmtflags fmtflags; + const fmtflags __fmt = __io.flags(); + __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); + + unsigned long __ul; + __beg = _M_extract_int(__beg, __end, __io, __err, __ul); + + // Reset from hex formatted input. + __io.flags(__fmt); + + if (!(__err & ios_base::failbit)) + __v = reinterpret_cast(__ul); + else + __err |= ios_base::failbit; + return __beg; + } + + // For use by integer and floating-point types after they have been + // converted into a char_type string. + template + void + num_put<_CharT, _OutIter>:: + _M_pad(_CharT __fill, streamsize __w, ios_base& __io, + _CharT* __new, const _CharT* __cs, int& __len) const + { + // [22.2.2.2.2] Stage 3. + // If necessary, pad. + __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, + __w, __len, true); + __len = static_cast(__w); + } + + // Forwarding functions to peel signed from unsigned integer types. + template + inline int + __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + unsigned long __ul = static_cast(__v); + bool __neg = false; + if (__v < 0) + { + __ul = -__ul; + __neg = true; + } + return __int_to_char(__bufend, __ul, __lit, __flags, __neg); + } + + template + inline int + __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + // About showpos, see Table 60 and C99 7.19.6.1, p6 (+). + return __int_to_char(__bufend, __v, __lit, + __flags & ~ios_base::showpos, false); + } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + inline int + __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + unsigned long long __ull = static_cast(__v); + bool __neg = false; + if (__v < 0) + { + __ull = -__ull; + __neg = true; + } + return __int_to_char(__bufend, __ull, __lit, __flags, __neg); + } + + template + inline int + __int_to_char(_CharT* __bufend, unsigned long long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { return __int_to_char(__bufend, __v, __lit, + __flags & ~ios_base::showpos, false); } +#endif + + template + int + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __neg) + { + // Don't write base if already 0. + const bool __showbase = (__flags & ios_base::showbase) && __v; + const ios_base::fmtflags __basefield = __flags & ios_base::basefield; + _CharT* __buf = __bufend - 1; + + if (__builtin_expect(__basefield != ios_base::oct && + __basefield != ios_base::hex, true)) + { + // Decimal. + do + { + *__buf-- = __lit[(__v % 10) + __num_base::_S_odigits]; + __v /= 10; + } + while (__v != 0); + if (__neg) + *__buf-- = __lit[__num_base::_S_ominus]; + else if (__flags & ios_base::showpos) + *__buf-- = __lit[__num_base::_S_oplus]; + } + else if (__basefield == ios_base::oct) + { + // Octal. + do + { + *__buf-- = __lit[(__v & 0x7) + __num_base::_S_odigits]; + __v >>= 3; + } + while (__v != 0); + if (__showbase) + *__buf-- = __lit[__num_base::_S_odigits]; + } + else + { + // Hex. + const bool __uppercase = __flags & ios_base::uppercase; + const int __case_offset = __uppercase ? __num_base::_S_oudigits + : __num_base::_S_odigits; + do + { + *__buf-- = __lit[(__v & 0xf) + __case_offset]; + __v >>= 4; + } + while (__v != 0); + if (__showbase) + { + // 'x' or 'X' + *__buf-- = __lit[__num_base::_S_ox + __uppercase]; + // '0' + *__buf-- = __lit[__num_base::_S_odigits]; + } + } + return __bufend - __buf - 1; + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, + ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const + { + // By itself __add_grouping cannot deal correctly with __cs when + // ios::showbase is set and ios_base::oct || ios_base::hex. + // Therefore we take care "by hand" of the initial 0, 0x or 0X. + // However, remember that the latter do not occur if the number + // printed is '0' (__len == 1). + streamsize __off = 0; + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + if ((__io.flags() & ios_base::showbase) && __len > 1) + if (__basefield == ios_base::oct) + { + __off = 1; + __new[0] = __cs[0]; + } + else if (__basefield == ios_base::hex) + { + __off = 2; + __new[0] = __cs[0]; + __new[1] = __cs[1]; + } + _CharT* __p; + __p = std::__add_grouping(__new + __off, __sep, __grouping, + __grouping_size, __cs + __off, + __cs + __len); + __len = __p - __new; + } + + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_out; + + // Long enough to hold hex, dec, and octal representations. + const int __ilen = 4 * sizeof(_ValueT); + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __ilen)); + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + // Result is returned right-justified in the buffer. + int __len; + __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags()); + __cs += __ilen - __len; + + // Add grouping, if necessary. + if (__lc->_M_use_grouping) + { + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __io, __cs2, __cs, __len); + __cs = __cs2; + } + + // Pad. + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs3, __cs, __len); + __cs = __cs3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __cs, __len); + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_float(const char* __grouping, size_t __grouping_size, + _CharT __sep, const _CharT* __p, _CharT* __new, + _CharT* __cs, int& __len) const + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 282. What types does numpunct grouping refer to? + // Add grouping, if necessary. + _CharT* __p2; + const int __declen = __p ? __p - __cs : __len; + __p2 = std::__add_grouping(__new, __sep, __grouping, __grouping_size, + __cs, __cs + __declen); + + // Tack on decimal part. + int __newlen = __p2 - __new; + if (__p) + { + char_traits<_CharT>::copy(__p2, __p, __len - __declen); + __newlen += __len - __declen; + } + __len = __newlen; + } + + // The following code uses snprintf (or sprintf(), when + // _GLIBCXX_USE_C99 is not defined) to convert floating point values + // for insertion into a stream. An optimization would be to replace + // them with code that works directly on a wide buffer and then use + // __pad to do the padding. It would be good to replace them anyway + // to gain back the efficiency that C++ provides by knowing up front + // the type of the values to insert. Also, sprintf is dangerous + // since may lead to accidental buffer overruns. This + // implementation follows the C++ standard fairly directly as + // outlined in 22.2.2.2 [lib.locale.num.put] + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, + _ValueT __v) const + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + // Use default precision if out of range. + streamsize __prec = __io.precision(); + if (__prec < static_cast(0)) + __prec = static_cast(6); + + const int __max_digits = numeric_limits<_ValueT>::digits10; + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + int __len; + // Long enough for the max format spec. + char __fbuf[16]; + +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough (most probably sufficient + // for non-ios_base::fixed outputs) + int __cs_size = __max_digits * 3; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + + __num_base::_S_format_float(__io, __fbuf, __mod); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); + + // If the buffer was not large enough, try again with the correct size. + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); + } +#else + // Consider the possibility of long ios_base::fixed outputs + const bool __fixed = __io.flags() & ios_base::fixed; + const int __max_exp = numeric_limits<_ValueT>::max_exponent10; + + // The size of the output string is computed as follows. + // ios_base::fixed outputs may need up to __max_exp + 1 chars + // for the integer part + __prec chars for the fractional part + // + 3 chars for sign, decimal point, '\0'. On the other hand, + // for non-fixed outputs __max_digits * 2 + __prec chars are + // largely sufficient. + const int __cs_size = __fixed ? __max_exp + __prec + 4 + : __max_digits * 2 + __prec; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + + __num_base::_S_format_float(__io, __fbuf, __mod); + __len = std::__convert_from_v(__cs, 0, __fbuf, __v, + _S_get_c_locale(), __prec); +#endif + + // [22.2.2.2.2] Stage 2, convert to char_type, using correct + // numpunct.decimal_point() values for '.' and adding grouping. + const ctype<_CharT>& __ctype = use_facet >(__loc); + + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__cs, __cs + __len, __ws); + + // Replace decimal point. + const _CharT __cdec = __ctype.widen('.'); + const _CharT __dec = __lc->_M_decimal_point; + const _CharT* __p; + if (__p = char_traits<_CharT>::find(__ws, __len, __cdec)) + __ws[__p - __ws] = __dec; + + // Add grouping, if necessary. + if (__lc->_M_use_grouping) + { + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __p, __ws2, __ws, __len); + __ws = __ws2; + } + + // Pad. + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __ws3, __ws, __len); + __ws = __ws3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __ws, __len); + } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + if ((__flags & ios_base::boolalpha) == 0) + { + const long __l = __v; + __s = _M_insert_int(__s, __io, __fill, __l); + } + else + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + const _CharT* __name = __v ? __lc->_M_truename + : __lc->_M_falsename; + int __len = __v ? __lc->_M_truename_size + : __lc->_M_falsename_size; + + const streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + _CharT* __cs + = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs, __name, __len); + __name = __cs; + } + __io.width(0); + __s = std::__write(__s, __name, __len); + } + return __s; + } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const + { return _M_insert_int(__s, __b, __fill, __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + unsigned long long __v) const + { return _M_insert_int(__s, __io, __fill, __v); } +#endif + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const + { return _M_insert_float(__s, __io, __fill, char(), __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + long double __v) const + { return _M_insert_float(__s, __io, __fill, 'L', __v); } + + template + _OutIter + num_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type __fill, + const void* __v) const + { + const ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __fmt = ~(ios_base::basefield + | ios_base::uppercase + | ios_base::internal); + __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); + + __s = _M_insert_int(__s, __io, __fill, + reinterpret_cast(__v)); + __io.flags(__flags); + return __s; + } + + template + template + _InIter + money_get<_CharT, _InIter>:: + _M_extract(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __units) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef moneypunct<_CharT, _Intl> __moneypunct_type; + typedef typename __moneypunct_type::__cache_type __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Deduced sign. + bool __negative = false; + // Sign size. + size_type __sign_size = 0; + // True if sign is mandatory. + const bool __mandatory_sign = (__lc->_M_positive_sign_size + && __lc->_M_negative_sign_size); + // String of grouping info from thousands_sep plucked from __units. + string __grouping_tmp; + if (__lc->_M_use_grouping) + __grouping_tmp.reserve(32); + // Last position before the decimal point. + int __last_pos = 0; + // Separator positions, then, possibly, fractional digits. + int __n = 0; + // If input iterator is in a valid state. + bool __testvalid = true; + // Flag marking when a decimal point is found. + bool __testdecfound = false; + + // The tentative returned string is stored here. + string __res; + __res.reserve(32); + + const char_type* __lit_zero = __lit + money_base::_S_zero; + const char_type* __q; + const money_base::pattern __p = __lc->_M_neg_format; + for (int __i = 0; __i < 4 && __testvalid; ++__i) + { + const part __which = static_cast(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + // According to 22.2.6.1.2, p2, symbol is required + // if (__io.flags() & ios_base::showbase), otherwise + // is optional and consumed only if other characters + // are needed to complete the format. + if (__io.flags() & ios_base::showbase || __sign_size > 1 + || __i == 0 + || (__i == 1 && (__mandatory_sign + || (static_cast(__p.field[0]) + == money_base::sign) + || (static_cast(__p.field[2]) + == money_base::space))) + || (__i == 2 && ((static_cast(__p.field[3]) + == money_base::value) + || __mandatory_sign + && (static_cast(__p.field[3]) + == money_base::sign)))) + { + const size_type __len = __lc->_M_curr_symbol_size; + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __lc->_M_curr_symbol[__j]; + ++__beg, ++__j); + if (__j != __len + && (__j || __io.flags() & ios_base::showbase)) + __testvalid = false; + } + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__lc->_M_positive_sign_size && __beg != __end + && *__beg == __lc->_M_positive_sign[0]) + { + __sign_size = __lc->_M_positive_sign_size; + ++__beg; + } + else if (__lc->_M_negative_sign_size && __beg != __end + && *__beg == __lc->_M_negative_sign[0]) + { + __negative = true; + __sign_size = __lc->_M_negative_sign_size; + ++__beg; + } + else if (__lc->_M_positive_sign_size + && !__lc->_M_negative_sign_size) + // "... if no sign is detected, the result is given the sign + // that corresponds to the source of the empty string" + __negative = true; + else if (__mandatory_sign) + __testvalid = false; + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + if (__q = __traits_type::find(__lit_zero, 10, *__beg)) + { + __res += money_base::_S_atoms[__q - __lit]; + ++__n; + } + else if (*__beg == __lc->_M_decimal_point && !__testdecfound) + { + __last_pos = __n; + __n = 0; + __testdecfound = true; + } + else if (__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep + && !__testdecfound) + { + if (__n) + { + // Mark position for later analysis. + __grouping_tmp += static_cast(__n); + __n = 0; + } + else + { + __testvalid = false; + break; + } + } + else + break; + if (__res.empty()) + __testvalid = false; + break; + case money_base::space: + // At least one space is required. + if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) + ++__beg; + else + __testvalid = false; + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } + } + + // Need to get the rest of the sign characters, if they exist. + if (__sign_size > 1 && __testvalid) + { + const char_type* __sign = __negative ? __lc->_M_negative_sign + : __lc->_M_positive_sign; + size_type __i = 1; + for (; __beg != __end && __i < __sign_size + && *__beg == __sign[__i]; ++__beg, ++__i); + + if (__i != __sign_size) + __testvalid = false; + } + + if (__testvalid) + { + // Strip leading zeros. + if (__res.size() > 1) + { + const size_type __first = __res.find_first_not_of('0'); + const bool __only_zeros = __first == string::npos; + if (__first) + __res.erase(0, __only_zeros ? __res.size() - 1 : __first); + } + + // 22.2.6.1.2, p4 + if (__negative && __res[0] != '0') + __res.insert(__res.begin(), '-'); + + // Test for grouping fidelity. + if (__grouping_tmp.size()) + { + // Add the ending grouping. + __grouping_tmp += static_cast(__testdecfound ? __last_pos + : __n); + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __grouping_tmp)) + __testvalid = false; + } + + // Iff not enough digits were supplied after the decimal-point. + if (__testdecfound && __lc->_M_frac_digits > 0 + && __n != __lc->_M_frac_digits) + __testvalid = false; + } + + // Iff no more characters are available. + if (__beg == __end) + __err |= ios_base::eofbit; + + // Iff valid sequence is not recognized. + if (!__testvalid) + __err |= ios_base::failbit; + else + __units.swap(__res); + + return __beg; + } + + template + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { + string __str; + if (__intl) + __beg = _M_extract(__beg, __end, __io, __err, __str); + else + __beg = _M_extract(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __units) const + { + typedef typename string::size_type size_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + string __str; + const iter_type __ret = __intl ? _M_extract(__beg, __end, __io, + __err, __str) + : _M_extract(__beg, __end, __io, + __err, __str); + const size_type __len = __str.size(); + if (__len) + { + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__str.data(), __str.data() + __len, __ws); + __units.assign(__ws, __len); + } + + return __ret; + } + + template + template + _OutIter + money_put<_CharT, _OutIter>:: + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const + { + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef moneypunct<_CharT, _Intl> __moneypunct_type; + typedef typename __moneypunct_type::__cache_type __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Determine if negative or positive formats are to be used, and + // discard leading negative_sign if it is present. + const char_type* __beg = __digits.data(); + + money_base::pattern __p; + const char_type* __sign; + size_type __sign_size; + if (*__beg != __lit[money_base::_S_minus]) + { + __p = __lc->_M_pos_format; + __sign = __lc->_M_positive_sign; + __sign_size = __lc->_M_positive_sign_size; + } + else + { + __p = __lc->_M_neg_format; + __sign = __lc->_M_negative_sign; + __sign_size = __lc->_M_negative_sign_size; + if (__digits.size()) + ++__beg; + } + + // Look for valid numbers in the ctype facet within input digits. + size_type __len = __ctype.scan_not(ctype_base::digit, __beg, + __beg + __digits.size()) - __beg; + if (__len) + { + // Assume valid input, and attempt to format. + // Break down input numbers into base components, as follows: + // final_value = grouped units + (decimal point) + (digits) + string_type __value; + __value.reserve(2 * __len); + + // Add thousands separators to non-decimal digits, per + // grouping rules. + int __paddec = __len - __lc->_M_frac_digits; + if (__paddec > 0) + { + if (__lc->_M_frac_digits < 0) + __paddec = __len; + if (__lc->_M_grouping_size) + { + _CharT* __ws = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * 2 * __len)); + _CharT* __ws_end = + std::__add_grouping(__ws, __lc->_M_thousands_sep, + __lc->_M_grouping, + __lc->_M_grouping_size, + __beg, __beg + __paddec); + __value.assign(__ws, __ws_end - __ws); + } + else + __value.assign(__beg, __paddec); + } + + // Deal with decimal point, decimal digits. + if (__lc->_M_frac_digits > 0) + { + __value += __lc->_M_decimal_point; + if (__paddec >= 0) + __value.append(__beg + __paddec, __lc->_M_frac_digits); + else + { + // Have to pad zeros in the decimal position. + __value.append(-__paddec, __lit[money_base::_S_zero]); + __value.append(__beg, __len); + } + } + + // Calculate length of resulting string. + const ios_base::fmtflags __f = __io.flags() + & ios_base::adjustfield; + __len = __value.size() + __sign_size; + __len += ((__io.flags() & ios_base::showbase) + ? __lc->_M_curr_symbol_size : 0); + + string_type __res; + __res.reserve(2 * __len); + + const size_type __width = static_cast(__io.width()); + const bool __testipad = (__f == ios_base::internal + && __len < __width); + // Fit formatted digits into the required pattern. + for (int __i = 0; __i < 4; ++__i) + { + const part __which = static_cast(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase) + __res.append(__lc->_M_curr_symbol, + __lc->_M_curr_symbol_size); + break; + case money_base::sign: + // Sign might not exist, or be more than one + // charater long. In that case, add in the rest + // below. + if (__sign_size) + __res += __sign[0]; + break; + case money_base::value: + __res += __value; + break; + case money_base::space: + // At least one space is required, but if internal + // formatting is required, an arbitrary number of + // fill spaces will be necessary. + if (__testipad) + __res.append(__width - __len, __fill); + else + __res += __fill; + break; + case money_base::none: + if (__testipad) + __res.append(__width - __len, __fill); + break; + } + } + + // Special case of multi-part sign parts. + if (__sign_size > 1) + __res.append(__sign + 1, __sign_size - 1); + + // Pad, if still necessary. + __len = __res.size(); + if (__width > __len) + { + if (__f == ios_base::left) + // After. + __res.append(__width - __len, __fill); + else + // Before. + __res.insert(0, __width - __len, __fill); + __len = __width; + } + + // Write resulting, fully-formatted string to output iterator. + __s = std::__write(__s, __res.data(), __len); + } + __io.width(0); + return __s; + } + + template + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const + { + const locale __loc = __io.getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough. + int __cs_size = 64; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 328. Bad sprintf format modifier in money_put<>::do_put() + int __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, + _S_get_c_locale(), 0); + // If the buffer was not large enough, try again with the correct size. + if (__len >= __cs_size) + { + __cs_size = __len + 1; + __cs = static_cast(__builtin_alloca(__cs_size)); + __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, + _S_get_c_locale(), 0); + } +#else + // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. + const int __cs_size = numeric_limits::max_exponent10 + 3; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + int __len = std::__convert_from_v(__cs, 0, "%.*Lf", __units, + _S_get_c_locale(), 0); +#endif + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __cs_size)); + __ctype.widen(__cs, __cs + __len, __ws); + const string_type __digits(__ws, __len); + return __intl ? _M_insert(__s, __io, __fill, __digits) + : _M_insert(__s, __io, __fill, __digits); + } + + template + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const + { return __intl ? _M_insert(__s, __io, __fill, __digits) + : _M_insert(__s, __io, __fill, __digits); } + + + // NB: Not especially useful. Without an ios_base object or some + // kind of locale reference, we are left clawing at the air where + // the side of the mountain used to be... + template + time_base::dateorder + time_get<_CharT, _InIter>::do_date_order() const + { return time_base::no_order; } + + // Expand a strftime format string and parse it. E.g., do_get_date() may + // pass %m/%d/%Y => extracted characters. + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const size_t __len = char_traits<_CharT>::length(__format); + + for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i) + { + if (__ctype.narrow(__format[__i], 0) == '%') + { + // Verify valid formatting code, attempt to extract. + char __c = __ctype.narrow(__format[++__i], 0); + int __mem = 0; + if (__c == 'E' || __c == 'O') + __c = __ctype.narrow(__format[++__i], 0); + switch (__c) + { + const char* __cs; + _CharT __wcs[10]; + case 'a': + // Abbreviated weekday name [tm_wday] + const char_type* __days1[7]; + __tp._M_days_abbreviated(__days1); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, + 7, __io, __err); + break; + case 'A': + // Weekday name [tm_wday]. + const char_type* __days2[7]; + __tp._M_days(__days2); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, + 7, __io, __err); + break; + case 'h': + case 'b': + // Abbreviated month name [tm_mon] + const char_type* __months1[12]; + __tp._M_months_abbreviated(__months1); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months1, 12, __io, __err); + break; + case 'B': + // Month name [tm_mon]. + const char_type* __months2[12]; + __tp._M_months(__months2); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months2, 12, __io, __err); + break; + case 'c': + // Default time and date representation. + const char_type* __dt[2]; + __tp._M_date_time_formats(__dt); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dt[0]); + break; + case 'd': + // Day [01, 31]. [tm_mday] + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, + __io, __err); + break; + case 'e': + // Day [1, 31], with single digits preceded by + // space. [tm_mday] + if (__ctype.is(ctype_base::space, *__beg)) + __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, + 1, __io, __err); + else + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, + 2, __io, __err); + break; + case 'D': + // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] + __cs = "%m/%d/%y"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); + break; + case 'H': + // Hour [00, 23]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, + __io, __err); + break; + case 'I': + // Hour [01, 12]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, + __io, __err); + break; + case 'm': + // Month [01, 12]. [tm_mon] + __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, + __io, __err); + if (!__err) + __tm->tm_mon = __mem - 1; + break; + case 'M': + // Minute [00, 59]. [tm_min] + __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, + __io, __err); + break; + case 'n': + if (__ctype.narrow(*__beg, 0) == '\n') + ++__beg; + else + __err |= ios_base::failbit; + break; + case 'R': + // Equivalent to (%H:%M). + __cs = "%H:%M"; + __ctype.widen(__cs, __cs + 6, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); + break; + case 'S': + // Seconds. [tm_sec] + // [00, 60] in C99 (one leap-second), [00, 61] in C89. +#ifdef _GLIBCXX_USE_C99 + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, +#else + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, +#endif + __io, __err); + break; + case 't': + if (__ctype.narrow(*__beg, 0) == '\t') + ++__beg; + else + __err |= ios_base::failbit; + break; + case 'T': + // Equivalent to (%H:%M:%S). + __cs = "%H:%M:%S"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); + break; + case 'x': + // Locale's date. + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); + break; + case 'X': + // Locale's time. + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); + break; + case 'y': + case 'C': // C99 + // Two digit year. [tm_year] + __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, + __io, __err); + break; + case 'Y': + // Year [1900). [tm_year] + __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, + __io, __err); + if (!__err) + __tm->tm_year = __mem - 1900; + break; + case 'Z': + // Timezone info. + if (__ctype.is(ctype_base::upper, *__beg)) + { + int __tmp; + __beg = _M_extract_name(__beg, __end, __tmp, + __timepunct_cache<_CharT>::_S_timezones, + 14, __io, __err); + + // GMT requires special effort. + if (__beg != __end && !__err && __tmp == 0 + && (*__beg == __ctype.widen('-') + || *__beg == __ctype.widen('+'))) + { + __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, + __io, __err); + __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, + __io, __err); + } + } + else + __err |= ios_base::failbit; + break; + default: + // Not recognized. + __err |= ios_base::failbit; + } + } + else + { + // Verify format and input match, extract and discard. + if (__format[__i] == *__beg) + ++__beg; + else + __err |= ios_base::failbit; + } + } + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + // As-is works for __len = 1, 2, 4, the values actually used. + int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); + + ++__min; + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < __len; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + __value = __value * 10 + (__c - '0'); + const int __valuec = __value * __mult; + if (__valuec > __max || __valuec + __mult < __min) + break; + __mult /= 10; + } + else + break; + } + if (__i == __len) + __member = __value; + else + __err |= ios_base::failbit; + return __beg; + } + + // Assumptions: + // All elements in __names are unique. + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + int* __matches = static_cast(__builtin_alloca(sizeof(int) + * __indexlen)); + size_t __nmatches = 0; + size_t __pos = 0; + bool __testvalid = true; + const char_type* __name; + + // Look for initial matches. + // NB: Some of the locale data is in the form of all lowercase + // names, and some is in the form of initially-capitalized + // names. Look for both. + if (__beg != __end) + { + const char_type __c = *__beg; + for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) + if (__c == __names[__i1][0] + || __c == __ctype.toupper(__names[__i1][0])) + __matches[__nmatches++] = __i1; + } + + while (__nmatches > 1) + { + // Find smallest matching string. + size_t __minlen = __traits_type::length(__names[__matches[0]]); + for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) + __minlen = std::min(__minlen, + __traits_type::length(__names[__matches[__i2]])); + ++__beg, ++__pos; + if (__pos < __minlen && __beg != __end) + for (size_t __i3 = 0; __i3 < __nmatches;) + { + __name = __names[__matches[__i3]]; + if (__name[__pos] != *__beg) + __matches[__i3] = __matches[--__nmatches]; + else + ++__i3; + } + else + break; + } + + if (__nmatches == 1) + { + // Make sure found name is completely extracted. + ++__beg, ++__pos; + __name = __names[__matches[0]]; + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end && __name[__pos] == *__beg) + ++__beg, ++__pos; + + if (__len == __pos) + __member = __matches[0]; + else + __testvalid = false; + } + else + __testvalid = false; + if (!__testvalid) + __err |= ios_base::failbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const char_type* __days[7]; + __tp._M_days_abbreviated(__days); + int __tmpwday; + __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, __io, __err); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_days and _M_days_abbreviated organized in + // exact same order, first to last, such that the resulting + // __days array with the same index points to a day, and that + // day's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__err && __beg != __end) + { + size_t __pos = __traits_type::length(__days[__tmpwday]); + __tp._M_days(__days); + const char_type* __name = __days[__tmpwday]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __err |= ios_base::failbit; + } + } + if (!__err) + __tm->tm_wday = __tmpwday; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_monthname(iter_type __beg, iter_type __end, + ios_base& __io, ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const char_type* __months[12]; + __tp._M_months_abbreviated(__months); + int __tmpmon; + __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, + __io, __err); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_months and _M_months_abbreviated organized in + // exact same order, first to last, such that the resulting + // __months array with the same index points to a month, and that + // month's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__err && __beg != __end) + { + size_t __pos = __traits_type::length(__months[__tmpmon]); + __tp._M_months(__months); + const char_type* __name = __months[__tmpmon]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __err |= ios_base::failbit; + } + } + if (!__err) + __tm->tm_mon = __tmpmon; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < 4; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + __value = __value * 10 + (__c - '0'); + else + break; + } + if (__i == 2 || __i == 4) + __tm->tm_year = __i == 2 ? __value : __value - 1900; + else + __err |= ios_base::failbit; + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _OutIter + time_put<_CharT, _OutIter>:: + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet >(__loc); + for (; __beg != __end; ++__beg) + if (__ctype.narrow(*__beg, 0) != '%') + { + *__s = *__beg; + ++__s; + } + else if (++__beg != __end) + { + char __format; + char __mod = 0; + const char __c = __ctype.narrow(*__beg, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__beg != __end) + { + __mod = __c; + __format = __ctype.narrow(*__beg, 0); + } + else + break; + __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); + } + else + break; + return __s; + } + + template + _OutIter + time_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + char __format, char __mod) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet >(__loc); + __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + + // NB: This size is arbitrary. Should this be a data member, + // initialized at construction? + const size_t __maxlen = 128; + char_type* __res = + static_cast(__builtin_alloca(sizeof(char_type) * __maxlen)); + + // NB: In IEE 1003.1-200x, and perhaps other locale models, it + // is possible that the format character will be longer than one + // character. Possibilities include 'E' or 'O' followed by a + // format character: if __mod is not the default argument, assume + // it's a valid modifier. + char_type __fmt[4]; + __fmt[0] = __ctype.widen('%'); + if (!__mod) + { + __fmt[1] = __format; + __fmt[2] = char_type(); + } + else + { + __fmt[1] = __mod; + __fmt[2] = __format; + __fmt[3] = char_type(); + } + + __tp._M_put(__res, __maxlen, __fmt, __tm); + + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __res, char_traits::length(__res)); + } + + + // Generic version does nothing. + template + int + collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const + { return 0; } + + // Generic version does nothing. + template + size_t + collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const + { return 0; } + + template + int + collate<_CharT>:: + do_compare(const _CharT* __lo1, const _CharT* __hi1, + const _CharT* __lo2, const _CharT* __hi2) const + { + // strcoll assumes zero-terminated strings so we make a copy + // and then put a zero at the end. + const string_type __one(__lo1, __hi1); + const string_type __two(__lo2, __hi2); + + const _CharT* __p = __one.c_str(); + const _CharT* __pend = __one.data() + __one.length(); + const _CharT* __q = __two.c_str(); + const _CharT* __qend = __two.data() + __two.length(); + + // strcoll stops when it sees a nul character so we break + // the strings into zero-terminated substrings and pass those + // to strcoll. + for (;;) + { + const int __res = _M_compare(__p, __q); + if (__res) + return __res; + + __p += char_traits<_CharT>::length(__p); + __q += char_traits<_CharT>::length(__q); + if (__p == __pend && __q == __qend) + return 0; + else if (__p == __pend) + return -1; + else if (__q == __qend) + return 1; + + __p++; + __q++; + } + } + + template + typename collate<_CharT>::string_type + collate<_CharT>:: + do_transform(const _CharT* __lo, const _CharT* __hi) const + { + // strxfrm assumes zero-terminated strings so we make a copy + string_type __str(__lo, __hi); + + const _CharT* __p = __str.c_str(); + const _CharT* __pend = __str.data() + __str.length(); + + size_t __len = (__hi - __lo) * 2; + + string_type __ret; + + // strxfrm stops when it sees a nul character so we break + // the string into zero-terminated substrings and pass those + // to strxfrm. + for (;;) + { + // First try a buffer perhaps big enough. + _CharT* __c = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); + size_t __res = _M_transform(__c, __p, __len); + // If the buffer was not large enough, try again with the + // correct size. + if (__res >= __len) + { + __len = __res + 1; + __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __res = _M_transform(__c, __p, __res + 1); + } + + __ret.append(__c, __res); + __p += char_traits<_CharT>::length(__p); + if (__p == __pend) + return __ret; + + __p++; + __ret.push_back(_CharT()); + } + } + + template + long + collate<_CharT>:: + do_hash(const _CharT* __lo, const _CharT* __hi) const + { + unsigned long __val = 0; + for (; __lo < __hi; ++__lo) + __val = *__lo + ((__val << 7) | + (__val >> (numeric_limits::digits - 7))); + return static_cast(__val); + } + + // Construct correctly padded string, as per 22.2.2.2.2 + // Assumes + // __newlen > __oldlen + // __news is allocated for __newlen size + // Used by both num_put and ostream inserters: if __num, + // internal-adjusted objects are padded according to the rules below + // concerning 0[xX] and +-, otherwise, exactly as right-adjusted + // ones are. + + // NB: Of the two parameters, _CharT can be deduced from the + // function arguments. The other (_Traits) has to be explicitly specified. + template + void + __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, + _CharT* __news, const _CharT* __olds, + const streamsize __newlen, + const streamsize __oldlen, const bool __num) + { + const size_t __plen = static_cast(__newlen - __oldlen); + const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + + // Padding last. + if (__adjust == ios_base::left) + { + _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); + _Traits::assign(__news + __oldlen, __plen, __fill); + return; + } + + size_t __mod = 0; + if (__adjust == ios_base::internal && __num) + { + // Pad after the sign, if there is one. + // Pad after 0[xX], if there is one. + // Who came up with these rules, anyway? Jeeze. + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + const bool __testsign = (__ctype.widen('-') == __olds[0] + || __ctype.widen('+') == __olds[0]); + const bool __testhex = (__ctype.widen('0') == __olds[0] + && __oldlen > 1 + && (__ctype.widen('x') == __olds[1] + || __ctype.widen('X') == __olds[1])); + if (__testhex) + { + __news[0] = __olds[0]; + __news[1] = __olds[1]; + __mod = 2; + __news += 2; + } + else if (__testsign) + { + __news[0] = __olds[0]; + __mod = 1; + ++__news; + } + // else Padding first. + } + _Traits::assign(__news, __plen, __fill); + _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), + __oldlen - __mod); + } + + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) + { + const size_t __n = __grouping_tmp.size() - 1; + const size_t __min = std::min(__n, __grouping_size - 1); + size_t __i = __n; + bool __test = true; + + // Parsed number groupings have to match the + // numpunct::grouping string exactly, starting at the + // right-most point of the parsed sequence of elements ... + for (size_t __j = 0; __j < __min && __test; --__i, ++__j) + __test = __grouping_tmp[__i] == __grouping[__j]; + for (; __i && __test; --__i) + __test = __grouping_tmp[__i] == __grouping[__min]; + // ... but the last parsed grouping can be <= numpunct + // grouping. + __test &= __grouping_tmp[0] <= __grouping[__min]; + return __test; + } + + template + _CharT* + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, + const _CharT* __first, const _CharT* __last) + { + if (__last - __first > *__gbeg) + { + const bool __bump = __gsize != 1; + __s = std::__add_grouping(__s, __sep, __gbeg + __bump, + __gsize - __bump, __first, + __last - *__gbeg); + __first = __last - *__gbeg; + *__s++ = __sep; + } + do + *__s++ = *__first++; + while (__first != __last); + return __s; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class moneypunct; + extern template class moneypunct; + extern template class moneypunct_byname; + extern template class moneypunct_byname; + extern template class money_get; + extern template class money_put; + extern template class numpunct; + extern template class numpunct_byname; + extern template class num_get; + extern template class num_put; + extern template class __timepunct; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; + extern template class messages; + extern template class messages_byname; + extern template class ctype_byname; + extern template class codecvt_byname; + extern template class collate; + extern template class collate_byname; + + extern template + const codecvt& + use_facet >(const locale&); + + extern template + const collate& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class moneypunct; + extern template class moneypunct; + extern template class moneypunct_byname; + extern template class moneypunct_byname; + extern template class money_get; + extern template class money_put; + extern template class numpunct; + extern template class numpunct_byname; + extern template class num_get; + extern template class num_put; + extern template class __timepunct; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; + extern template class messages; + extern template class messages_byname; + extern template class ctype_byname; + extern template class codecvt_byname; + extern template class collate; + extern template class collate_byname; + + extern template + const codecvt& + use_facet >(locale const&); + + extern template + const collate& + use_facet >(const locale&); + + extern template + const numpunct& + use_facet >(const locale&); + + extern template + const num_put& + use_facet >(const locale&); + + extern template + const num_get& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/localefwd.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/localefwd.h new file mode 100644 index 00000000000..247158df374 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/localefwd.h @@ -0,0 +1,192 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file localefwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_FWD_H +#define _LOCALE_FWD_H 1 + +#pragma GCC system_header + +#include +#include // Defines __c_locale, config-specific includes +#include // For ostreambuf_iterator, istreambuf_iterator +#include + +namespace std +{ + // 22.1.1 Locale + class locale; + + // 22.1.3 Convenience interfaces + template + inline bool + isspace(_CharT, const locale&); + + template + inline bool + isprint(_CharT, const locale&); + + template + inline bool + iscntrl(_CharT, const locale&); + + template + inline bool + isupper(_CharT, const locale&); + + template + inline bool + islower(_CharT, const locale&); + + template + inline bool + isalpha(_CharT, const locale&); + + template + inline bool + isdigit(_CharT, const locale&); + + template + inline bool + ispunct(_CharT, const locale&); + + template + inline bool + isxdigit(_CharT, const locale&); + + template + inline bool + isalnum(_CharT, const locale&); + + template + inline bool + isgraph(_CharT, const locale&); + + template + inline _CharT + toupper(_CharT, const locale&); + + template + inline _CharT + tolower(_CharT, const locale&); + + // 22.2.1 and 22.2.1.3 ctype + class ctype_base; + template + class ctype; + template<> class ctype; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> class ctype; +#endif + template + class ctype_byname; + // NB: Specialized for char and wchar_t in locale_facets.h. + + class codecvt_base; + class __enc_traits; + template + class codecvt; + template<> class codecvt; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> class codecvt; +#endif + template + class codecvt_byname; + + // 22.2.2 and 22.2.3 numeric + template > + class num_get; + template > + class num_put; + template class numpunct; + template class numpunct_byname; + + // 22.2.4 collation + template + class collate; + template class + collate_byname; + + // 22.2.5 date and time + class time_base; + template > + class time_get; + template > + class time_get_byname; + template > + class time_put; + template > + class time_put_byname; + + // 22.2.6 money + class money_base; + template > + class money_get; + template > + class money_put; + template + class moneypunct; + template + class moneypunct_byname; + + // 22.2.7 message retrieval + class messages_base; + template + class messages; + template + class messages_byname; + + template + bool + has_facet(const locale& __loc) throw(); + + template + const _Facet& + use_facet(const locale& __loc); + + template + inline const _Facet& + __check_facet(const _Facet* __f) + { + if (!__f) + __throw_bad_cast(); + return *__f; + } +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/mask_array.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/mask_array.h new file mode 100644 index 00000000000..1a694f3c61f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/mask_array.h @@ -0,0 +1,209 @@ +// The template and inlines for the -*- C++ -*- mask_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file mask_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MASK_ARRAY_H +#define _MASK_ARRAY_H 1 + +#pragma GCC system_header + +namespace std { + + /** + * @brief Reference to selected subset of an array. + * + * A mask_array is a reference to the actual elements of an array specified + * by a bitmask in the form of an array of bool. The way to get a + * mask_array is to call operator[](valarray) on a valarray. The + * returned mask_array then permits carrying operations out on the + * referenced subset of elements in the original valarray. + * + * For example, if a mask_array is obtained using the array (false, true, + * false, true) as an argument, the mask array has two elements referring + * to array[1] and array[3] in the underlying array. + * + * @param Tp Element type. + */ + template + class mask_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + mask_array (const mask_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + mask_array& operator=(const mask_array&); + + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp&) const; + + // ~mask_array (); + + template + void operator=(const _Expr<_Dom,_Tp>&) const; + template + void operator*=(const _Expr<_Dom,_Tp>&) const; + template + void operator/=(const _Expr<_Dom,_Tp>&) const; + template + void operator%=(const _Expr<_Dom,_Tp>&) const; + template + void operator+=(const _Expr<_Dom,_Tp>&) const; + template + void operator-=(const _Expr<_Dom,_Tp>&) const; + template + void operator^=(const _Expr<_Dom,_Tp>&) const; + template + void operator&=(const _Expr<_Dom,_Tp>&) const; + template + void operator|=(const _Expr<_Dom,_Tp>&) const; + template + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + mask_array(_Array<_Tp>, size_t, _Array); + friend class valarray<_Tp>; + + const size_t _M_sz; + const _Array _M_mask; + const _Array<_Tp> _M_array; + + // not implemented + mask_array(); + }; + + + template + inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& a) + : _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {} + + template + inline + mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array __m) + : _M_sz(__s), _M_mask(__m), _M_array(__a) {} + + template + inline mask_array<_Tp>& + mask_array<_Tp>::operator=(const mask_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_mask, + _M_sz, _M_array, _M_mask); + return *this; + } + + template + inline void + mask_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); } + + template + inline void + mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); } + + template + template + inline void + mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const + { std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ + template \ + inline void \ + mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _M_mask, \ + _Array<_Tp>(__v), __v.size()); \ + } \ + \ + template \ + template \ + inline void \ + mask_array<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_mask, __e, __e.size()); \ + } + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _MASK_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/ostream.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/ostream.tcc new file mode 100644 index 00000000000..2d1b5b419cf --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/ostream.tcc @@ -0,0 +1,699 @@ +// ostream classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +#ifndef _OSTREAM_TCC +#define _OSTREAM_TCC 1 + +#pragma GCC system_header + +#include + +namespace std +{ + template + basic_ostream<_CharT, _Traits>::sentry:: + sentry(basic_ostream<_CharT, _Traits>& __os) + : _M_ok(false), _M_os(__os) + { + // XXX MT + if (__os.tie() && __os.good()) + __os.tie()->flush(); + + if (__os.good()) + _M_ok = true; + else + __os.setstate(ios_base::failbit); + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__ostream_type& (*__pf)(__ostream_type&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + return __pf(*this); + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__ios_type& (*__pf)(__ios_type&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(ios_base& (*__pf)(ios_base&)) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(bool __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + bool __b = false; + const char_type __c = this->fill(); + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) + { + const unsigned long __l = static_cast(__n); + __b = __np.put(*this, *this, __c, __l).failed(); + } + else + __b = __np.put(*this, *this, __c, __n).failed(); + if (__b) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + +#ifdef _GLIBCXX_USE_LONG_LONG + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + bool __b = false; + const char_type __c = this->fill(); + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) + { + const unsigned long long __l = (static_cast< + unsigned long long>(__n)); + __b = __np.put(*this, *this, __c, __l).failed(); + } + else + __b = __np.put(*this, *this, __c, __n).failed(); + if (__b) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned long long __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } +#endif + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(double __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long double __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(const void* __n) + { + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__streambuf_type* __sbin) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this); + if (__cerb && __sbin) + { + try + { + if (!__copy_streambufs(__sbin, this->rdbuf())) + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbin) + __err |= ios_base::badbit; + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + put(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::put(char_type) is an unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __put = this->rdbuf()->sputc(__c); + if (traits_type::eq_int_type(__put, traits_type::eof())) + __err |= ios_base::badbit; + } + catch (...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + write(const _CharT* __s, streamsize __n) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::write(const char_type*, streamsize) is an + // unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + sentry __cerb(*this); + if (__cerb) + { + try + { _M_write(__s, __n); } + catch (...) + { this->_M_setstate(ios_base::badbit); } + } + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + flush() + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::flush() is *not* an unformatted output function. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (this->rdbuf() && this->rdbuf()->pubsync() == -1) + __err |= ios_base::badbit; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + typename basic_ostream<_CharT, _Traits>::pos_type + basic_ostream<_CharT, _Traits>:: + tellp() + { + pos_type __ret = pos_type(-1); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + return __ret; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(pos_type __pos) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + template + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + seekp(off_type __off, ios_base::seekdir __dir) + { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } + } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + return *this; + } + + // 27.6.2.5.4 Character inserters. + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = 1; + _CharT* __cs = &__c; + if (__w > __len) + { + __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, + &__c, __w, __len, false); + __len = __w; + } + __out._M_write(__cs, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + return __out; + } + + // Specializations. + template + basic_ostream& + operator<<(basic_ostream& __out, char __c) + { + typedef basic_ostream __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = 1; + char* __cs = &__c; + if (__w > __len) + { + __cs = static_cast(__builtin_alloca(__w)); + __pad::_S_pad(__out, __out.fill(), __cs, + &__c, __w, __len, false); + __len = __w; + } + __out._M_write(__cs, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + return __out; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb && __s) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(_Traits::length(__s)); + if (__w > __len) + { + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) + * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, + __s, __w, __len, false); + __s = __cs; + __len = __w; + } + __out._M_write(__s, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + else if (!__s) + __out.setstate(ios_base::badbit); + return __out; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 167. Improper use of traits_type::length() + // Note that this is only in 'Review' status. + typedef char_traits __traits_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb && __s) + { + size_t __clen = __traits_type::length(__s); + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __clen)); + for (size_t __i = 0; __i < __clen; ++__i) + __ws[__i] = __out.widen(__s[__i]); + _CharT* __str = __ws; + + try + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(__clen); + if (__w > __len) + { + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) + * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, + __ws, __w, __len, false); + __str = __cs; + __len = __w; + } + __out._M_write(__str, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + else if (!__s) + __out.setstate(ios_base::badbit); + return __out; + } + + // Partial specializations. + template + basic_ostream& + operator<<(basic_ostream& __out, const char* __s) + { + typedef basic_ostream __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb && __s) + { + try + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(_Traits::length(__s)); + if (__w > __len) + { + char* __cs = static_cast(__builtin_alloca(__w)); + __pad::_S_pad(__out, __out.fill(), __cs, + __s, __w, __len, false); + __s = __cs; + __len = __w; + } + __out._M_write(__s, __len); + __out.width(0); + } + catch(...) + { __out._M_setstate(ios_base::badbit); } + } + else if (!__s) + __out.setstate(ios_base::badbit); + return __out; + } + + // 21.3.7.9 basic_string::operator<< + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, + const basic_string<_CharT, _Traits, _Alloc>& __str) + { + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typename __ostream_type::sentry __cerb(__out); + if (__cerb) + { + const streamsize __w = __out.width(); + streamsize __len = static_cast(__str.size()); + const _CharT* __s = __str.data(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 25. String operator<< uses width() value wrong + if (__w > __len) + { + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s, + __w, __len, false); + __s = __cs; + __len = __w; + } + __out._M_write(__s, __len); + __out.width(0); + } + return __out; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_ostream; + extern template ostream& endl(ostream&); + extern template ostream& ends(ostream&); + extern template ostream& flush(ostream&); + extern template ostream& operator<<(ostream&, char); + extern template ostream& operator<<(ostream&, unsigned char); + extern template ostream& operator<<(ostream&, signed char); + extern template ostream& operator<<(ostream&, const char*); + extern template ostream& operator<<(ostream&, const unsigned char*); + extern template ostream& operator<<(ostream&, const signed char*); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_ostream; + extern template wostream& endl(wostream&); + extern template wostream& ends(wostream&); + extern template wostream& flush(wostream&); + extern template wostream& operator<<(wostream&, wchar_t); + extern template wostream& operator<<(wostream&, char); + extern template wostream& operator<<(wostream&, const wchar_t*); + extern template wostream& operator<<(wostream&, const char*); +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/postypes.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/postypes.h new file mode 100644 index 00000000000..0cfb61b2df2 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/postypes.h @@ -0,0 +1,215 @@ +// Position types -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4.1 - Types +// ISO C++ 14882: 27.4.3 - Template class fpos +// + +/** @file postypes.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_POSTYPES_H +#define _GLIBCXX_POSTYPES_H 1 + +#pragma GCC system_header + +#include // For mbstate_t + +#ifdef _GLIBCXX_HAVE_STDINT_H +#include // For int64_t +#endif + +namespace std +{ + // The types streamoff, streampos and wstreampos and the class + // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2, + // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbage, the + // behaviour of these types is mostly implementation defined or + // unspecified. The behaviour in this implementation is as noted + // below. + + /** + * @brief Type used by fpos, char_traits, and char_traits. + * + * @if maint + * In clauses 21.1.3.1 and 27.4.1 streamoff is described as an + * implementation defined type. + * Note: In versions of GCC up to and including GCC 3.3, streamoff + * was typedef long. + * @endif + */ +#ifdef _GLIBCXX_HAVE_INT64_T + typedef int64_t streamoff; +#else + typedef long long streamoff; +#endif + + /// Integral type for I/O operation counts and buffer sizes. + typedef ptrdiff_t streamsize; // Signed integral type + + template + class fpos; + + /** + * @brief Class representing stream positions. + * + * The standard places no requirements upon the template parameter StateT. + * In this implementation StateT must be DefaultConstructible, + * CopyConstructible and Assignable. The standard only requires that fpos + * should contain a member of type StateT. In this implementation it also + * contains an offset stored as a signed integer. + * + * @param StateT Type passed to and returned from state(). + */ + template + class fpos + { + private: + streamoff _M_off; + _StateT _M_state; + + public: + // The standard doesn't require that fpos objects can be default + // constructed. This implementation provides a default + // constructor that initializes the offset to 0 and default + // constructs the state. + fpos() + : _M_off(0), _M_state() { } + + // The standard requires that fpos objects can be constructed + // from streamoff objects using the constructor syntax, and + // fails to give any meaningful semantics. In this + // implementation implicit conversion is also allowed, and this + // constructor stores the streamoff as the offset and default + // constructs the state. + /// Construct position from offset. + fpos(streamoff __off) + : _M_off(__off), _M_state() { } + + /// Convert to streamoff. + operator streamoff() const { return _M_off; } + + /// Remember the value of @a st. + void + state(_StateT __st) + { _M_state = __st; } + + /// Return the last set value of @a st. + _StateT + state() const + { return _M_state; } + + // The standard only requires that operator== must be an + // equivalence relation. In this implementation two fpos + // objects belong to the same equivalence class if the contained + // offsets compare equal. + /// Test if equivalent to another position. + bool + operator==(const fpos& __other) const + { return _M_off == __other._M_off; } + + /// Test if not equivalent to another position. + bool + operator!=(const fpos& __other) const + { return _M_off != __other._M_off; } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just adds it's + // argument to the stored offset and returns *this. + /// Add offset to this position. + fpos& + operator+=(streamoff __off) + { + _M_off += __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just subtracts + // it's argument from the stored offset and returns *this. + /// Subtract offset from this position. + fpos& + operator-=(streamoff __off) + { + _M_off -= __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator-. In this + // implementation it constructs a copy of *this, adds the + // argument to that copy using operator+= and then returns the + // copy. + /// Add position and offset. + fpos + operator+(streamoff __off) const + { + fpos __pos(*this); + __pos += __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it constructs a copy of *this, subtracts the + // argument from that copy using operator-= and then returns the + // copy. + /// Subtract offset from position. + fpos + operator-(streamoff __off) const + { + fpos __pos(*this); + __pos -= __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it returns the difference between the offset + // stored in *this and in the argument. + /// Subtract position to return offset. + streamoff + operator-(const fpos& __other) const + { return _M_off - __other._M_off; } + }; + + // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos + // as implementation defined types, but clause 27.2 requires that + // they must both be typedefs for fpos + /// File position for char streams. + typedef fpos streampos; + /// File position for wchar_t streams. + typedef fpos wstreampos; +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/slice_array.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/slice_array.h new file mode 100644 index 00000000000..31c89bcdb61 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/slice_array.h @@ -0,0 +1,273 @@ +// The template and inlines for the -*- C++ -*- slice_array class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file slice_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SLICE_ARRAY_H +#define _SLICE_ARRAY_H 1 + +#pragma GCC system_header + +namespace std +{ + /** + * @brief Class defining one-dimensional subset of an array. + * + * The slice class represents a one-dimensional subset of an array, + * specified by three parameters: start offset, size, and stride. The + * start offset is the index of the first element of the array that is part + * of the subset. The size is the total number of elements in the subset. + * Stride is the distance between each successive array element to include + * in the subset. + * + * For example, with an array of size 10, and a slice with offset 1, size 3 + * and stride 2, the subset consists of array elements 1, 3, and 5. + */ + class slice + { + public: + /// Construct an empty slice. + slice(); + + /** + * @brief Construct a slice. + * + * @param o Offset in array of first element. + * @param d Number of elements in slice. + * @param s Stride between array elements. + */ + slice(size_t, size_t, size_t); + + /// Return array offset of first slice element. + size_t start() const; + /// Return size of slice. + size_t size() const; + /// Return array stride of slice. + size_t stride() const; + + private: + size_t _M_off; // offset + size_t _M_sz; // size + size_t _M_st; // stride unit + }; + + // The default constructor constructor is not required to initialize + // data members with any meaningful values, so we choose to do nothing. + inline + slice::slice() {} + + inline + slice::slice(size_t __o, size_t __d, size_t __s) + : _M_off(__o), _M_sz(__d), _M_st(__s) {} + + inline size_t + slice::start() const + { return _M_off; } + + inline size_t + slice::size() const + { return _M_sz; } + + inline size_t + slice::stride() const + { return _M_st; } + + /** + * @brief Reference to one-dimensional subset of an array. + * + * A slice_array is a reference to the actual elements of an array + * specified by a slice. The way to get a slice_array is to call + * operator[](slice) on a valarray. The returned slice_array then permits + * carrying operations out on the referenced subset of elements in the + * original valarray. For example, operator+=(valarray) will add values + * to the subset of elements in the underlying valarray this slice_array + * refers to. + * + * @param Tp Element type. + */ + template + class slice_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + slice_array(const slice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + slice_array& operator=(const slice_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator=(const _Tp &) const; + // ~slice_array (); + + template + void operator=(const _Expr<_Dom,_Tp>&) const; + template + void operator*=(const _Expr<_Dom,_Tp>&) const; + template + void operator/=(const _Expr<_Dom,_Tp>&) const; + template + void operator%=(const _Expr<_Dom,_Tp>&) const; + template + void operator+=(const _Expr<_Dom,_Tp>&) const; + template + void operator-=(const _Expr<_Dom,_Tp>&) const; + template + void operator^=(const _Expr<_Dom,_Tp>&) const; + template + void operator&=(const _Expr<_Dom,_Tp>&) const; + template + void operator|=(const _Expr<_Dom,_Tp>&) const; + template + void operator<<=(const _Expr<_Dom,_Tp>&) const; + template + void operator>>=(const _Expr<_Dom,_Tp>&) const; + + private: + friend class valarray<_Tp>; + slice_array(_Array<_Tp>, const slice&); + + const size_t _M_sz; + const size_t _M_stride; + const _Array<_Tp> _M_array; + + // not implemented + slice_array(); + }; + + template + inline + slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s) + : _M_sz(__s.size()), _M_stride(__s.stride()), + _M_array(__a.begin() + __s.start()) {} + + template + inline + slice_array<_Tp>::slice_array(const slice_array<_Tp>& a) + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + + // template + // inline slice_array<_Tp>::~slice_array () {} + + template + inline slice_array<_Tp>& + slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, + _M_array, _M_stride); + return *this; + } + + template + inline void + slice_array<_Tp>::operator=(const _Tp& __t) const + { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); } + + template + inline void + slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const + { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } + + template + template + inline void + slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const + { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \ + template \ + inline void \ + slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ + { \ + _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\ + } \ + \ + template \ + template \ + inline void \ + slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ + { \ + _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz); \ + } + + +_DEFINE_VALARRAY_OPERATOR(*, __multiplies) +_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(%, __modulus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(-, __minus) +_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) +_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) +_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) +_DEFINE_VALARRAY_OPERATOR(<<, __shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, __shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // std:: + +#endif /* _SLICE_ARRAY_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/sstream.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/sstream.tcc new file mode 100644 index 00000000000..03f49fb0fd5 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/sstream.tcc @@ -0,0 +1,227 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.7 String-based streams +// + +#ifndef _SSTREAM_TCC +#define _SSTREAM_TCC 1 + +#pragma GCC system_header + +#include + +namespace std +{ + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + pbackfail(int_type __c) + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(__c, __ret); + + if (this->eback() < this->gptr()) + { + const bool __testeq = traits_type::eq(traits_type::to_char_type(__c), + this->gptr()[-1]); + this->gbump(-1); + + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && __testeq) + __ret = __c; + else if (__testeof) + __ret = traits_type::not_eof(__c); + else + { + *this->gptr() = traits_type::to_char_type(__c); + __ret = __c; + } + } + return __ret; + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + overflow(int_type __c) + { + const bool __testout = this->_M_mode & ios_base::out; + if (__builtin_expect(!__testout, false)) + return traits_type::eof(); + + const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); + if (__builtin_expect(__testeof, false)) + return traits_type::not_eof(__c); + + const __size_type __capacity = _M_string.capacity(); + const __size_type __max_size = _M_string.max_size(); + const bool __testput = this->pptr() < this->epptr(); + if (__builtin_expect(!__testput && __capacity == __max_size, false)) + return traits_type::eof(); + + // Try to append __c into output sequence in one of two ways. + // Order these tests done in is unspecified by the standard. + if (!__testput) + { + // NB: Start ostringstream buffers at 512 chars. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suit particular needs. + // Then, in virtue of DR 169 (TC) we are allowed to grow more + // than one char. + const __size_type __opt_len = std::max(__size_type(2 * __capacity), + __size_type(512)); + const __size_type __len = std::min(__opt_len, __max_size); + __string_type __tmp; + __tmp.reserve(__len); + __tmp.assign(_M_string.data(), this->epptr() - this->pbase()); + _M_string.swap(__tmp); + _M_sync(const_cast(_M_string.data()), + this->gptr() - this->eback(), this->pptr() - this->pbase()); + } + return this->sputc(traits_type::to_char_type(__c)); + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin) + { + // Update egptr() to match the actual string end. + _M_update_egptr(); + + if (this->gptr() < this->egptr()) + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + const bool __testboth = __testin && __testout && __way != ios_base::cur; + __testin &= !(__mode & ios_base::out); + __testout &= !(__mode & ios_base::in); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 453. basic_stringbuf::seekoff need not always fail for an empty stream. + const char_type* __beg = __testin ? this->eback() : this->pbase(); + if ((__beg || !__off) && (__testin || __testout || __testboth)) + { + _M_update_egptr(); + + off_type __newoffi = 0; + off_type __newoffo = 0; + if (__way == ios_base::cur) + { + __newoffi = this->gptr() - __beg; + __newoffo = this->pptr() - __beg; + } + else if (__way == ios_base::end) + __newoffo = __newoffi = this->egptr() - __beg; + + if ((__testin || __testboth) + && __newoffi + __off >= 0 + && this->egptr() - __beg >= __newoffi + __off) + { + this->gbump((__beg + __newoffi + __off) - this->gptr()); + __ret = pos_type(__newoffi); + } + if ((__testout || __testboth) + && __newoffo + __off >= 0 + && this->egptr() - __beg >= __newoffo + __off) + { + this->pbump((__beg + __newoffo + __off) - this->pptr()); + __ret = pos_type(__newoffo); + } + } + return __ret; + } + + template + typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + seekpos(pos_type __sp, ios_base::openmode __mode) + { + pos_type __ret = pos_type(off_type(-1)); + const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + + const char_type* __beg = __testin ? this->eback() : this->pbase(); + if (__beg) + { + _M_update_egptr(); + + off_type __pos(__sp); + const bool __testpos = 0 <= __pos + && __pos <= this->egptr() - __beg; + if ((__testin || __testout) && __testpos) + { + if (__testin) + this->gbump((__beg + __pos) - this->gptr()); + if (__testout) + this->pbump((__beg + __pos) - this->pptr()); + __ret = __sp; + } + } + return __ret; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_stringbuf; + extern template class basic_istringstream; + extern template class basic_ostringstream; + extern template class basic_stringstream; + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_stringbuf; + extern template class basic_istringstream; + extern template class basic_ostringstream; + extern template class basic_stringstream; +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algo.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algo.h new file mode 100644 index 00000000000..74956d75b4d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algo.h @@ -0,0 +1,5148 @@ +// Algorithm implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_algo.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALGO_H +#define _ALGO_H 1 + +#include +#include // for _Temporary_buffer +#include + +// See concept_check.h for the __glibcxx_*_requires macros. + +namespace std +{ + /** + * @brief Find the median of three values. + * @param a A value. + * @param b A value. + * @param c A value. + * @return One of @p a, @p b or @p c. + * + * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n + * then the value returned will be @c m. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template + inline const _Tp& + __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; + else + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; + else + return __b; + } + + /** + * @brief Find the median of three values using a predicate for comparison. + * @param a A value. + * @param b A value. + * @param c A value. + * @param comp A binary predicate. + * @return One of @p a, @p b or @p c. + * + * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) + * and @p comp(m,n) are both true then the value returned will be @c m. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template + inline const _Tp& + __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>) + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; + else + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; + else + return __b; + } + + /** + * @brief Apply a function to every element of a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param f A unary function object. + * @return @p f. + * + * Applies the function object @p f to each element in the range + * @p [first,last). @p f must not modify the order of the sequence. + * If @p f has a return value it is ignored. + */ + template + _Function + for_each(_InputIterator __first, _InputIterator __last, _Function __f) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) + __f(*__first); + return __f; + } + + /** + * @if maint + * This is an overload used by find() for the Input Iterator case. + * @endif + */ + template + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, + const _Tp& __val, input_iterator_tag) + { + while (__first != __last && !(*__first == __val)) + ++__first; + return __first; + } + + /** + * @if maint + * This is an overload used by find_if() for the Input Iterator case. + * @endif + */ + template + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, input_iterator_tag) + { + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; + } + + /** + * @if maint + * This is an overload used by find() for the RAI case. + * @endif + */ + template + _RandomAccessIterator + find(_RandomAccessIterator __first, _RandomAccessIterator __last, + const _Tp& __val, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) + { + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + + if (*__first == __val) + return __first; + ++__first; + } + + switch (__last - __first) + { + case 3: + if (*__first == __val) + return __first; + ++__first; + case 2: + if (*__first == __val) + return __first; + ++__first; + case 1: + if (*__first == __val) + return __first; + ++__first; + case 0: + default: + return __last; + } + } + + /** + * @if maint + * This is an overload used by find_if() for the RAI case. + * @endif + */ + template + _RandomAccessIterator + find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Predicate __pred, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) + { + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + + if (__pred(*__first)) + return __first; + ++__first; + } + + switch (__last - __first) + { + case 3: + if (__pred(*__first)) + return __first; + ++__first; + case 2: + if (__pred(*__first)) + return __first; + ++__first; + case 1: + if (__pred(*__first)) + return __first; + ++__first; + case 0: + default: + return __last; + } + } + + /** + * @brief Find the first occurrence of a value in a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param val The value to find. + * @return The first iterator @c i in the range @p [first,last) + * such that @c *i == @p val, or @p last if no such iterator exists. + */ + template + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, + const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + return std::find(__first, __last, __val, + std::__iterator_category(__first)); + } + + /** + * @brief Find the first element in a sequence for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param pred A predicate. + * @return The first iterator @c i in the range @p [first,last) + * such that @p pred(*i) is true, or @p last if no such iterator exists. + */ + template + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + return std::find_if(__first, __last, __pred, + std::__iterator_category(__first)); + } + + /** + * @brief Find two adjacent values in a sequence that are equal. + * @param first A forward iterator. + * @param last A forward iterator. + * @return The first iterator @c i such that @c i and @c i+1 are both + * valid iterators in @p [first,last) and such that @c *i == @c *(i+1), + * or @p last if no such iterator exists. + */ + template + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (*__first == *__next) + return __first; + __first = __next; + } + return __last; + } + + /** + * @brief Find two adjacent values in a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param binary_pred A binary predicate. + * @return The first iterator @c i such that @c i and @c i+1 are both + * valid iterators in @p [first,last) and such that + * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator + * exists. + */ + template + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; + } + return __last; + } + + /** + * @brief Count the number of copies of a value in a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param value The value to be counted. + * @return The number of iterators @c i in the range @p [first,last) + * for which @c *i == @p value + */ + template + typename iterator_traits<_InputIterator>::difference_type + count(_InputIterator __first, _InputIterator __last, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; + } + + /** + * @brief Count the elements of a sequence for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param pred A predicate. + * @return The number of iterators @c i in the range @p [first,last) + * for which @p pred(*i) is true. + */ + template + typename iterator_traits<_InputIterator>::difference_type + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; + } + + /** + * @brief Search a sequence for a matching sub-sequence. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @param last2 A forward iterator. + * @return The first iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return std::find(__first1, __last1, *__first2); + + // General case. + _ForwardIterator2 __p1, __p; + __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; + + while (__first1 != __last1) + { + __first1 = std::find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + + /** + * @brief Search a sequence for a matching sub-sequence using a predicate. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @param last2 A forward iterator. + * @param predicate A binary predicate. + * @return The first iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that + * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range + * @p [0,last2-first2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2), + * using @p predicate to determine equality, and returns an iterator + * to the first element of the sub-sequence, or @p last1 if no such + * iterator exists. + * + * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) + */ + template + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + { + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + return __first1; + } + + // General case. + _ForwardIterator2 __p1, __p; + __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; + + while (__first1 != __last1) + { + while (__first1 != __last1) + { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; + } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (__predicate(*__current, *__p)) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + + /** + * @brief Search a sequence for a number of consecutive values. + * @param first A forward iterator. + * @param last A forward iterator. + * @param count The number of consecutive values. + * @param val The value to find. + * @return The first iterator @c i in the range @p [first,last-count) + * such that @c *(i+N) == @p val for each @c N in the range @p [0,count), + * or @p last if no such iterator exists. + * + * Searches the range @p [first,last) for @p count consecutive elements + * equal to @p val. + */ + template + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + + if (__count <= 0) + return __first; + else + { + __first = std::find(__first, __last, __val); + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && *__i == __val) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + else + __first = std::find(__i, __last, __val); + } + return __last; + } + } + + /** + * @brief Search a sequence for a number of consecutive values using a + * predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param count The number of consecutive values. + * @param val The value to find. + * @param binary_pred A binary predicate. + * @return The first iterator @c i in the range @p [first,last-count) + * such that @p binary_pred(*(i+N),val) is true for each @c N in the + * range @p [0,count), or @p last if no such iterator exists. + * + * Searches the range @p [first,last) for @p count consecutive elements + * for which the predicate returns true. + */ + template + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, const _Tp& __val, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + if (__count <= 0) + return __first; + else + { + while (__first != __last) + { + if (__binary_pred(*__first, __val)) + break; + ++__first; + } + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && __binary_pred(*__i, __val)) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + else + { + while (__i != __last) + { + if (__binary_pred(*__i, __val)) + break; + ++__i; + } + __first = __i; + } + } + return __last; + } + } + + /** + * @brief Swap the elements of two sequences. + * @param first1 A forward iterator. + * @param last1 A forward iterator. + * @param first2 A forward iterator. + * @return An iterator equal to @p first2+(last1-first1). + * + * Swaps each element in the range @p [first1,last1) with the + * corresponding element in the range @p [first2,(last1-first1)). + * The ranges must not overlap. + */ + template + _ForwardIterator2 + swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator2>::value_type, + typename iterator_traits<_ForwardIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + std::iter_swap(__first1, __first2); + return __first2; + } + + /** + * @brief Perform an operation on a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param unary_op A unary operator. + * @return An output iterator equal to @p result+(last-first). + * + * Applies the operator to each element in the input range and assigns + * the results to successive elements of the output sequence. + * Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the + * range @p [0,last-first). + * + * @p unary_op must not alter its argument. + */ + template + _OutputIterator + transform(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _UnaryOperation __unary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _UnaryOperation" + __typeof__(__unary_op(*__first))>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __unary_op(*__first); + return __result; + } + + /** + * @brief Perform an operation on corresponding elements of two sequences. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param result An output iterator. + * @param binary_op A binary operator. + * @return An output iterator equal to @p result+(last-first). + * + * Applies the operator to the corresponding elements in the two + * input ranges and assigns the results to successive elements of the + * output sequence. + * Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each + * @c N in the range @p [0,last1-first1). + * + * @p binary_op must not alter either of its arguments. + */ + template + _OutputIterator + transform(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _OutputIterator __result, + _BinaryOperation __binary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _BinaryOperation" + __typeof__(__binary_op(*__first1,*__first2))>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; + } + + /** + * @brief Replace each occurrence of one value in a sequence with another + * value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param old_value The value to be replaced. + * @param new_value The replacement value. + * @return replace() returns no value. + * + * For each iterator @c i in the range @p [first,last) if @c *i == + * @p old_value then the assignment @c *i = @p new_value is performed. + */ + template + void + replace(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __old_value, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; + } + + /** + * @brief Replace each value in a sequence for which a predicate returns + * true with another value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate. + * @param new_value The replacement value. + * @return replace_if() returns no value. + * + * For each iterator @c i in the range @p [first,last) if @p pred(*i) + * is true then the assignment @c *i = @p new_value is performed. + */ + template + void + replace_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; + } + + /** + * @brief Copy a sequence, replacing each element of one value with another + * value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param old_value The value to be replaced. + * @param new_value The replacement value. + * @return The end of the output sequence, @p result+(last-first). + * + * Copies each element in the input range @p [first,last) to the + * output range @p [result,result+(last-first)) replacing elements + * equal to @p old_value with @p new_value. + */ + template + _OutputIterator + replace_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = *__first == __old_value ? __new_value : *__first; + return __result; + } + + /** + * @brief Copy a sequence, replacing each value for which a predicate + * returns true with another value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param pred A predicate. + * @param new_value The replacement value. + * @return The end of the output sequence, @p result+(last-first). + * + * Copies each element in the range @p [first,last) to the range + * @p [result,result+(last-first)) replacing elements for which + * @p pred returns true with @p new_value. + */ + template + _OutputIterator + replace_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first, ++__result) + *__result = __pred(*__first) ? __new_value : *__first; + return __result; + } + + /** + * @brief Assign the result of a function object to each value in a + * sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @param gen A function object taking no arguments. + * @return generate() returns no value. + * + * Performs the assignment @c *i = @p gen() for each @c i in the range + * @p [first,last). + */ + template + void + generate(_ForwardIterator __first, _ForwardIterator __last, + _Generator __gen) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_GeneratorConcept<_Generator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + *__first = __gen(); + } + + /** + * @brief Assign the result of a function object to each value in a + * sequence. + * @param first A forward iterator. + * @param n The length of the sequence. + * @param gen A function object taking no arguments. + * @return The end of the sequence, @p first+n + * + * Performs the assignment @c *i = @p gen() for each @c i in the range + * @p [first,first+n). + */ + template + _OutputIterator + generate_n(_OutputIterator __first, _Size __n, _Generator __gen) + { + // concept requirements + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + // "the type returned by a _Generator" + __typeof__(__gen())>) + + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; + } + + /** + * @brief Copy a sequence, removing elements of a given value. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param value The value to be removed. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) not equal to @p value + * to the range beginning at @p result. + * remove_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + _OutputIterator + remove_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (!(*__first == __value)) + { + *__result = *__first; + ++__result; + } + return __result; + } + + /** + * @brief Copy a sequence, removing elements for which a predicate is true. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param pred A predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) for which + * @p pred returns true to the range beginning at @p result. + * + * remove_copy_if() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + _OutputIterator + remove_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } + return __result; + } + + /** + * @brief Remove elements from a sequence. + * @param first An input iterator. + * @param last An input iterator. + * @param value The value to be removed. + * @return An iterator designating the end of the resulting sequence. + * + * All elements equal to @p value are removed from the range + * @p [first,last). + * + * remove() is stable, so the relative order of elements that are + * not removed is unchanged. + * + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + remove(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find(__first, __last, __value); + _ForwardIterator __i = __first; + return __first == __last ? __first + : std::remove_copy(++__i, __last, + __first, __value); + } + + /** + * @brief Remove elements from a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate. + * @return An iterator designating the end of the resulting sequence. + * + * All elements for which @p pred returns true are removed from the range + * @p [first,last). + * + * remove_if() is stable, so the relative order of elements that are + * not removed is unchanged. + * + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + remove_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find_if(__first, __last, __pred); + _ForwardIterator __i = __first; + return __first == __last ? __first + : std::remove_copy_if(++__i, __last, + __first, __pred); + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for output iterators. + * @endif + */ + template + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + output_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + typename iterator_traits<_InputIterator>::value_type __value = *__first; + *__result = __value; + while (++__first != __last) + if (!(__value == *__first)) + { + __value = *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for forward iterators. + * @endif + */ + template + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + forward_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + *__result = *__first; + while (++__first != __last) + if (!(*__result == *__first)) + *++__result = *__first; + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for output iterators. + * @endif + */ + template + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _BinaryPredicate __binary_pred, + output_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + typename iterator_traits<_InputIterator>::value_type __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) + { + __value = *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for forward iterators. + * @endif + */ + template + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + _BinaryPredicate __binary_pred, + forward_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) *++__result = *__first; + return ++__result; + } + + /** + * @brief Copy a sequence, removing consecutive duplicate values. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements that compare equal. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename iterator_traits<_OutputIterator>::iterator_category + _IterType; + + if (__first == __last) return __result; + return std::__unique_copy(__first, __last, __result, _IterType()); + } + + /** + * @brief Copy a sequence, removing consecutive values using a predicate. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @param binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements for which @p binary_pred returns + * true. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _BinaryPredicate __binary_pred) + { + // concept requirements -- predicates checked later + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename iterator_traits<_OutputIterator>::iterator_category + _IterType; + + if (__first == __last) return __result; + return std::__unique_copy(__first, __last, __result, + __binary_pred, _IterType()); + } + + /** + * @brief Remove consecutive duplicate values from a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Removes all but the first element from each group of consecutive + * values that compare equal. + * unique() is stable, so the relative order of elements that are + * not removed is unchanged. + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!(*__dest == *__first)) + *++__dest = *__first; + return ++__dest; + } + + /** + * @brief Remove consecutive values from a sequence using a predicate. + * @param first A forward iterator. + * @param last A forward iterator. + * @param binary_pred A binary predicate. + * @return An iterator designating the end of the resulting sequence. + * + * Removes all but the first element from each group of consecutive + * values for which @p binary_pred returns true. + * unique() is stable, so the relative order of elements that are + * not removed is unchanged. + * Elements between the end of the resulting sequence and @p last + * are still present, but their value is unspecified. + */ + template + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last, __binary_pred); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!__binary_pred(*__dest, *__first)) + *++__dest = *__first; + return ++__dest; + } + + /** + * @if maint + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) + * overloaded for bidirectional iterators. + * @endif + */ + template + void + __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, + bidirectional_iterator_tag) + { + while (true) + if (__first == __last || __first == --__last) + return; + else + std::iter_swap(__first++, __last); + } + + /** + * @if maint + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) + * overloaded for bidirectional iterators. + * @endif + */ + template + void + __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + while (__first < __last) + std::iter_swap(__first++, --__last); + } + + /** + * @brief Reverse a sequence. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @return reverse() returns no value. + * + * Reverses the order of the elements in the range @p [first,last), + * so that the first element becomes the last etc. + * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse() + * swaps @p *(first+i) and @p *(last-(i+1)) + */ + template + inline void + reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_requires_valid_range(__first, __last); + std::__reverse(__first, __last, std::__iterator_category(__first)); + } + + /** + * @brief Copy a sequence, reversing its elements. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies the elements in the range @p [first,last) to the range + * @p [result,result+(last-first)) such that the order of the + * elements is reversed. + * For every @c i such that @p 0<=i<=(last-first), @p reverse_copy() + * performs the assignment @p *(result+(last-first)-i) = *(first+i). + * The ranges @p [first,last) and @p [result,result+(last-first)) + * must not overlap. + */ + template + _OutputIterator + reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + while (__first != __last) + { + --__last; + *__result = *__last; + ++__result; + } + return __result; + } + + + /** + * @if maint + * This is a helper function for the rotate algorithm specialized on RAIs. + * It returns the greatest common divisor of two integer values. + * @endif + */ + template + _EuclideanRingElement + __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) + { + while (__n != 0) + { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } + return __m; + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template + void + __rotate(_ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + forward_iterator_tag) + { + if ((__first == __middle) || (__last == __middle)) + return; + + _ForwardIterator __first2 = __middle; + do + { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } + while (__first2 != __last); + + __first2 = __middle; + + while (__first2 != __last) + { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template + void + __rotate(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + + if ((__first == __middle) || (__last == __middle)) + return; + + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + swap(*__first++, *--__last); + + if (__first == __middle) + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + else + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + } + + /** + * @if maint + * This is a helper function for the rotate algorithm. + * @endif + */ + template + void + __rotate(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + + if ((__first == __middle) || (__last == __middle)) + return; + + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + const _Distance __n = __last - __first; + const _Distance __k = __middle - __first; + const _Distance __l = __n - __k; + + if (__k == __l) + { + std::swap_ranges(__first, __middle, __middle); + return; + } + + const _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) + { + const _ValueType __tmp = *__first; + _RandomAccessIterator __p = __first; + + if (__k < __l) + { + for (_Distance __j = 0; __j < __l / __d; __j++) + { + if (__p > __first + __l) + { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + else + { + for (_Distance __j = 0; __j < __k / __d - 1; __j ++) + { + if (__p < __last - __k) + { + *__p = *(__p + __k); + __p += __k; + } + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + } + + /** + * @brief Rotate the elements of a sequence. + * @param first A forward iterator. + * @param middle A forward iterator. + * @param last A forward iterator. + * @return Nothing. + * + * Rotates the elements of the range @p [first,last) by @p (middle-first) + * positions so that the element at @p middle is moved to @p first, the + * element at @p middle+1 is moved to @first+1 and so on for each element + * in the range @p [first,last). + * + * This effectively swaps the ranges @p [first,middle) and + * @p [middle,last). + * + * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for + * each @p n in the range @p [0,last-first). + */ + template + inline void + rotate(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + typedef typename iterator_traits<_ForwardIterator>::iterator_category + _IterType; + std::__rotate(__first, __middle, __last, _IterType()); + } + + /** + * @brief Copy a sequence, rotating its elements. + * @param first A forward iterator. + * @param middle A forward iterator. + * @param last A forward iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies the elements of the range @p [first,last) to the range + * beginning at @result, rotating the copied elements by @p (middle-first) + * positions so that the element at @p middle is moved to @p result, the + * element at @p middle+1 is moved to @result+1 and so on for each element + * in the range @p [first,last). + * + * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for + * each @p n in the range @p [0,last-first). + */ + template + _OutputIterator + rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + return std::copy(__first, __middle, copy(__middle, __last, __result)); + } + + /** + * @brief Randomly shuffle the elements of a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @return Nothing. + * + * Reorder the elements in the range @p [first,last) using a random + * distribution, so that every possible ordering of the sequence is + * equally likely. + */ + template + inline void + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); + } + + /** + * @brief Shuffle the elements of a sequence using a random number + * generator. + * @param first A forward iterator. + * @param last A forward iterator. + * @param rand The RNG functor or function. + * @return Nothing. + * + * Reorders the elements in the range @p [first,last) using @p rand to + * provide a random distribution. Calling @p rand(N) for a positive + * integer @p N should return a randomly chosen integer from the + * range [0,N). + */ + template + void + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return; + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + __rand((__i - __first) + 1)); + } + + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _ForwardIterator + __partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, + forward_iterator_tag) + { + if (__first == __last) + return __first; + + while (__pred(*__first)) + if (++__first == __last) + return __first; + + _ForwardIterator __next = __first; + + while (++__next != __last) + if (__pred(*__next)) + { + swap(*__first, *__next); + ++__first; + } + + return __first; + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _BidirectionalIterator + __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, + _Predicate __pred, + bidirectional_iterator_tag) + { + while (true) + { + while (true) + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; + else + break; + --__last; + while (true) + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; + else + break; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @brief Move elements for which a predicate is true to the beginning + * of a sequence. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate functor. + * @return An iterator @p middle such that @p pred(i) is true for each + * iterator @p i in the range @p [first,middle) and false for each @p i + * in the range @p [middle,last). + * + * @p pred must not modify its operand. @p partition() does not preserve + * the relative ordering of elements in each group, use + * @p stable_partition() if this is needed. + */ + template + inline _ForwardIterator + partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__partition(__first, __last, __pred, + std::__iterator_category(__first)); + } + + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _ForwardIterator + __inplace_stable_partition(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, _Distance __len) + { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = std::__inplace_stable_partition(__first, + __middle, + __pred, + __len / 2); + _ForwardIterator __end = std::__inplace_stable_partition(__middle, __last, + __pred, + __len + - __len / 2); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _ForwardIterator + __stable_partition_adaptive(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) + { + if (__len <= __buffer_size) + { + _ForwardIterator __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) + { + *__result1 = *__first; + ++__result1; + } + else + { + *__result2 = *__first; + ++__result2; + } + std::copy(__buffer, __result2, __result1); + return __result1; + } + else + { + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = + std::__stable_partition_adaptive(__first, __middle, __pred, + __len / 2, __buffer, + __buffer_size); + _ForwardIterator __end = + std::__stable_partition_adaptive(__middle, __last, __pred, + __len - __len / 2, + __buffer, __buffer_size); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } + } + + /** + * @brief Move elements for which a predicate is true to the beginning + * of a sequence, preserving relative ordering. + * @param first A forward iterator. + * @param last A forward iterator. + * @param pred A predicate functor. + * @return An iterator @p middle such that @p pred(i) is true for each + * iterator @p i in the range @p [first,middle) and false for each @p i + * in the range @p [middle,last). + * + * Performs the same function as @p partition() with the additional + * guarantee that the relative ordering of elements in each group is + * preserved, so any two elements @p x and @p y in the range + * @p [first,last) such that @p pred(x)==pred(y) will have the same + * relative ordering after calling @p stable_partition(). + */ + template + _ForwardIterator + stable_partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + else + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, + __last); + if (__buf.size() > 0) + return + std::__stable_partition_adaptive(__first, __last, __pred, + _DistanceType(__buf.requested_size()), + __buf.begin(), __buf.size()); + else + return + std::__inplace_stable_partition(__first, __last, __pred, + _DistanceType(__buf.requested_size())); + } + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp __pivot) + { + while (true) + { + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * This is a helper function... + * @endif + */ + template + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Tp __pivot, _Compare __comp) + { + while (true) + { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } + } + + /** + * @if maint + * @doctodo + * This controls some aspect of the sort routines. + * @endif + */ + enum { _S_threshold = 16 }; + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val) + { + _RandomAccessIterator __next = __last; + --__next; + while (__val < *__next) + { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val, + _Compare __comp) + { + _RandomAccessIterator __next = __last; + --__next; + while (__comp(__val, *__next)) + { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__first == __last) + return; + + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__val < *__first) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val); + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__first == __last) return; + + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__comp(__val, *__first)) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val, __comp); + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + inline void + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i)); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + inline void + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__last - __first > _S_threshold) + { + std::__insertion_sort(__first, __first + _S_threshold); + std::__unguarded_insertion_sort(__first + _S_threshold, __last); + } + else + std::__insertion_sort(__first, __last); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first > _S_threshold) + { + std::__insertion_sort(__first, __first + _S_threshold, __comp); + std::__unguarded_insertion_sort(__first + _S_threshold, __last, + __comp); + } + else + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + inline _Size + __lg(_Size __n) + { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) + ++__k; + return __k; + } + + /** + * @brief Sort the smallest elements of a sequence. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the smallest @p (middle-first) elements in the range + * @p [first,last) and moves them to the range @p [first,middle). The + * order of the remaining elements in the range @p [middle,last) is + * undefined. + * After the sort if @p i and @j are iterators in the range + * @p [first,middle) such that @i precedes @j and @k is an iterator in + * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false. + */ + template + void + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::make_heap(__first, __middle); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + std::__pop_heap(__first, __middle, __i, _ValueType(*__i)); + std::sort_heap(__first, __middle); + } + + /** + * @brief Sort the smallest elements of a sequence using a predicate + * for comparison. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the smallest @p (middle-first) elements in the range + * @p [first,last) and moves them to the range @p [first,middle). The + * order of the remaining elements in the range @p [middle,last) is + * undefined. + * After the sort if @p i and @j are iterators in the range + * @p [first,middle) such that @i precedes @j and @k is an iterator in + * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i) + * are both false. + */ + template + void + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::make_heap(__first, __middle, __comp); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + std::__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp); + std::sort_heap(__first, __middle, __comp); + } + + /** + * @brief Copy the smallest elements of a sequence. + * @param first An iterator. + * @param last Another iterator. + * @param result_first A random-access iterator. + * @param result_last Another random-access iterator. + * @return An iterator indicating the end of the resulting sequence. + * + * Copies and sorts the smallest N values from the range @p [first,last) + * to the range beginning at @p result_first, where the number of + * elements to be copied, @p N, is the smaller of @p (last-first) and + * @p (result_last-result_first). + * After the sort if @p i and @j are iterators in the range + * @p [result_first,result_first+N) such that @i precedes @j then + * @p *j<*i is false. + * The value returned is @p result_first+N. + */ + template + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_InputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + std::make_heap(__result_first, __result_real_last); + while (__first != __last) + { + if (*__first < *__result_first) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first)); + ++__first; + } + std::sort_heap(__result_first, __result_real_last); + return __result_real_last; + } + + /** + * @brief Copy the smallest elements of a sequence using a predicate for + * comparison. + * @param first An input iterator. + * @param last Another input iterator. + * @param result_first A random-access iterator. + * @param result_last Another random-access iterator. + * @param comp A comparison functor. + * @return An iterator indicating the end of the resulting sequence. + * + * Copies and sorts the smallest N values from the range @p [first,last) + * to the range beginning at @p result_first, where the number of + * elements to be copied, @p N, is the smaller of @p (last-first) and + * @p (result_last-result_first). + * After the sort if @p i and @j are iterators in the range + * @p [result_first,result_first+N) such that @i precedes @j then + * @p comp(*j,*i) is false. + * The value returned is @p result_first+N. + */ + template + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _OutputValueType, _OutputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + std::make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) + { + if (__comp(*__first, *__result_first)) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first), + __comp); + ++__first; + } + std::sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > _S_threshold) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + std::__introsort_loop(__cut, __last, __depth_limit); + __last = __cut; + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > _S_threshold) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), + __comp); + std::__introsort_loop(__cut, __last, __depth_limit, __comp); + __last = __cut; + } + } + + /** + * @brief Sort the elements of a sequence. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. + */ + template + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, __lg(__last - __first) * 2); + std::__final_insertion_sort(__first, __last); + } + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for every iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. + */ + template + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, __lg(__last - __first) * 2, + __comp); + std::__final_insertion_sort(__first, __last, __comp); + } + } + + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. + * @ingroup binarysearch + */ + template + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // Note that these are slightly stricter than those of the 4-argument + // version, defined next. The difference is in the strictness of the + // comparison operations... so for looser checking, define your own + // comparison function, as was intended. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; + } + + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. + * @ingroup binarysearch + */ + template + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__val < *__middle) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; + } + + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2) + { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (*__middle < *__first) + std::iter_swap(__first, __middle); + return; + } + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22); + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Compare __comp) + { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (__comp(*__middle, *__first)) + std::iter_swap(__first, __middle); + return; + } + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22, __comp); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22, __comp); + } + + /** + * @if maint + * This is a helper function for the stable sorting routines. + * @endif + */ + template + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) + { + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle); + std::__inplace_stable_sort(__middle, __last); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); + } + + /** + * @if maint + * This is a helper function for the stable sorting routines. + * @endif + */ + template + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last, __comp); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle, __comp); + std::__inplace_stable_sort(__middle, __last, __comp); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); + } + + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + */ + template + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + template + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _Distance __step_size) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; + } + + __step_size = std::min(_Distance(__last - __first), __step_size); + std::merge(__first, __first + __step_size, __first + __step_size, __last, + __result); + } + + template + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, _Distance __step_size, + _Compare __comp) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; + } + __step_size = std::min(_Distance(__last - __first), __step_size); + + std::merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); + } + + enum { _S_chunk_size = 7 }; + + template + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size) + { + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last); + } + + template + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size, _Compare __comp) + { + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last, __comp); + } + + template + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; + } + } + + template + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, + __step_size, __comp); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, + __step_size, __comp); + __step_size *= 2; + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result) + { + if (__first1 == __last1) + return std::copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return std::copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) + { + if (*__last2 < *__last1) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result, + _Compare __comp) + { + if (__first1 == __last1) + return std::copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return std::copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) + { + if (__comp(*__last2, *__last1)) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + _BidirectionalIterator1 + __rotate_adaptive(_BidirectionalIterator1 __first, + _BidirectionalIterator1 __middle, + _BidirectionalIterator1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIterator2 __buffer, + _Distance __buffer_size) + { + _BidirectionalIterator2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) + { + __buffer_end = std::copy(__middle, __last, __buffer); + std::copy_backward(__first, __middle, __last); + return std::copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) + { + __buffer_end = std::copy(__first, __middle, __buffer); + std::copy(__middle, __last, __first); + return std::copy_backward(__buffer, __buffer_end, __last); + } + else + { + std::rotate(__first, __middle, __last); + std::advance(__first, std::distance(__middle, __last)); + return __first; + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) + { + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__merge_backward(__first, __middle, __buffer, + __buffer_end, __last); + } + else + { + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, + *__first_cut); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, + *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template + void + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__merge_backward(__first, __middle, __buffer, __buffer_end, + __last, __comp); + } + else + { + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); + } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, + __buffer_size, __comp); + } + } + + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + */ + template + void + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_sorted(__first, __middle); + __glibcxx_requires_sorted(__middle, __last); + + if (__first == __middle || __middle == __last) + return; + + _DistanceType __len1 = std::distance(__first, __middle); + _DistanceType __len2 = std::distance(__middle, __last); + + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size())); + } + + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A functor to use for comparisons. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + void + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_sorted_pred(__first, __middle, __comp); + __glibcxx_requires_sorted_pred(__middle, __last, __comp); + + if (__first == __middle || __middle == __last) + return; + + const _DistanceType __len1 = std::distance(__first, __middle); + const _DistanceType __len2 = std::distance(__middle, __last); + + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); + if (__buf.begin() == 0) + std::__merge_without_buffer(__first, __middle, __last, __len1, + __len2, __comp); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size()), + __comp); + } + + template + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, + __buffer, __buffer_size); + std::__stable_sort_adaptive(__middle, __last, + __buffer, __buffer_size); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer); + std::__merge_sort_with_buffer(__middle, __last, __buffer); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size); + } + + template + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, __buffer, + __buffer_size, __comp); + std::__stable_sort_adaptive(__middle, __last, __buffer, + __buffer_size, __comp); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); + std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size, + __comp); + } + + /** + * @brief Sort the elements of a sequence, preserving the relative order + * of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p x + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> + buf(__first, __last); + if (buf.begin() == 0) + std::__inplace_stable_sort(__first, __last); + else + std::__stable_sort_adaptive(__first, __last, buf.begin(), + _DistanceType(buf.size())); + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison, + * preserving the relative order of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for each iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p comp(x,y) is false and @p comp(y,x) is false will have the same + * relative ordering after calling @p stable_sort(). + */ + template + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last); + if (buf.begin() == 0) + std::__inplace_stable_sort(__first, __last, __comp); + else + std::__stable_sort_adaptive(__first, __last, buf.begin(), + _DistanceType(buf.size()), __comp); + } + + /** + * @brief Sort a sequence just enough to find a particular position. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p *j<*i is false. + */ + template + void + nth_element(_RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + while (__last - __first > 3) + { + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last); + } + + /** + * @brief Sort a sequence just enough to find a particular position + * using a predicate for comparison. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p comp(*j,*i) is false. + */ + template + void + nth_element(_RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + while (__last - __first > 3) + { + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val), + * upper_bound(first, last, val)) + * @endcode + * but does not actually call those functions. + */ + template + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val, comp), + * upper_bound(first, last, val, comp)) + * @endcode + * but does not actually call those functions. + */ + template + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, + _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val, __comp); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + */ + template + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); + } + + // Set algorithms: includes, set_union, set_intersection, set_difference, + // set_symmetric_difference. All of these algorithms have the precondition + // that their input ranges are sorted and the postcondition that their output + // ranges are sorted. + + /** + * @brief Determines whether all elements of a sequence exists in a range. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1). False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1). The iterators over each range only move forward, + * so this is a linear algorithm. If an element in [first2,last2) is not + * found before the search iterator reaches @a last2, false is returned. + */ + template + bool + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + return false; + else if(*__first1 < *__first2) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + + /** + * @brief Determines whether all elements of a sequence exists in a range + * using comparison. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @param comp Comparison function to use. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1) according to comp. False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1), using comp to decide. The iterators over each + * range only move forward, so this is a linear algorithm. If an element + * in [first2,last2) is not found before the search iterator reaches @a + * last2, false is returned. + */ + template + bool + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + return false; + else if(__comp(*__first1, *__first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + + /** + * @brief Return the union of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that element is copied and the iterator advanced. If an element is + * contained in both ranges, the element from the first range is copied and + * both ranges advance. The output range may not overlap either input + * range. + */ + template + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Return the union of two sorted ranges using a comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that element is copied and the iterator advanced. + * If an equivalent element according to @a comp is contained in both + * ranges, the element from the first range is copied and both ranges + * advance. The output range may not overlap either input range. + */ + template + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + /** + * @brief Return the intersection of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that iterator advances. If an element is contained in both ranges, the + * element from the first range is copied and both ranges advance. The + * output range may not overlap either input range. + */ + template + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; + } + + /** + * @brief Return the intersection of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that iterator advances. If an element is + * contained in both ranges according to @a comp, the element from the + * first range is copied and both ranges advance. The output range may not + * overlap either input range. + */ + template + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; + } + + /** + * @brief Return the difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second, that element is copied and the + * iterator advances. If the current element of the second range is less, + * the iterator advances, but no element is copied. If an element is + * contained in both ranges, no elements are copied and both ranges + * advance. The output range may not overlap either input range. + */ + template + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); + } + + /** + * @brief Return the difference of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second according to @a comp, that element + * is copied and the iterator advances. If the current element of the + * second range is less, no element is copied and the iterator advances. + * If an element is contained in both ranges according to @a comp, no + * elements are copied and both ranges advance. The output range may not + * overlap either input range. + */ + template + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + ++__first2; + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); + } + + /** + * @brief Return the symmetric difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other, that element is copied and the iterator advances. If an + * element is contained in both ranges, no elements are copied and both + * ranges advance. The output range may not overlap either input range. + */ + template + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); + } + + /** + * @brief Return the symmetric difference of two sorted ranges using + * comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other according to @a comp, that element is copied and the + * iterator advances. If an element is contained in both ranges according + * to @a comp, no elements are copied and both ranges advance. The output + * range may not overlap either input range. + */ + template + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); + } + + // min_element and max_element, with and without an explicitly supplied + // comparison function. + + /** + * @brief Return the maximum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the largest value. + */ + template + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; + } + + /** + * @brief Return the maximum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the largest value + * according to comp. + */ + template + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; + } + + /** + * @brief Return the minimum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the smallest value. + */ + template + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; + } + + /** + * @brief Return the minimum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the smallest value + * according to comp. + */ + template + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; + } + + // next_permutation and prev_permutation, with and without an explicitly + // supplied comparison function. + + /** + * @brief Permute range into the next "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the next one of this set. + * Returns true if there are more sequences to generate. If the sequence + * is the largest of the set, the smallest is generated and false returned. + */ + template + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__i < *__ii) + { + _BidirectionalIterator __j = __last; + while (!(*__i < *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the next "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the next one of this set. Returns true if there are more + * sequences to generate. If the sequence is the largest of the set, the + * smallest is generated and false returned. + */ + template + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__i, *__ii)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*__i, *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the previous "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the previous one of this + * set. Returns true if there are more sequences to generate. If the + * sequence is the smallest of the set, the largest is generated and false + * returned. + */ + template + bool + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__ii < *__i) + { + _BidirectionalIterator __j = __last; + while (!(*--__j < *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + /** + * @brief Permute range into the previous "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the previous one of this set. Returns true if there are + * more sequences to generate. If the sequence is the smallest of the set, + * the largest is generated and false returned. + */ + template + bool + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return false; + _BidirectionalIterator __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__ii, *__i)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*--__j, *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } + } + } + + // find_first_of, with and without an explicitly supplied comparison function. + + /** + * @brief Find element from a set in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c *i == @p *(i2) such that i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator + * in the range [first1,last1), otherwise returns @p last1. + */ + template + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; + } + + /** + * @brief Find element from a set in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @param comp Predicate to use. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c comp(*i, @p *(i2)) is true and i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator in + * the range [first1,last1), otherwise returns @p last1. + */ + template + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; + } + + + // find_end, with and without an explicitly supplied comparison function. + // Search [first2, last2) as a subsequence in [first1, last1), and return + // the *last* possible match. Note that find_end for bidirectional iterators + // is much faster than for forward iterators. + + // find_end for forward iterators. + template + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + forward_iterator_tag, forward_iterator_tag) + { + if (__first2 == __last2) + return __last1; + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } + } + + template + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) + { + if (__first2 == __last2) + return __last1; + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } + } + + // find_end for bidirectional iterators. Requires partial specialization. + template + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) + + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; + + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2); + + if (__rresult == __rlast1) + return __last1; + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } + } + + template + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) + + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; + + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2, + __comp); + + if (__rresult == __rlast1) + return __last1; + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } + } + + // Dispatching functions for find_end. + + /** + * @brief Find last matching subsequence in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. The sub-sequence will be the + * last such subsequence contained in [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2)); + } + + /** + * @brief Find last matching subsequence in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @param comp The predicate to use. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c predicate(*(i+N), @p + * (first2+N)) is true for each @c N in the range @p [0,last2-first2), or + * @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) using + * comp as a predicate and returns an iterator to the first element of the + * sub-sequence, or @p last1 if the sub-sequence is not found. The + * sub-sequence will be the last such subsequence contained in + * [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2), + __comp); + } + +} // namespace std + +#endif /* _ALGO_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algobase.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algobase.h new file mode 100644 index 00000000000..d482529bf9e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_algobase.h @@ -0,0 +1,842 @@ +// Bits and pieces used in algorithms -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_algobase.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALGOBASE_H +#define _ALGOBASE_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std +{ + /** + * @brief Swaps the contents of two iterators. + * @param a An iterator. + * @param b Another iterator. + * @return Nothing. + * + * This function swaps the values pointed to by two iterators, not the + * iterators themselves. + */ + template + inline void + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + { + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_ForwardIterator2>::value_type + _ValueType2; + + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType1, + _ValueType2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType2, + _ValueType1>) + + const _ValueType1 __tmp = *__a; + *__a = *__b; + *__b = __tmp; + } + + /** + * @brief Swaps two values. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return Nothing. + * + * This is the simple classic generic implementation. It will work on + * any type which has a copy constructor and an assignment operator. + */ + template + inline void + swap(_Tp& __a, _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) + + const _Tp __tmp = __a; + __a = __b; + __b = __tmp; + } + + #undef min + #undef max + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return The lesser of the parameters. + * + * This is the simple classic generic implementation. It will work on + * temporary expressions, since they are only evaluated once, unlike a + * preprocessor macro. + */ + template + inline const _Tp& + min(const _Tp& __a, const _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + //return __b < __a ? __b : __a; + if (__b < __a) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @return The greater of the parameters. + * + * This is the simple classic generic implementation. It will work on + * temporary expressions, since they are only evaluated once, unlike a + * preprocessor macro. + */ + template + inline const _Tp& + max(const _Tp& __a, const _Tp& __b) + { + // concept requirements + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + //return __a < __b ? __b : __a; + if (__a < __b) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return The lesser of the parameters. + * + * This will work on temporary expressions, since they are only evaluated + * once, unlike a preprocessor macro. + */ + template + inline const _Tp& + min(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + //return __comp(__b, __a) ? __b : __a; + if (__comp(__b, __a)) + return __b; + return __a; + } + + /** + * @brief This does what you think it does. + * @param a A thing of arbitrary type. + * @param b Another thing of arbitrary type. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return The greater of the parameters. + * + * This will work on temporary expressions, since they are only evaluated + * once, unlike a preprocessor macro. + */ + template + inline const _Tp& + max(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + //return __comp(__a, __b) ? __b : __a; + if (__comp(__a, __b)) + return __b; + return __a; + } + + // All of these auxiliary functions serve two purposes. (1) Replace + // calls to copy with memmove whenever possible. (Memmove, not memcpy, + // because the input and output ranges are permitted to overlap.) + // (2) If we're using random access iterators, then write the loop as + // a for loop with an explicit count. + + template + inline _OutputIterator + __copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, input_iterator_tag) + { + for (; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; + } + + template + inline _OutputIterator + __copy(_RandomAccessIterator __first, _RandomAccessIterator __last, + _OutputIterator __result, random_access_iterator_tag) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + for (_Distance __n = __last - __first; __n > 0; --__n) + { + *__result = *__first; + ++__first; + ++__result; + } + return __result; + } + + template + inline _Tp* + __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + std::memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); + } + + template + inline _OutputIterator + __copy_aux2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { return std::__copy(__first, __last, __result, + std::__iterator_category(__first)); } + + template + inline _OutputIterator + __copy_aux2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { return std::__copy(__first, __last, __result, + std::__iterator_category(__first)); } + + template + inline _Tp* + __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type) + { return std::__copy_trivial(__first, __last, __result); } + + template + inline _Tp* + __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, + __true_type) + { return std::__copy_trivial(__first, __last, __result); } + + template + inline _OutputIterator + __copy_ni2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { + typedef typename iterator_traits<_InputIterator>::value_type + _ValueType; + typedef typename __type_traits< + _ValueType>::has_trivial_assignment_operator _Trivial; + return _OutputIterator(std::__copy_aux2(__first, __last, __result.base(), + _Trivial())); + } + + template + inline _OutputIterator + __copy_ni2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + typedef typename __type_traits< + _ValueType>::has_trivial_assignment_operator _Trivial; + return std::__copy_aux2(__first, __last, __result, _Trivial()); + } + + template + inline _OutputIterator + __copy_ni1(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { + typedef typename _Is_normal_iterator<_OutputIterator>::_Normal __Normal; + return std::__copy_ni2(__first.base(), __last.base(), + __result, __Normal()); + } + + template + inline _OutputIterator + __copy_ni1(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { + typedef typename _Is_normal_iterator<_OutputIterator>::_Normal __Normal; + return std::__copy_ni2(__first, __last, __result, __Normal()); + } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). Result may not be contained within + * [first,last); the copy_backward function should be used instead. + * + * Note that the end of the output range is permitted to be contained + * within [first,last). + */ + template + inline _OutputIterator + copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal; + return std::__copy_ni1(__first, __last, __result, __Normal()); + } + + template + inline _BidirectionalIterator2 + __copy_backward(_BidirectionalIterator1 __first, + _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result, + bidirectional_iterator_tag) + { + while (__first != __last) + *--__result = *--__last; + return __result; + } + + template + inline _BidirectionalIterator + __copy_backward(_RandomAccessIterator __first, _RandomAccessIterator __last, + _BidirectionalIterator __result, random_access_iterator_tag) + { + typename iterator_traits<_RandomAccessIterator>::difference_type __n; + for (__n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; + } + + + // This dispatch class is a workaround for compilers that do not + // have partial ordering of function templates. All we're doing is + // creating a specialization so that we can turn a call to copy_backward + // into a memmove whenever possible. + template + struct __copy_backward_dispatch + { + static _BidirectionalIterator2 + copy(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) + { return std::__copy_backward(__first, __last, __result, + std::__iterator_category(__first)); } + }; + + template + struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + { + static _Tp* + copy(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + const ptrdiff_t _Num = __last - __first; + std::memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; + } + }; + + template + struct __copy_backward_dispatch + { + static _Tp* + copy(const _Tp* __first, const _Tp* __last, _Tp* __result) + { + return std::__copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); + } + }; + + template + inline _BI2 + __copy_backward_aux(_BI1 __first, _BI1 __last, _BI2 __result) + { + typedef typename __type_traits::value_type> + ::has_trivial_assignment_operator _Trivial; + return + std::__copy_backward_dispatch<_BI1, _BI2, _Trivial>::copy(__first, + __last, + __result); + } + + template + inline _BI2 + __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __true_type) + { return _BI2(std::__copy_backward_aux(__first, __last, __result.base())); } + + template + inline _BI2 + __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __false_type) + { return std::__copy_backward_aux(__first, __last, __result); } + + template + inline _BI2 + __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __true_type) + { + typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; + return std::__copy_backward_output_normal_iterator(__first.base(), + __last.base(), + __result, __Normal()); + } + + template + inline _BI2 + __copy_backward_input_normal_iterator(_BI1 __first, _BI1 __last, + _BI2 __result, __false_type) + { + typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; + return std::__copy_backward_output_normal_iterator(__first, __last, + __result, __Normal()); + } + + /** + * @brief Copies the range [first,last) into result. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result A bidirectional iterator. + * @return result - (first - last) + * + * The function has the same effect as copy, but starts at the end of the + * range and works its way to the start, returning the start of the result. + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). + * + * Result may not be in the range [first,last). Use copy instead. Note + * that the start of the output range may overlap [first,last). + */ + template + inline _BI2 + copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_BI1>::value_type, + typename iterator_traits<_BI2>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal; + return std::__copy_backward_input_normal_iterator(__first, __last, + __result, __Normal()); + } + + + /** + * @brief Fills the range [first,last) with copies of value. + * @param first A forward iterator. + * @param last A forward iterator. + * @param value A reference-to-const of arbitrary type. + * @return Nothing. + * + * This function fills a range with copies of the same value. For one-byte + * types filling contiguous areas of memory, this becomes an inline call to + * @c memset. + */ + template + void + fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + *__first = __value; + } + + /** + * @brief Fills the range [first,first+n) with copies of value. + * @param first An output iterator. + * @param n The count of copies to perform. + * @param value A reference-to-const of arbitrary type. + * @return The iterator at first+n. + * + * This function fills a range with copies of the same value. For one-byte + * types filling contiguous areas of memory, this becomes an inline call to + * @c memset. + */ + template + _OutputIterator + fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) + { + // concept requirements + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,_Tp>) + + for ( ; __n > 0; --__n, ++__first) + *__first = __value; + return __first; + } + + // Specialization: for one-byte types we can use memset. + inline void + fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const unsigned char __tmp = __c; + std::memset(__first, __tmp, __last - __first); + } + + inline void + fill(signed char* __first, signed char* __last, const signed char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const signed char __tmp = __c; + std::memset(__first, static_cast(__tmp), __last - __first); + } + + inline void + fill(char* __first, char* __last, const char& __c) + { + __glibcxx_requires_valid_range(__first, __last); + const char __tmp = __c; + std::memset(__first, static_cast(__tmp), __last - __first); + } + + template + inline unsigned char* + fill_n(unsigned char* __first, _Size __n, const unsigned char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + template + inline signed char* + fill_n(char* __first, _Size __n, const signed char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + template + inline char* + fill_n(char* __first, _Size __n, const char& __c) + { + std::fill(__first, __first + __n, __c); + return __first + __n; + } + + + /** + * @brief Finds the places in ranges which don't match. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @return A pair of iterators pointing to the first mismatch. + * + * This compares the elements of two ranges using @c == and returns a pair + * of iterators. The first iterator points into the first range, the + * second iterator points into the second range, and the elements pointed + * to by the iterators are not equal. + */ + template + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && *__first1 == *__first2) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + /** + * @brief Finds the places in ranges which don't match. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink. + * @return A pair of iterators pointing to the first mismatch. + * + * This compares the elements of two ranges using the binary_pred + * parameter, and returns a pair + * of iterators. The first iterator points into the first range, the + * second iterator points into the second range, and the elements pointed + * to by the iterators are not equal. + */ + template + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + } + + /** + * @brief Tests a range for element-wise equality. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @return A boolean true or false. + * + * This compares the elements of two ranges using @c == and returns true or + * false depending on whether all of the corresponding elements of the + * ranges are equal. + */ + template + inline bool + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + return false; + return true; + } + + /** + * @brief Tests a range for element-wise equality. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param binary_pred A binary predicate @link s20_3_1_base functor@endlink. + * @return A boolean true or false. + * + * This compares the elements of two ranges using the binary_pred + * parameter, and returns true or + * false depending on whether all of the corresponding elements of the + * ranges are equal. + */ + template + inline bool + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, + _BinaryPredicate __binary_pred) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) + return false; + return true; + } + + /** + * @brief Performs "dictionary" comparison on ranges. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @return A boolean true or false. + * + * "Returns true if the sequence of elements defined by the range + * [first1,last1) is lexicographically less than the sequence of elements + * defined by the range [first2,last2). Returns false otherwise." + * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, + * then this is an inline call to @c memcmp. + */ + template + bool + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for (;__first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + /** + * @brief Performs "dictionary" comparison on ranges. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @param comp A @link s20_3_3_comparisons comparison functor@endlink. + * @return A boolean true or false. + * + * The same as the four-parameter @c lexigraphical_compare, but uses the + * comp parameter instead of @c <. + */ + template + bool + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) + { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + + inline bool + lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = std::memcmp(__first1, __first2, + std::min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; + } + + inline bool + lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + +#if CHAR_MAX == SCHAR_MAX + return std::lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return std::lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ + } + +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_bvector.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_bvector.h new file mode 100644 index 00000000000..afae738418d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_bvector.h @@ -0,0 +1,876 @@ +// vector specialization -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1999 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_bvector.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BVECTOR_H +#define _BVECTOR_H 1 + +namespace _GLIBCXX_STD +{ + typedef unsigned long _Bit_type; + enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) }; + + struct _Bit_reference + { + _Bit_type * _M_p; + _Bit_type _M_mask; + + _Bit_reference(_Bit_type * __x, _Bit_type __y) + : _M_p(__x), _M_mask(__y) { } + + _Bit_reference() : _M_p(0), _M_mask(0) { } + + operator bool() const { return !!(*_M_p & _M_mask); } + + _Bit_reference& + operator=(bool __x) + { + if (__x) + *_M_p |= _M_mask; + else + *_M_p &= ~_M_mask; + return *this; + } + + _Bit_reference& + operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + + bool + operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + + bool + operator<(const _Bit_reference& __x) const + { return !bool(*this) && bool(__x); } + + void + flip() { *_M_p ^= _M_mask; } + }; + + struct _Bit_iterator_base : public iterator + { + _Bit_type * _M_p; + unsigned int _M_offset; + + _Bit_iterator_base(_Bit_type * __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) { } + + void + _M_bump_up() + { + if (_M_offset++ == _S_word_bit - 1) + { + _M_offset = 0; + ++_M_p; + } + } + + void + _M_bump_down() + { + if (_M_offset-- == 0) + { + _M_offset = _S_word_bit - 1; + --_M_p; + } + } + + void + _M_incr(ptrdiff_t __i) + { + difference_type __n = __i + _M_offset; + _M_p += __n / _S_word_bit; + __n = __n % _S_word_bit; + if (__n < 0) + { + _M_offset = static_cast(__n + _S_word_bit); + --_M_p; + } + else + _M_offset = static_cast(__n); + } + + bool + operator==(const _Bit_iterator_base& __i) const + { return _M_p == __i._M_p && _M_offset == __i._M_offset; } + + bool + operator<(const _Bit_iterator_base& __i) const + { + return _M_p < __i._M_p + || (_M_p == __i._M_p && _M_offset < __i._M_offset); + } + + bool + operator!=(const _Bit_iterator_base& __i) const + { return !(*this == __i); } + + bool + operator>(const _Bit_iterator_base& __i) const + { return __i < *this; } + + bool + operator<=(const _Bit_iterator_base& __i) const + { return !(__i < *this); } + + bool + operator>=(const _Bit_iterator_base& __i) const + { return !(*this < __i); } + }; + + inline ptrdiff_t + operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) + { + return _S_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset; + } + + struct _Bit_iterator : public _Bit_iterator_base + { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; + + _Bit_iterator() : _Bit_iterator_base(0, 0) { } + _Bit_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + + reference + operator*() const { return reference(_M_p, 1UL << _M_offset); } + + iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + iterator + operator++(int) + { + iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + iterator + operator--(int) + { + iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + iterator + operator+(difference_type __i) const + { + iterator __tmp = *this; + return __tmp += __i; + } + + iterator + operator-(difference_type __i) const + { + iterator __tmp = *this; + return __tmp -= __i; + } + + reference + operator[](difference_type __i) + { return *(*this + __i); } + }; + + inline _Bit_iterator + operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; } + + + struct _Bit_const_iterator : public _Bit_iterator_base + { + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } + _Bit_const_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + _Bit_const_iterator(const _Bit_iterator& __x) + : _Bit_iterator_base(__x._M_p, __x._M_offset) { } + + const_reference + operator*() const + { return _Bit_reference(_M_p, 1UL << _M_offset); } + + const_iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + const_iterator + operator++(int) + { + const_iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + const_iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + const_iterator + operator--(int) + { + const_iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + const_iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + const_iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + const_iterator + operator+(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp += __i; + } + + const_iterator + operator-(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp -= __i; + } + + const_reference + operator[](difference_type __i) + { return *(*this + __i); } + }; + + inline _Bit_const_iterator + operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) + { return __x + __n; } + + template + class _Bvector_base + { + typedef typename _Alloc::template rebind<_Bit_type>::other + _Bit_alloc_type; + + struct _Bvector_impl : public _Bit_alloc_type + { + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + _Bit_type* _M_end_of_storage; + _Bvector_impl(const _Bit_alloc_type& __a) + : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast(&this->_M_impl); } + + _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } + + ~_Bvector_base() { this->_M_deallocate(); } + + protected: + _Bvector_impl _M_impl; + + _Bit_type* + _M_allocate(size_t __n) + { return _M_impl.allocate((__n + _S_word_bit - 1) / _S_word_bit); } + + void + _M_deallocate() + { + if (_M_impl._M_start._M_p) + _M_impl.deallocate(_M_impl._M_start._M_p, + _M_impl._M_end_of_storage - _M_impl._M_start._M_p); + } + }; +} // namespace std + +// Declare a partial specialization of vector. +#include + +namespace _GLIBCXX_STD +{ + /** + * @brief A specialization of vector for booleans which offers fixed time + * access to individual elements in any order. + * + * Note that vector does not actually meet the requirements for being + * a container. This is because the reference and pointer types are not + * really references and pointers to bool. See DR96 for details. @see + * vector for function documentation. + * + * @ingroup Containers + * @ingroup Sequences + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ +template + class vector : public _Bvector_base<_Alloc> + { + public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + typedef typename _Bvector_base<_Alloc>::allocator_type allocator_type; + + allocator_type get_allocator() const + { return _Bvector_base<_Alloc>::get_allocator(); } + + protected: + using _Bvector_base<_Alloc>::_M_allocate; + using _Bvector_base<_Alloc>::_M_deallocate; + + protected: + void _M_initialize(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = __q + + (__n + _S_word_bit - 1) / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + } + + void _M_insert_aux(iterator __position, bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + { + std::copy_backward(__position, this->_M_impl._M_finish, + this->_M_impl._M_finish + 1); + *__position = __x; + ++this->_M_impl._M_finish; + } + else + { + const size_type __len = size() ? 2 * size() + : static_cast(_S_word_bit); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + + template + void _M_initialize_range(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + this->_M_impl._M_start = iterator(); + this->_M_impl._M_finish = iterator(); + this->_M_impl._M_end_of_storage = 0; + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + template + void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + _M_initialize(__n); + std::copy(__first, __last, this->_M_impl._M_start); + } + + template + void _M_insert_range(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template + void _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::copy(__first, __last, __position); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + __i = std::copy(__first, __last, __i); + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + } + + public: + iterator begin() + { return this->_M_impl._M_start; } + + const_iterator begin() const + { return this->_M_impl._M_start; } + + iterator end() + { return this->_M_impl._M_finish; } + + const_iterator end() const + { return this->_M_impl._M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + size_type size() const + { return size_type(end() - begin()); } + + size_type max_size() const + { return size_type(-1); } + + size_type capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) + - begin()); } + bool empty() const + { return begin() == end(); } + + reference operator[](size_type __n) + { return *(begin() + difference_type(__n)); } + + const_reference operator[](size_type __n) const + { return *(begin() + difference_type(__n)); } + + void _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("vector::_M_range_check")); + } + + reference at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + const_reference at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } + + explicit vector(const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) { } + + vector(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + __value ? ~0 : 0); + } + + explicit vector(size_type __n) + : _Bvector_base<_Alloc>(allocator_type()) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, 0); + } + + vector(const vector& __x) : _Bvector_base<_Alloc>(__x.get_allocator()) + { + _M_initialize(__x.size()); + std::copy(__x.begin(), __x.end(), this->_M_impl._M_start); + } + + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } + + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + ~vector() { } + + vector& operator=(const vector& __x) + { + if (&__x == this) + return *this; + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + std::copy(__x.begin(), __x.end(), begin()); + this->_M_impl._M_finish = begin() + difference_type(__x.size()); + return *this; + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void _M_fill_assign(size_t __n, bool __x) + { + if (__n > size()) + { + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else + { + erase(begin() + __n, end()); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + } + + void assign(size_t __n, bool __x) + { _M_fill_assign(__n, __x); } + + template + void assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_t) __n, (bool) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len < size()) + erase(std::copy(__first, __last, begin()), end()); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + + void reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = std::copy(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = __q + (__n + _S_word_bit - 1) / _S_word_bit; + } + } + + reference front() + { return *begin(); } + + const_reference front() const + { return *begin(); } + + reference back() + { return *(end() - 1); } + + const_reference back() const + { return *(end() - 1); } + + void push_back(bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(end(), __x); + } + + void swap(vector& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, + __x._M_impl._M_end_of_storage); + } + + // [23.2.5]/1, third-to-last entry in synopsis listing + static void swap(reference __x, reference __y) + { + bool __tmp = __x; + __x = __y; + __y = __tmp; + } + + iterator insert(iterator __position, bool __x = bool()) + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + && __position == end()) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { _M_fill_insert(__pos, __n, __x); } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { _M_insert_range(__pos, __first, __last, + std::__iterator_category(__first)); } + + template + void insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + void _M_fill_insert(iterator __position, size_type __n, bool __x) + { + if (__n == 0) + return; + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::fill(__position, __position + difference_type(__n), __x); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + std::fill_n(__i, __n, __x); + this->_M_impl._M_finish = std::copy(__position, end(), + __i + difference_type(__n)); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + + void insert(iterator __position, size_type __n, bool __x) + { _M_fill_insert(__position, __n, __x); } + + void pop_back() + { --this->_M_impl._M_finish; } + + iterator erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + return __position; + } + + iterator erase(iterator __first, iterator __last) + { + this->_M_impl._M_finish = std::copy(__last, end(), __first); + return __first; + } + + void resize(size_type __new_size, bool __x = bool()) + { + if (__new_size < size()) + erase(begin() + difference_type(__new_size), end()); + else + insert(end(), __new_size - size(), __x); + } + + void flip() + { + for (_Bit_type * __p = this->_M_impl._M_start._M_p; + __p != this->_M_impl._M_end_of_storage; ++__p) + *__p = ~*__p; + } + + void clear() + { erase(begin(), end()); } + }; +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_construct.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_construct.h new file mode 100644 index 00000000000..afb33879852 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_construct.h @@ -0,0 +1,157 @@ +// nonstandard construct and destroy functions -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_construct.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_CONSTRUCT_H +#define _STL_CONSTRUCT_H 1 + +#include +#include + +namespace std +{ + /** + * @if maint + * Constructs an object in existing memory by invoking an allocated + * object's constructor with an initializer. + * @endif + */ + template + inline void + _Construct(_T1* __p, const _T2& __value) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast(__p)) _T1(__value); + } + + /** + * @if maint + * Constructs an object in existing memory by invoking an allocated + * object's default constructor (no initializers). + * @endif + */ + template + inline void + _Construct(_T1* __p) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast(__p)) _T1(); + } + + /** + * @if maint + * Destroy the object pointed to by a pointer type. + * @endif + */ + template + inline void + _Destroy(_Tp* __pointer) + { __pointer->~_Tp(); } + + /** + * @if maint + * Destroy a range of objects with nontrivial destructors. + * + * This is a helper function used only by _Destroy(). + * @endif + */ + template + inline void + __destroy_aux(_ForwardIterator __first, _ForwardIterator __last, + __false_type) + { for ( ; __first != __last; ++__first) std::_Destroy(&*__first); } + + /** + * @if maint + * Destroy a range of objects with trivial destructors. Since the destructors + * are trivial, there's nothing to do and hopefully this function will be + * entirely optimized away. + * + * This is a helper function used only by _Destroy(). + * @endif + */ + template + inline void + __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) + { } + + /** + * @if maint + * Destroy a range of objects. If the value_type of the object has + * a trivial destructor, the compiler should optimize all of this + * away, otherwise the objects' destructors must be invoked. + * @endif + */ + template + inline void + _Destroy(_ForwardIterator __first, _ForwardIterator __last) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _Value_type; + typedef typename __type_traits<_Value_type>::has_trivial_destructor + _Has_trivial_destructor; + + std::__destroy_aux(__first, __last, _Has_trivial_destructor()); + } +} // namespace std + +#endif /* _STL_CONSTRUCT_H */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_deque.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_deque.h new file mode 100644 index 00000000000..54dadf2c659 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_deque.h @@ -0,0 +1,1501 @@ +// Deque implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_deque.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _DEQUE_H +#define _DEQUE_H 1 + +#include +#include +#include + +namespace _GLIBCXX_STD +{ + /** + * @if maint + * @brief This function controls the size of memory nodes. + * @param size The size of an element. + * @return The number (not byte size) of elements per node. + * + * This function started off as a compiler kludge from SGI, but seems to + * be a useful wrapper around a repeated constant expression. The '512' is + * tuneable (and no other code needs to change), but no investigation has + * been done since inheriting the SGI code. + * @endif + */ + inline size_t + __deque_buf_size(size_t __size) + { return __size < 512 ? size_t(512 / __size) : size_t(1); } + + + /** + * @brief A deque::iterator. + * + * Quite a bit of intelligence here. Much of the functionality of deque is + * actually passed off to this class. A deque holds two of these internally, + * marking its valid range. Access to elements is done as offsets of either + * of those two, relying on operator overloading in this class. + * + * @if maint + * All the functions are op overloads except for _M_set_node. + * @endif + */ + template + struct _Deque_iterator + { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} + + reference + operator*() const + { return *_M_cur; } + + pointer + operator->() const + { return _M_cur; } + + _Self& + operator++() + { + ++_M_cur; + if (_M_cur == _M_last) + { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + ++*this; + return __tmp; + } + + _Self& + operator--() + { + if (_M_cur == _M_first) + { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& + operator+=(difference_type __n) + { + const difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else + { + const difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) + / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + (__offset - __node_offset + * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self + operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& + operator-=(difference_type __n) + { return *this += -__n; } + + _Self + operator-(difference_type __n) const + { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference + operator[](difference_type __n) const + { return *(*this + __n); } + + /** @if maint + * Prepares to traverse new_node. Sets everything except _M_cur, which + * should therefore be set by the caller immediately afterwards, based on + * _M_first and _M_last. + * @endif + */ + void + _M_set_node(_Map_pointer __new_node) + { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } + }; + + // Note: we also provide overloads whose operands are of the same type in + // order to avoid ambiguous overload resolution when std::rel_ops operators + // are in scope (for additional details, see libstdc++/3628) + template + inline bool + operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x == __y); } + + template + inline bool + operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x == __y); } + + template + inline bool + operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template + inline bool + operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template + inline bool + operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __y < __x; } + + template + inline bool + operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__y < __x); } + + template + inline bool + operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x < __y); } + + template + inline bool + operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x < __y); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { + return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } + + template + inline _Deque_iterator<_Tp, _Ref, _Ptr> + operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + { return __x + __n; } + + /** + * @if maint + * Deque base class. This class provides the unified face for %deque's + * allocation. This class's constructor and destructor allocate and + * deallocate (but do not initialize) storage. This makes %exception + * safety easier. + * + * Nothing in this class ever constructs or destroys an actual Tp element. + * (Deque handles that itself.) Only/All memory management is performed + * here. + * @endif + */ + template + class _Deque_base + { + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast(&this->_M_impl); } + + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _M_impl(__a) + { _M_initialize_map(__num_elements); } + + _Deque_base(const allocator_type& __a) + : _M_impl(__a) + { } + + ~_Deque_base(); + + protected: + //This struct encapsulates the implementation of the std::deque + //standard container and at the same time makes use of the EBO + //for empty allocators. + struct _Deque_impl + : public _Alloc { + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + _Deque_impl(const _Alloc& __a) + : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish() + { } + }; + + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; + _Map_alloc_type _M_get_map_allocator() const + { return _Map_alloc_type(this->get_allocator()); } + + _Tp* + _M_allocate_node() + { return _M_impl._Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } + + void + _M_deallocate_node(_Tp* __p) + { _M_impl._Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } + + _Tp** + _M_allocate_map(size_t __n) + { return _M_get_map_allocator().allocate(__n); } + + void + _M_deallocate_map(_Tp** __p, size_t __n) + { _M_get_map_allocator().deallocate(__p, __n); } + + protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + + _Deque_impl _M_impl; + }; + + template + _Deque_base<_Tp,_Alloc>::~_Deque_base() + { + if (this->_M_impl._M_map) + { + _M_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + } + } + + /** + * @if maint + * @brief Layout storage. + * @param num_elements The count of T's for which to allocate space + * at first. + * @return Nothing. + * + * The initial underlying memory layout is a bit complicated... + * @endif + */ + template + void + _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) + { + size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; + + this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, + __num_nodes + 2); + this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); + + // For "small" maps (needing less than _M_map_size nodes), allocation + // starts in the middle elements and grows outwards. So nstart may be + // the beginning of _M_map, but for small maps it may be as far in as + // _M_map+3. + + _Tp** __nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + try + { _M_create_nodes(__nstart, __nfinish); } + catch(...) + { + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + this->_M_impl._M_map = 0; + this->_M_impl._M_map_size = 0; + __throw_exception_again; + } + + this->_M_impl._M_start._M_set_node(__nstart); + this->_M_impl._M_finish._M_set_node(__nfinish - 1); + this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first + __num_elements + % __deque_buf_size(sizeof(_Tp)); + } + + template + void + _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) + { + _Tp** __cur; + try + { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + } + catch(...) + { + _M_destroy_nodes(__nstart, __cur); + __throw_exception_again; + } + } + + template + void + _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + { + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); + } + + /** + * @brief A standard container using fixed-size memory allocation and + * constant-time manipulation of elements at either end. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence, including the + * optional sequence requirements. + * + * In previous HP/SGI versions of deque, there was an extra template + * parameter so users could control the node size. This extension turned + * out to violate the C++ standard (it can be detected using template + * template parameters), and it was removed. + * + * @if maint + * Here's how a deque manages memory. Each deque has 4 members: + * + * - Tp** _M_map + * - size_t _M_map_size + * - iterator _M_start, _M_finish + * + * map_size is at least 8. %map is an array of map_size pointers-to-"nodes". + * (The name %map has nothing to do with the std::map class, and "nodes" + * should not be confused with std::list's usage of "node".) + * + * A "node" has no specific type name as such, but it is referred to as + * "node" in this file. It is a simple array-of-Tp. If Tp is very large, + * there will be one Tp element per node (i.e., an "array" of one). + * For non-huge Tp's, node size is inversely related to Tp size: the + * larger the Tp, the fewer Tp's will fit in a node. The goal here is to + * keep the total size of a node relatively small and constant over different + * Tp's, to improve allocator efficiency. + * + * **** As I write this, the nodes are /not/ allocated using the high-speed + * memory pool. There are 20 hours left in the year; perhaps I can fix + * this before 2002. + * + * Not every pointer in the %map array will point to a node. If the initial + * number of elements in the deque is small, the /middle/ %map pointers will + * be valid, and the ones at the edges will be unused. This same situation + * will arise as the %map grows: available %map pointers, if any, will be on + * the ends. As new nodes are created, only a subset of the %map's pointers + * need to be copied "outward". + * + * Class invariants: + * - For any nonsingular iterator i: + * - i.node points to a member of the %map array. (Yes, you read that + * correctly: i.node does not actually point to a node.) The member of + * the %map array is what actually points to the node. + * - i.first == *(i.node) (This points to the node (first Tp element).) + * - i.last == i.first + node_size + * - i.cur is a pointer in the range [i.first, i.last). NOTE: + * the implication of this is that i.cur is always a dereferenceable + * pointer, even if i is a past-the-end iterator. + * - Start and Finish are always nonsingular iterators. NOTE: this means that + * an empty deque must have one node, a deque with > + class deque : protected _Deque_base<_Tp, _Alloc> + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Deque_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + typedef pointer* _Map_pointer; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + // Functions controlling memory layout, and nothing else. + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + /** @if maint + * A total of four data members accumulated down the heirarchy. + * May be accessed via _M_impl.* + * @endif + */ + using _Base::_M_impl; + + public: + // [23.2.1.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + + /** + * @brief Create a %deque with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %deque with @a n copies of @a value. + */ + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a, __n) + { _M_fill_initialize(__value); } + + /** + * @brief Create a %deque with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %deque with @a n copies of a + * default-constructed element. + */ + explicit + deque(size_type __n) + : _Base(allocator_type(), __n) + { _M_fill_initialize(value_type()); } + + /** + * @brief %Deque copy constructor. + * @param x A %deque of identical element and allocator types. + * + * The newly-created %deque uses a copy of the allocation object used + * by @a x. + */ + deque(const deque& __x) + : _Base(__x.get_allocator(), __x.size()) + { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_impl._M_start); } + + /** + * @brief Builds a %deque from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %deque consisting of copies of the elements from [first, + * last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. But if only + * input iterators are used, then this will do at most 2N calls to the + * copy constructor, and logN memory reallocations. + */ + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + ~deque() + { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } + + /** + * @brief %Deque assignment operator. + * @param x A %deque of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + deque& + operator=(const deque& __x); + + /** + * @brief Assigns a given value to a %deque. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %deque with @a n copies of the given value. + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements assigned. + * Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %deque with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements + * assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %deque. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_start; } + + /** + * Returns a read/write iterator that points one past the last element in + * the %deque. Iteration is done in ordinary element order. + */ + iterator + end() + { return this->_M_impl._M_finish; } + + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + end() const + { return this->_M_impl._M_finish; } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %deque. Iteration is done in reverse element order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last element in the %deque. Iteration is done in reverse element + * order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first element in the %deque. Iteration is done in reverse element + * order. + */ + reverse_iterator + rend() { return reverse_iterator(this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %deque. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->_M_impl._M_start); } + + // [23.2.1.2] capacity + /** Returns the number of elements in the %deque. */ + size_type + size() const + { return this->_M_impl._M_finish - this->_M_impl._M_start; } + + /** Returns the size() of the largest possible %deque. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x) + { + const size_type __len = size(); + if (__new_size < __len) + erase(this->_M_impl._M_start + __new_size, this->_M_impl._M_finish); + else + insert(this->_M_impl._M_finish, __new_size - __len, __x); + } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * + * This function will resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are default-constructed. + */ + void + resize(size_type new_size) + { resize(new_size, value_type()); } + + /** + * Returns true if the %deque is empty. (Thus begin() would equal end().) + */ + bool + empty() const + { return this->_M_impl._M_finish == this->_M_impl._M_start; } + + // element access + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + reference + operator[](size_type __n) + { return this->_M_impl._M_start[difference_type(__n)]; } + + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + const_reference + operator[](size_type __n) const + { return this->_M_impl._M_start[difference_type(__n)]; } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("deque::_M_range_check")); + } + + public: + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; + } + + /** + * Returns a read/write reference to the data at the first element of the + * %deque. + */ + reference + front() + { return *this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %deque. + */ + const_reference + front() const + { return *this->_M_impl._M_start; } + + /** + * Returns a read/write reference to the data at the last element of the + * %deque. + */ + reference + back() + { + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return *__tmp; + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %deque. + */ + const_reference + back() const + { + const_iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return *__tmp; + } + + // [23.2.1.2] modifiers + /** + * @brief Add data to the front of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the front of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ + void + push_front(const value_type& __x) + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + std::_Construct(this->_M_impl._M_start._M_cur - 1, __x); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(__x); + } + + /** + * @brief Add data to the end of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the end of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1) + { + std::_Construct(this->_M_impl._M_finish._M_cur, __x); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(__x); + } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the first element's data is + * needed, it should be retrieved before pop_front() is called. + */ + void + pop_front() + { + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) + { + std::_Destroy(this->_M_impl._M_start._M_cur); + ++this->_M_impl._M_start._M_cur; + } + else + _M_pop_front_aux(); + } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the last element's data is + * needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) + { + --this->_M_impl._M_finish._M_cur; + std::_Destroy(this->_M_impl._M_finish._M_cur); + } + else + _M_pop_back_aux(); + } + + /** + * @brief Inserts given value into %deque before specified iterator. + * @param position An iterator into the %deque. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before the + * specified location. + */ + iterator + insert(iterator position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %deque. + * @param position An iterator into the %deque. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the given + * data before the location specified by @a position. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %deque. + * @param position An iterator into the %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [first,last) + * into the %deque before the location specified by @a pos. This is + * known as "range insert." + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %deque by one. + * + * The user is cautioned that + * this function only erases the element, and that if the element is + * itself a pointer, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %deque accordingly. + * + * The user is cautioned that + * this function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %deque. + * @param x A %deque of the same element and allocator types. + * + * This exchanges the elements between two deques in constant time. + * (Four pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(d1,d2) will feed to this function. + */ + void + swap(deque& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_map, __x._M_impl._M_map); + std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); + } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void clear(); + + protected: + // Internal constructor functions follow. + + // called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + // called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // called by the second initialize_dispatch above + //@{ + /** + * @if maint + * @brief Fills the deque with whatever is in [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @return Nothing. + * + * If the iterators are actually forward iterators (or better), then the + * memory layout can be done all at once. Else we move forward using + * push_back on each value from the iterator. + * @endif + */ + template + void + _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second initialize_dispatch above + template + void + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + //@} + + /** + * @if maint + * @brief Fills the %deque with copies of value. + * @param value Initial value. + * @return Nothing. + * @pre _M_start and _M_finish have already been initialized, but none of + * the %deque's elements have yet been constructed. + * + * This function is called only when the user provides an explicit size + * (with or without an explicit exemplar value). + * @endif + */ + void + _M_fill_initialize(const value_type& __value); + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // called by the second assign_dispatch above + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second assign_dispatch above + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len > size()) + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + erase(std::copy(__first, __last, begin()), end()); + } + + // Called by assign(n,t), and the range assign when it turns out to be the + // same thing. + void + _M_fill_assign(size_type __n, const value_type& __val) + { + if (__n > size()) + { + std::fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else + { + erase(begin() + __n, end()); + std::fill(begin(), end(), __val); + } + } + + //@{ + /** + * @if maint + * @brief Helper functions for push_* and pop_*. + * @endif + */ + void _M_push_back_aux(const value_type&); + void _M_push_front_aux(const value_type&); + void _M_pop_back_aux(); + void _M_pop_front_aux(); + //@} + + // Internal insert functions follow. The *_aux functions do the actual + // insertion work when all shortcuts fail. + + // called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _Integer __n, _Integer __x, __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__x)); + } + + // called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + } + + // called by the second insert_dispatch above + template + void + _M_range_insert_aux(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag); + + // called by the second insert_dispatch above + template + void + _M_range_insert_aux(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. Can use fill functions in optimal situations, + // otherwise passes off to insert_aux(p,n,x). + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // called by insert(p,x) + iterator + _M_insert_aux(iterator __pos, const value_type& __x); + + // called by insert(p,n,x) via fill_insert + void + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + + // called by range_insert_aux for forward iterators + template + void + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the previous internal insert + * functions. + * @endif + */ + iterator + _M_reserve_elements_at_front(size_type __n) + { + const size_type __vacancies = this->_M_impl._M_start._M_cur + - this->_M_impl._M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return this->_M_impl._M_start - difference_type(__n); + } + + iterator + _M_reserve_elements_at_back(size_type __n) + { + const size_type __vacancies = (this->_M_impl._M_finish._M_last + - this->_M_impl._M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return this->_M_impl._M_finish + difference_type(__n); + } + + void + _M_new_elements_at_front(size_type __new_elements); + + void + _M_new_elements_at_back(size_type __new_elements); + //@} + + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the major %map. + * + * Makes sure the _M_map has space for new nodes. Does not actually add + * the nodes. Can invalidate _M_map pointers. (And consequently, %deque + * iterators.) + * @endif + */ + void + _M_reserve_map_at_back (size_type __nodes_to_add = 1) + { + if (__nodes_to_add + 1 > this->_M_impl._M_map_size + - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, false); + } + + void + _M_reserve_map_at_front (size_type __nodes_to_add = 1) + { + if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, true); + } + + void + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + //@} + }; + + + /** + * @brief Deque equality comparison. + * @param x A %deque. + * @param y A %deque of the same type as @a x. + * @return True iff the size and elements of the deques are equal. + * + * This is an equivalence relation. It is linear in the size of the + * deques. Deques are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } + + /** + * @brief Deque ordering relation. + * @param x A %deque. + * @param y A %deque of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * deques. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template + inline bool + operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x < __y); } + + /// See std::deque::swap(). + template + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _DEQUE_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_function.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_function.h new file mode 100644 index 00000000000..74ddcce9d8b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_function.h @@ -0,0 +1,898 @@ +// Functor implementations -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_function.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _FUNCTION_H +#define _FUNCTION_H 1 + +namespace std +{ + // 20.3.1 base classes + /** @defgroup s20_3_1_base Functor Base Classes + * Function objects, or @e functors, are objects with an @c operator() + * defined and accessible. They can be passed as arguments to algorithm + * templates and used in place of a function pointer. Not only is the + * resulting expressiveness of the library increased, but the generated + * code can be more efficient than what you might write by hand. When we + * refer to "functors," then, generally we include function pointers in + * the description as well. + * + * Often, functors are only created as temporaries passed to algorithm + * calls, rather than being created as named variables. + * + * Two examples taken from the standard itself follow. To perform a + * by-element addition of two vectors @c a and @c b containing @c double, + * and put the result in @c a, use + * \code + * transform (a.begin(), a.end(), b.begin(), a.begin(), plus()); + * \endcode + * To negate every element in @c a, use + * \code + * transform(a.begin(), a.end(), a.begin(), negate()); + * \endcode + * The addition and negation functions will be inlined directly. + * + * The standard functiors are derived from structs named @c unary_function + * and @c binary_function. These two classes contain nothing but typedefs, + * to aid in generic (template) programming. If you write your own + * functors, you might consider doing the same. + * + * @{ + */ + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template + struct unary_function + { + typedef _Arg argument_type; ///< @c argument_type is the type of the + /// argument (no surprises here) + + typedef _Result result_type; ///< @c result_type is the return type + }; + + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template + struct binary_function + { + typedef _Arg1 first_argument_type; ///< the type of the first argument + /// (no surprises here) + + typedef _Arg2 second_argument_type; ///< the type of the second argument + typedef _Result result_type; ///< type of the return type + }; + /** @} */ + + // 20.3.2 arithmetic + /** @defgroup s20_3_2_arithmetic Arithmetic Classes + * Because basic math often needs to be done during an algorithm, the library + * provides functors for those operations. See the documentation for + * @link s20_3_1_base the base classes@endlink for examples of their use. + * + * @{ + */ + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct plus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct minus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct multiplies : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct divides : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct modulus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct negate : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; + /** @} */ + + // 20.3.3 comparisons + /** @defgroup s20_3_3_comparisons Comparison Classes + * The library provides six wrapper functors for all the basic comparisons + * in C++, like @c <. + * + * @{ + */ + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct not_equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct greater : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct less : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct greater_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct less_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + /** @} */ + + // 20.3.4 logical operations + /** @defgroup s20_3_4_logical Boolean Operations Classes + * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. + * + * @{ + */ + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_and : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_or : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_not : public unary_function<_Tp, bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + /** @} */ + + // 20.3.5 negators + /** @defgroup s20_3_5_negators Negators + * The functions @c not1 and @c not2 each take a predicate functor + * and return an instance of @c unary_negate or + * @c binary_negate, respectively. These classes are functors whose + * @c operator() performs the stored predicate function and then returns + * the negation of the result. + * + * For example, given a vector of integers and a trivial predicate, + * \code + * struct IntGreaterThanThree + * : public std::unary_function + * { + * bool operator() (int x) { return x > 3; } + * }; + * + * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); + * \endcode + * The call to @c find_if will locate the first index (i) of @c v for which + * "!(v[i] > 3)" is true. + * + * The not1/unary_negate combination works on predicates taking a single + * argument. The not2/binary_negate combination works on predicates which + * take two arguments. + * + * @{ + */ + /// One of the @link s20_3_5_negators negation functors@endlink. + template + class unary_negate + : public unary_function + { + protected: + _Predicate _M_pred; + public: + explicit + unary_negate(const _Predicate& __x) : _M_pred(__x) {} + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } + + /// One of the @link s20_3_5_negators negation functors@endlink. + template + class binary_negate + : public binary_function + { + protected: + _Predicate _M_pred; + public: + explicit + binary_negate(const _Predicate& __x) + : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } + /** @} */ + + // 20.3.6 binders + /** @defgroup s20_3_6_binder Binder Classes + * Binders turn functions/functors with two arguments into functors with + * a single argument, storing an argument to be applied later. For + * example, an variable @c B of type @c binder1st is constructed from a + * functor @c f and an argument @c x. Later, B's @c operator() is called + * with a single argument @c y. The return value is the value of @c f(x,y). + * @c B can be "called" with various arguments (y1, y2, ...) and will in + * turn call @c f(x,y1), @c f(x,y2), ... + * + * The function @c bind1st is provided to save some typing. It takes the + * function and an argument as parameters, and returns an instance of + * @c binder1st. + * + * The type @c binder2nd and its creator function @c bind2nd do the same + * thing, but the stored argument is passed as the second parameter instead + * of the first, e.g., @c bind2nd(std::minus,1.3) will create a + * functor whose @c operator() accepts a floating-point number, subtracts + * 1.3 from it, and returns the result. (If @c bind1st had been used, + * the functor would perform "1.3 - x" instead. + * + * Creator-wrapper functions like @c bind1st are intended to be used in + * calling algorithms. Their return values will be temporary objects. + * (The goal is to not require you to type names like + * @c std::binder1st> for declaring a variable to hold the + * return value from @c bind1st(std::plus,5). + * + * These become more useful when combined with the composition functions. + * + * @{ + */ + /// One of the @link s20_3_6_binder binder functors@endlink. + template + class binder1st + : public unary_function + { + protected: + _Operation op; + typename _Operation::first_argument_type value; + public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template + inline binder1st<_Operation> + bind1st(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); + } + + /// One of the @link s20_3_6_binder binder functors@endlink. + template + class binder2nd + : public unary_function + { + protected: + _Operation op; + typename _Operation::second_argument_type value; + public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template + inline binder2nd<_Operation> + bind2nd(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); + } + /** @} */ + + // 20.3.7 adaptors pointers functions + /** @defgroup s20_3_7_adaptors Adaptors for pointers to functions + * The advantage of function objects over pointers to functions is that + * the objects in the standard library declare nested typedefs describing + * their argument and result types with uniform names (e.g., @c result_type + * from the base classes @c unary_function and @c binary_function). + * Sometimes those typedefs are required, not just optional. + * + * Adaptors are provided to turn pointers to unary (single-argument) and + * binary (double-argument) functions into function objects. The + * long-winded functor @c pointer_to_unary_function is constructed with a + * function pointer @c f, and its @c operator() called with argument @c x + * returns @c f(x). The functor @c pointer_to_binary_function does the same + * thing, but with a double-argument @c f and @c operator(). + * + * The function @c ptr_fun takes a pointer-to-function @c f and constructs + * an instance of the appropriate functor. + * + * @{ + */ + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + public: + pointer_to_unary_function() {} + + explicit + pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) {} + + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_unary_function<_Arg, _Result> + ptr_fun(_Result (*__x)(_Arg)) + { return pointer_to_unary_function<_Arg, _Result>(__x); } + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + public: + pointer_to_binary_function() {} + + explicit + pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_binary_function<_Arg1, _Arg2, _Result> + ptr_fun(_Result (*__x)(_Arg1, _Arg2)) + { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } + /** @} */ + + template + struct _Identity : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; + + template + struct _Select1st : public unary_function<_Pair, + typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + const typename _Pair::first_type& + operator()(const _Pair& __x) const + { return __x.first; } + }; + + template + struct _Select2nd : public unary_function<_Pair, + typename _Pair::second_type> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; + + // 20.3.8 adaptors pointers members + /** @defgroup s20_3_8_memadaptors Adaptors for pointers to members + * There are a total of 16 = 2^4 function objects in this family. + * (1) Member functions taking no arguments vs member functions taking + * one argument. + * (2) Call through pointer vs call through reference. + * (3) Member function with void return type vs member function with + * non-void return type. + * (4) Const vs non-const member function. + * + * Note that choice (3) is nothing more than a workaround: according + * to the draft, compilers should handle void and non-void the same way. + * This feature is not yet widely implemented, though. You can only use + * member functions returning void if your compiler supports partial + * specialization. + * + * All of this complexity is in the function objects themselves. You can + * ignore it by using the helper function mem_fun and mem_fun_ref, + * which create whichever type of adaptor is appropriate. + * + * @{ + */ + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit + mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit + mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_t : public binary_function + { + public: + explicit + const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, void> + { + public: + explicit + mem_fun_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} + + void + operator()(_Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit + const_mem_fun_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, void> + { + public: + explicit + mem_fun_ref_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} + + void + operator()(_Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, void> + { + public: + explicit + const_mem_fun_ref_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, void> + { + public: + explicit + mem_fun1_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_t + : public binary_function + { + public: + explicit + const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_ref_t + : public binary_function<_Tp, _Arg, void> + { + public: + explicit + mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_ref_t + : public binary_function<_Tp, _Arg, void> + { + public: + explicit + const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + // Mem_fun adaptor helper functions. There are only two: + // mem_fun and mem_fun_ref. + template + inline mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret, _Tp>(__f); } + + template + inline mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + /** @} */ + +} // namespace std + +#endif /* _FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_heap.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_heap.h new file mode 100644 index 00000000000..eff7fd351d7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_heap.h @@ -0,0 +1,467 @@ +// Heap implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_heap.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_HEAP_H +#define _STL_HEAP_H 1 + +#include + +namespace std +{ + // is_heap, a predicate testing whether or not a range is + // a heap. This function is an extension, not part of the C++ + // standard. + template + bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__first[__parent] < __first[__child]) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template + bool + __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp, + _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__comp(__first[__parent], __first[__child])) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } + + // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + + template + void + __push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; + } + + /** + * @brief Push an element onto a heap. + * @param first Start of heap. + * @param last End of heap + element. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + */ + template + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last - 1); + + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1))); + } + + template + void + __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) + { + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; + } + + /** + * @brief Push an element onto a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap + element. + * @param comp Comparison functor. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + * Compare operations are performed using comp. + */ + template + inline void + push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last - 1, __comp); + + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1)), __comp); + } + + template + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) + { + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) + { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value); + } + + template + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + *__result = *__first; + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value); + } + + /** + * @brief Pop an element off a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. + */ + template + inline void + pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); + + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1))); + } + + template + void + __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) + { + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) + { + if (__comp(*(__first + __secondChild), + *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) + { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp); + } + + template + inline void + __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + *__result = *__first; + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); + } + + /** + * @brief Pop an element off a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. Comparisons are + * made using comp. + */ + template + inline void + pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); + + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1)), __comp); + } + + /** + * @brief Construct a heap over a range. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + */ + template + void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent))); + if (__parent == 0) + return; + __parent--; + } + } + + /** + * @brief Construct a heap over a range using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + * Comparisons are made using comp. + */ + template + inline void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent)), __comp); + if (__parent == 0) + return; + __parent--; + } + } + + /** + * @brief Sort a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + */ + template + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last); + + while (__last - __first > 1) + std::pop_heap(__first, __last--); + } + + /** + * @brief Sort a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + * Comparisons are made using comp. + */ + template + void + sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); + + while (__last - __first > 1) + std::pop_heap(__first, __last--, __comp); + } + +} // namespace std + +#endif /* _STL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator.h new file mode 100644 index 00000000000..cc564314bc8 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator.h @@ -0,0 +1,772 @@ +// Iterators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file implements reverse_iterator, back_insert_iterator, + * front_insert_iterator, insert_iterator, __normal_iterator, and their + * supporting functions and overloaded operators. + */ + +#ifndef _ITERATOR_H +#define _ITERATOR_H 1 + +namespace std +{ + // 24.4.1 Reverse iterators + /** + * "Bidirectional and random access iterators have corresponding reverse + * %iterator adaptors that iterate through the data structure in the + * opposite direction. They have the same signatures as the corresponding + * iterators. The fundamental relation between a reverse %iterator and its + * corresponding %iterator @c i is established by the identity: + * @code + * &*(reverse_iterator(i)) == &*(i - 1) + * @endcode + * + * This mapping is dictated by the fact that while there is always a + * pointer past the end of an array, there might not be a valid pointer + * before the beginning of an array." [24.4.1]/1,2 + * + * Reverse iterators can be tricky and surprising at first. Their + * semantics make sense, however, and the trickiness is a side effect of + * the requirement that the iterators must be safe. + */ + template + class reverse_iterator + : public iterator::iterator_category, + typename iterator_traits<_Iterator>::value_type, + typename iterator_traits<_Iterator>::difference_type, + typename iterator_traits<_Iterator>::pointer, + typename iterator_traits<_Iterator>::reference> + { + protected: + _Iterator current; + + public: + typedef _Iterator iterator_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + public: + /** + * The default constructor default-initializes member @p current. + * If it is a pointer, that means it is zero-initialized. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 235 No specification of default ctor for reverse_iterator + reverse_iterator() : current() { } + + /** + * This %iterator will move in the opposite direction that @p x does. + */ + explicit + reverse_iterator(iterator_type __x) : current(__x) { } + + /** + * The copy constructor is normal. + */ + reverse_iterator(const reverse_iterator& __x) + : current(__x.current) { } + + /** + * A reverse_iterator across other types can be copied in the normal + * fashion. + */ + template + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) { } + + /** + * @return @c current, the %iterator used for underlying work. + */ + iterator_type + base() const + { return current; } + + /** + * @return TODO + * + * @doctodo + */ + reference + operator*() const + { + _Iterator __tmp = current; + return *--__tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + pointer + operator->() const + { return &(operator*()); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator++() + { + --current; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator++(int) + { + reverse_iterator __tmp = *this; + --current; + return __tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator--() + { + ++current; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator operator--(int) + { + reverse_iterator __tmp = *this; + ++current; + return __tmp; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator+(difference_type __n) const + { return reverse_iterator(current - __n); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator+=(difference_type __n) + { + current -= __n; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator + operator-(difference_type __n) const + { return reverse_iterator(current + __n); } + + /** + * @return TODO + * + * @doctodo + */ + reverse_iterator& + operator-=(difference_type __n) + { + current += __n; + return *this; + } + + /** + * @return TODO + * + * @doctodo + */ + reference + operator[](difference_type __n) const + { return *(*this + __n); } + }; + + //@{ + /** + * @param x A %reverse_iterator. + * @param y A %reverse_iterator. + * @return A simple bool. + * + * Reverse iterators forward many operations to their underlying base() + * iterators. Others are implemented in terms of one another. + * + */ + template + inline bool + operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __x.base() == __y.base(); } + + template + inline bool + operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() < __x.base(); } + + template + inline bool + operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return !(__x < __y); } + + template + inline typename reverse_iterator<_Iterator>::difference_type + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() - __x.base(); } + + template + inline reverse_iterator<_Iterator> + operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) + { return reverse_iterator<_Iterator>(__x.base() - __n); } + //@} + + // 24.4.2.2.1 back_insert_iterator + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator appends it to the container using + * push_back. + * + * Tip: Using the back_inserter function to create these iterators can + * save typing. + */ + template + class back_insert_iterator + : public iterator + { + protected: + _Container* container; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /// The only way to create this %iterator is with a container. + explicit + back_insert_iterator(_Container& __x) : container(&__x) { } + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the end, if you like). Assigning a value to the %iterator will + * always append the value to the end of the container. + */ + back_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_back(__value); + return *this; + } + + /// Simply returns *this. + back_insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + back_insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + back_insert_iterator + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of back_insert_iterator working on @p x. + * + * This wrapper function helps in creating back_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template + inline back_insert_iterator<_Container> + back_inserter(_Container& __x) + { return back_insert_iterator<_Container>(__x); } + + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator prepends it to the container using + * push_front. + * + * Tip: Using the front_inserter function to create these iterators can + * save typing. + */ + template + class front_insert_iterator + : public iterator + { + protected: + _Container* container; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /// The only way to create this %iterator is with a container. + explicit front_insert_iterator(_Container& __x) : container(&__x) { } + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the front, if you like). Assigning a value to the %iterator will + * always prepend the value to the front of the container. + */ + front_insert_iterator& + operator=(typename _Container::const_reference __value) + { + container->push_front(__value); + return *this; + } + + /// Simply returns *this. + front_insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + front_insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + front_insert_iterator + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of front_insert_iterator working on @p x. + * + * This wrapper function helps in creating front_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template + inline front_insert_iterator<_Container> + front_inserter(_Container& __x) + { return front_insert_iterator<_Container>(__x); } + + /** + * @brief Turns assignment into insertion. + * + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator inserts it in the container at the + * %iterator's position, rather than overwriting the value at that + * position. + * + * (Sequences will actually insert a @e copy of the value before the + * %iterator's position.) + * + * Tip: Using the inserter function to create these iterators can + * save typing. + */ + template + class insert_iterator + : public iterator + { + protected: + _Container* container; + typename _Container::iterator iter; + + public: + /// A nested typedef for the type of whatever container you used. + typedef _Container container_type; + + /** + * The only way to create this %iterator is with a container and an + * initial position (a normal %iterator into the container). + */ + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} + + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container. + * @return This %iterator, for chained operations. + * + * This kind of %iterator maintains its own position in the + * container. Assigning a value to the %iterator will insert the + * value into the container at the place before the %iterator. + * + * The position is maintained such that subsequent assignments will + * insert values immediately after one another. For example, + * @code + * // vector v contains A and Z + * + * insert_iterator i (v, ++v.begin()); + * i = 1; + * i = 2; + * i = 3; + * + * // vector v contains A, 1, 2, 3, and Z + * @endcode + */ + insert_iterator& + operator=(const typename _Container::const_reference __value) + { + iter = container->insert(iter, __value); + ++iter; + return *this; + } + + /// Simply returns *this. + insert_iterator& + operator*() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + insert_iterator& + operator++() + { return *this; } + + /// Simply returns *this. (This %iterator does not "move".) + insert_iterator& + operator++(int) + { return *this; } + }; + + /** + * @param x A container of arbitrary type. + * @return An instance of insert_iterator working on @p x. + * + * This wrapper function helps in creating insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ + template + inline insert_iterator<_Container> + inserter(_Container& __x, _Iterator __i) + { + return insert_iterator<_Container>(__x, + typename _Container::iterator(__i)); + } +} // namespace std + +namespace __gnu_cxx +{ + // This iterator adapter is 'normal' in the sense that it does not + // change the semantics of any of the operators of its iterator + // parameter. Its primary purpose is to convert an iterator that is + // not a class, e.g. a pointer, into an iterator that is a class. + // The _Container parameter exists solely so that different containers + // using this template can instantiate different types, even if the + // _Iterator parameter is the same. + using std::iterator_traits; + using std::iterator; + template + class __normal_iterator + { + protected: + _Iterator _M_current; + + public: + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; + + __normal_iterator() : _M_current(_Iterator()) { } + + explicit + __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + + // Allow iterator to const_iterator conversion + template + inline __normal_iterator(const __normal_iterator<_Iter, + _Container>& __i) + : _M_current(__i.base()) { } + + // Forward iterator requirements + reference + operator*() const + { return *_M_current; } + + pointer + operator->() const + { return _M_current; } + + __normal_iterator& + operator++() + { + ++_M_current; + return *this; + } + + __normal_iterator + operator++(int) + { return __normal_iterator(_M_current++); } + + // Bidirectional iterator requirements + __normal_iterator& + operator--() + { + --_M_current; + return *this; + } + + __normal_iterator + operator--(int) + { return __normal_iterator(_M_current--); } + + // Random access iterator requirements + reference + operator[](const difference_type& __n) const + { return _M_current[__n]; } + + __normal_iterator& + operator+=(const difference_type& __n) + { _M_current += __n; return *this; } + + __normal_iterator + operator+(const difference_type& __n) const + { return __normal_iterator(_M_current + __n); } + + __normal_iterator& + operator-=(const difference_type& __n) + { _M_current -= __n; return *this; } + + __normal_iterator + operator-(const difference_type& __n) const + { return __normal_iterator(_M_current - __n); } + + const _Iterator& + base() const + { return _M_current; } + }; + + // Note: In what follows, the left- and right-hand-side iterators are + // allowed to vary in types (conceptually in cv-qualification) so that + // comparaison between cv-qualified and non-cv-qualified iterators be + // valid. However, the greedy and unfriendly operators in std::rel_ops + // will make overload resolution ambiguous (when in scope) if we don't + // provide overloads whose operands are of the same type. Can someone + // remind me what generic programming is about? -- Gaby + + // Forward iterator requirements + template + inline bool + operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator==(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } + + template + inline bool + operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + template + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + // Random access iterator requirements + template + inline bool + operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator<(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } + + template + inline bool + operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator>(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } + + template + inline bool + operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } + + template + inline bool + operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + template + inline bool + operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename __normal_iterator<_IteratorL, _Container>::difference_type + operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } + + template + inline __normal_iterator<_Iterator, _Container> + operator+(typename __normal_iterator<_Iterator, _Container>::difference_type + __n, const __normal_iterator<_Iterator, _Container>& __i) + { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } +} // namespace __gnu_cxx + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_funcs.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_funcs.h new file mode 100644 index 00000000000..c514e81a089 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_funcs.h @@ -0,0 +1,179 @@ +// Functions used by iterators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator_base_funcs.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility + * functions, such as distance() and advance(). + */ + +#ifndef _ITERATOR_BASE_FUNCS_H +#define _ITERATOR_BASE_FUNCS_H 1 + +#pragma GCC system_header +#include + +namespace std +{ + template + inline typename iterator_traits<_InputIterator>::difference_type + __distance(_InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) + { + ++__first; + ++__n; + } + return __n; + } + + template + inline typename iterator_traits<_RandomAccessIterator>::difference_type + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + return __last - __first; + } + + /** + * @brief A generalization of pointer arithmetic. + * @param first An input iterator. + * @param last An input iterator. + * @return The distance between them. + * + * Returns @c n such that first + n == last. This requires that @p last + * must be reachable from @p first. Note that @c n may be negative. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. + */ + template + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + // concept requirements -- taken care of in __distance + return std::__distance(__first, __last, + std::__iterator_category(__first)); + } + + template + inline void + __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + while (__n--) + ++__i; + } + + template + inline void + __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + if (__n > 0) + while (__n--) + ++__i; + else + while (__n++) + --__i; + } + + template + inline void + __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __i += __n; + } + + /** + * @brief A generalization of pointer arithmetic. + * @param i An input iterator. + * @param n The "delta" by which to change @p i. + * @return Nothing. + * + * This increments @p i by @p n. For bidirectional and random access + * iterators, @p n may be negative, in which case @p i is decremented. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. + */ + template + inline void + advance(_InputIterator& __i, _Distance __n) + { + // concept requirements -- taken care of in __advance + std::__advance(__i, __n, std::__iterator_category(__i)); + } +} // namespace std + +#endif /* _ITERATOR_BASE_FUNCS_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_types.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_types.h new file mode 100644 index 00000000000..c3bb1c55727 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_iterator_base_types.h @@ -0,0 +1,170 @@ +// Types used in iterator implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_iterator_base_types.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility types, + * such as iterator_traits and struct iterator. + */ + +#ifndef _ITERATOR_BASE_TYPES_H +#define _ITERATOR_BASE_TYPES_H 1 + +#pragma GCC system_header + +namespace std +{ + //@{ + /** + * @defgroup iterator_tags Iterator Tags + * These are empty types, used to distinguish different iterators. The + * distinction is not made by what they contain, but simply by what they + * are. Different underlying algorithms can then be used based on the + * different operations supporetd by different iterator types. + */ + /// Marking input iterators. + struct input_iterator_tag {}; + /// Marking output iterators. + struct output_iterator_tag {}; + /// Forward iterators support a superset of input iterator operations. + struct forward_iterator_tag : public input_iterator_tag {}; + /// Bidirectional iterators support a superset of forward iterator + /// operations. + struct bidirectional_iterator_tag : public forward_iterator_tag {}; + /// Random-access iterators support a superset of bidirectional iterator + /// operations. + struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + //@} + + + /** + * @brief Common %iterator class. + * + * This class does nothing but define nested typedefs. %Iterator classes + * can inherit from this class to save some work. The typedefs are then + * used in specializations and overloading. + * + * In particular, there are no default implementations of requirements + * such as @c operator++ and the like. (How could there be?) + */ + template + struct iterator + { + /// One of the @link iterator_tags tag types@endlink. + typedef _Category iterator_category; + /// The type "pointed to" by the iterator. + typedef _Tp value_type; + /// Distance between iterators is represented as this type. + typedef _Distance difference_type; + /// This type represents a pointer-to-value_type. + typedef _Pointer pointer; + /// This type represents a reference-to-value_type. + typedef _Reference reference; + }; + + /** + * This class does nothing but define nested typedefs. The general + * version simply "forwards" the nested typedefs from the Iterator + * argument. Specialized versions for pointers and pointers-to-const + * provide tighter, more correct semantics. + */ + template + struct iterator_traits + { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; + }; + + template + struct iterator_traits<_Tp*> + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; + }; + + template + struct iterator_traits + { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + }; + + /** + * @if maint + * This function is not a part of the C++ standard but is syntactic + * sugar for internal library use only. + * @endif + */ + template + inline typename iterator_traits<_Iter>::iterator_category + __iterator_category(const _Iter&) + { return typename iterator_traits<_Iter>::iterator_category(); } + +} // namespace std + +#endif /* _ITERATOR_BASE_TYPES_H */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_list.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_list.h new file mode 100644 index 00000000000..afb118bb31e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_list.h @@ -0,0 +1,1255 @@ +// List implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_list.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LIST_H +#define _LIST_H 1 + +#include + +namespace _GLIBCXX_STD +{ + // Supporting structures are split into common and templated types; the + // latter publicly inherits from the former in an effort to reduce code + // duplication. This results in some "needless" static_cast'ing later on, + // but it's all safe downcasting. + + /// @if maint Common part of a node in the %list. @endif + struct _List_node_base + { + _List_node_base* _M_next; ///< Self-explanatory + _List_node_base* _M_prev; ///< Self-explanatory + + static void + swap(_List_node_base& __x, _List_node_base& __y); + + void + transfer(_List_node_base * const __first, + _List_node_base * const __last); + + void + reverse(); + + void + hook(_List_node_base * const __position); + + void + unhook(); + }; + + /// @if maint An actual node in the %list. @endif + template + struct _List_node : public _List_node_base + { + _Tp _M_data; ///< User's data. + }; + + /** + * @brief A list::iterator. + * + * @if maint + * All the functions are op overloads. + * @endif + */ + template + struct _List_iterator + { + typedef _List_iterator<_Tp> _Self; + typedef _List_node<_Tp> _Node; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + + _List_iterator() + : _M_node() { } + + _List_iterator(_List_node_base* __x) + : _M_node(__x) { } + + // Must downcast from List_node_base to _List_node to get to _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + _List_node_base* _M_node; + }; + + /** + * @brief A list::const_iterator. + * + * @if maint + * All the functions are op overloads. + * @endif + */ + template + struct _List_const_iterator + { + typedef _List_const_iterator<_Tp> _Self; + typedef const _List_node<_Tp> _Node; + typedef _List_iterator<_Tp> iterator; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + _List_const_iterator() + : _M_node() { } + + _List_const_iterator(const _List_node_base* __x) + : _M_node(__x) { } + + _List_const_iterator(const iterator& __x) + : _M_node(__x._M_node) { } + + // Must downcast from List_node_base to _List_node to get to + // _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + const _List_node_base* _M_node; + }; + + template + inline bool + operator==(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + + /** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif + */ + template + class _List_base + { + protected: + // NOTA BENE + // The stored instance is not actually of "allocator_type"'s + // type. Instead we rebind the type to + // Allocator>, which according to [20.1.5]/4 + // should probably be the same. List_node is not the same + // size as Tp (it's two pointers larger), and specializations on + // Tp may go unused because List_node is being bound + // instead. + // + // We put this to the test in the constructors and in + // get_allocator, where we use conversions between + // allocator_type and _Node_Alloc_type. The conversion is + // required by table 32 in [20.1.5]. + typedef typename _Alloc::template rebind<_List_node<_Tp> >::other + + _Node_Alloc_type; + + struct _List_impl + : public _Node_Alloc_type { + _List_node_base _M_node; + _List_impl (const _Node_Alloc_type& __a) + : _Node_Alloc_type(__a) + { } + }; + + _List_impl _M_impl; + + _List_node<_Tp>* + _M_get_node() + { return _M_impl._Node_Alloc_type::allocate(1); } + + void + _M_put_node(_List_node<_Tp>* __p) + { _M_impl._Node_Alloc_type::deallocate(__p, 1); } + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return allocator_type(*static_cast(&this->_M_impl)); } + + _List_base(const allocator_type& __a) + : _M_impl(__a) + { _M_init(); } + + // This is what actually destroys the list. + ~_List_base() + { _M_clear(); } + + void + _M_clear(); + + void + _M_init() + { + this->_M_impl._M_node._M_next = &this->_M_impl._M_node; + this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; + } + }; + + /** + * @brief A standard container with linear time access to elements, + * and fixed time insertion/deletion at any point in the sequence. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence, including the + * optional sequence requirements with the + * %exception of @c at and @c operator[]. + * + * This is a @e doubly @e linked %list. Traversal up and down the + * %list requires linear time, but adding and removing elements (or + * @e nodes) is done in constant time, regardless of where the + * change takes place. Unlike std::vector and std::deque, + * random-access iterators are not provided, so subscripting ( @c + * [] ) access is not allowed. For algorithms which only need + * sequential access, this lack makes no difference. + * + * Also unlike the other standard containers, std::list provides + * specialized algorithms %unique to linked lists, such as + * splicing, sorting, and in-place reversal. + * + * @if maint + * A couple points on memory allocation for list: + * + * First, we never actually allocate a Tp, we allocate + * List_node's and trust [20.1.5]/4 to DTRT. This is to ensure + * that after elements from %list are spliced into + * %list, destroying the memory of the second %list is a + * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. + * + * Second, a %list conceptually represented as + * @code + * A <---> B <---> C <---> D + * @endcode + * is actually circular; a link exists between A and D. The %list + * class holds (as its only data member) a private list::iterator + * pointing to @e D, not to @e A! To get to the head of the %list, + * we start at the tail and move forward by one. When this member + * iterator's next/previous pointers refer to itself, the %list is + * %empty. @endif + */ + template > + class list : protected _List_base<_Tp, _Alloc> + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _List_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef _List_iterator<_Tp> iterator; + typedef _List_const_iterator<_Tp> const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + // Note that pointers-to-_Node's can be ctor-converted to + // iterator types. + typedef _List_node<_Tp> _Node; + + /** @if maint + * One data member plus two memory-handling functions. If the + * _Alloc type requires separate instances, then one of those + * will also be included, accumulated from the topmost parent. + * @endif + */ + using _Base::_M_impl; + using _Base::_M_put_node; + using _Base::_M_get_node; + + /** + * @if maint + * @param x An instance of user data. + * + * Allocates space for a new node and constructs a copy of @a x in it. + * @endif + */ + _Node* + _M_create_node(const value_type& __x) + { + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data, __x); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; + } + + /** + * @if maint + * Allocates space for a new node and default-constructs a new + * instance of @c value_type in it. + * @endif + */ + _Node* + _M_create_node() + { + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; + } + + public: + // [23.2.2.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + list(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + /** + * @brief Create a %list with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %list with @a n copies of @a value. + */ + list(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __n, __value); } + + /** + * @brief Create a %list with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %list with @a n copies of a + * default-constructed element. + */ + explicit + list(size_type __n) + : _Base(allocator_type()) + { this->insert(begin(), __n, value_type()); } + + /** + * @brief %List copy constructor. + * @param x A %list of identical element and allocator types. + * + * The newly-created %list uses a copy of the allocation object used + * by @a x. + */ + list(const list& __x) + : _Base(__x.get_allocator()) + { this->insert(begin(), __x.begin(), __x.end()); } + + /** + * @brief Builds a %list from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %list consisting of copies of the elements from + * [@a first,@a last). This is linear in N (where N is + * distance(@a first,@a last)). + * + * @if maint + * We don't need any dispatching tricks here, because insert does all of + * that anyway. + * @endif + */ + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __first, __last); } + + /** + * No explicit dtor needed as the _Base dtor takes care of + * things. The _Base dtor only erases the elements, and note + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + + /** + * @brief %List assignment operator. + * @param x A %list of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy + * constructor, the allocator object is not copied. + */ + list& + operator=(const list& __x); + + /** + * @brief Assigns a given value to a %list. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %list with @a n copies of the given + * value. Note that the assignment completely changes the %list + * and that the resulting %list's size is the same as the number + * of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %list with copies of the elements in the + * range [@a first,@a last). + * + * Note that the assignment completely changes the %list and + * that the resulting %list's size is the same as the number of + * elements assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %list. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_node._M_next; } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_node._M_next; } + + /** + * Returns a read/write iterator that points one past the last + * element in the %list. Iteration is done in ordinary element + * order. + */ + iterator + end() { return &this->_M_impl._M_node; } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + end() const + { return &this->_M_impl._M_node; } + + /** + * Returns a read/write reverse iterator that points to the last + * element in the %list. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points to + * the last element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %list. Iteration is done in + * reverse element order. + */ + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // [23.2.2.2] capacity + /** + * Returns true if the %list is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } + + /** Returns the number of elements in the %list. */ + size_type + size() const + { return std::distance(begin(), end()); } + + /** Returns the size() of the largest possible %list. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %list to the specified number + * of elements. If the number is smaller than the %list's + * current size the %list is truncated, otherwise the %list is + * extended and new elements are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x); + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * + * This function will resize the %list to the specified number of + * elements. If the number is smaller than the %list's current + * size the %list is truncated, otherwise the %list is extended + * and new elements are default-constructed. + */ + void + resize(size_type __new_size) + { this->resize(__new_size, value_type()); } + + // element access + /** + * Returns a read/write reference to the data at the first + * element of the %list. + */ + reference + front() + { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %list. + */ + const_reference + front() const + { return *begin(); } + + /** + * Returns a read/write reference to the data at the last element + * of the %list. + */ + reference + back() + { return *(--end()); } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %list. + */ + const_reference + back() const + { return *(--end()); } + + // [23.2.2.3] modifiers + /** + * @brief Add data to the front of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the front of the %list and assigns the given data + * to it. Due to the nature of a %list this operation can be + * done in constant time, and does not invalidate iterators and + * references. + */ + void + push_front(const value_type& __x) + { this->_M_insert(begin(), __x); } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the first element's data + * is needed, it should be retrieved before pop_front() is + * called. + */ + void + pop_front() + { this->_M_erase(begin()); } + + /** + * @brief Add data to the end of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %list and assigns the given data to + * it. Due to the nature of a %list this operation can be done + * in constant time, and does not invalidate iterators and + * references. + */ + void + push_back(const value_type& __x) + { this->_M_insert(end(), __x); } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the last element's data + * is needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { this->_M_erase(this->_M_impl._M_node._M_prev); } + + /** + * @brief Inserts given value into %list before specified iterator. + * @param position An iterator into the %list. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Due to the nature of a %list this + * operation can be done in constant time, and does not + * invalidate iterators and references. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %list. + * @param position An iterator into the %list. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the + * given data before the location specified by @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %list. + * @param position An iterator into the %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [@a + * first,@a last) into the %list before the location specified by + * @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %list by one. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the element, and that if the element + * is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range @a + * [first,last) and shorten the %list accordingly. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + iterator + erase(iterator __first, iterator __last) + { + while (__first != __last) + __first = erase(__first); + return __last; + } + + /** + * @brief Swaps data with another %list. + * @param x A %list of the same element and allocator types. + * + * This exchanges the elements between two lists in constant + * time. Note that the global std::swap() function is + * specialized such that std::swap(l1,l2) will feed to this + * function. + */ + void + swap(list& __x) + { _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); } + + /** + * Erases all the elements. Note that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + void + clear() + { + _Base::_M_clear(); + _Base::_M_init(); + } + + // [23.2.2.4] list operations + /** + * @brief Insert contents of another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * + * The elements of @a x are inserted in constant time in front of + * the element referenced by @a position. @a x becomes an empty + * list. + */ + void + splice(iterator __position, list& __x) + { + if (!__x.empty()) + this->_M_transfer(__position, __x.begin(), __x.end()); + } + + /** + * @brief Insert element from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param i Iterator referencing the element to move. + * + * Removes the element in list @a x referenced by @a i and + * inserts it into the current list before @a position. + */ + void + splice(iterator __position, list&, iterator __i) + { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) + return; + this->_M_transfer(__position, __i, __j); + } + + /** + * @brief Insert range from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param first Iterator referencing the start of range in x. + * @param last Iterator referencing the end of range in x. + * + * Removes elements in the range [first,last) and inserts them + * before @a position in constant time. + * + * Undefined if @a position is in [first,last). + */ + void + splice(iterator __position, list&, iterator __first, iterator __last) + { + if (__first != __last) + this->_M_transfer(__position, __first, __last); + } + + /** + * @brief Remove all elements equal to value. + * @param value The value to remove. + * + * Removes every element in the list equal to @a value. + * Remaining elements stay in list order. Note that this + * function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + remove(const _Tp& __value); + + /** + * @brief Remove all elements satisfying a predicate. + * @param Predicate Unary predicate function or object. + * + * Removes every element in the list for which the predicate + * returns true. Remaining elements stay in list order. Note + * that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + template + void + remove_if(_Predicate); + + /** + * @brief Remove consecutive duplicate elements. + * + * For each consecutive set of elements with the same value, + * remove all but the first one. Remaining elements stay in + * list order. Note that this function only erases the + * elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + void + unique(); + + /** + * @brief Remove consecutive elements satisfying a predicate. + * @param BinaryPredicate Binary predicate function or object. + * + * For each consecutive set of elements [first,last) that + * satisfy predicate(first,i) where i is an iterator in + * [first,last), remove all but the first one. Remaining + * elements stay in list order. Note that this function only + * erases the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + template + void + unique(_BinaryPredicate); + + /** + * @brief Merge sorted lists. + * @param x Sorted list to merge. + * + * Assumes that both @a x and this list are sorted according to + * operator<(). Merges elements of @a x into this list in + * sorted order, leaving @a x empty when complete. Elements in + * this list precede elements in @a x that are equal. + */ + void + merge(list& __x); + + /** + * @brief Merge sorted lists according to comparison function. + * @param x Sorted list to merge. + * @param StrictWeakOrdering Comparison function definining + * sort order. + * + * Assumes that both @a x and this list are sorted according to + * StrictWeakOrdering. Merges elements of @a x into this list + * in sorted order, leaving @a x empty when complete. Elements + * in this list precede elements in @a x that are equivalent + * according to StrictWeakOrdering(). + */ + template + void + merge(list&, _StrictWeakOrdering); + + /** + * @brief Reverse the elements in list. + * + * Reverse the order of elements in the list in linear time. + */ + void + reverse() + { this->_M_impl._M_node.reverse(); } + + /** + * @brief Sort the elements. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + void + sort(); + + /** + * @brief Sort the elements according to comparison function. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + template + void + sort(_StrictWeakOrdering); + + protected: + // Internal assign functions follow. + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__x)); + } + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + for ( ; __first != __last; ++__first) + _M_insert(__pos, *__first); + } + + // Called by insert(p,n,x), and the range insert when it turns out + // to be the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) + { + for ( ; __n > 0; --__n) + _M_insert(__pos, __x); + } + + + // Moves the elements from [first,last) before position. + void + _M_transfer(iterator __position, iterator __first, iterator __last) + { __position._M_node->transfer(__first._M_node,__last._M_node); } + + // Inserts new element at position given and with value given. + void + _M_insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); + } + + // Erases element at position given. + void + _M_erase(iterator __position) + { + __position._M_node->unhook(); + _Node* __n = static_cast<_Node*>(__position._M_node); + std::_Destroy(&__n->_M_data); + _M_put_node(__n); + } + }; + + /** + * @brief List equality comparison. + * @param x A %list. + * @param y A %list of the same type as @a x. + * @return True iff the size and elements of the lists are equal. + * + * This is an equivalence relation. It is linear in the size of + * the lists. Lists are considered equivalent if their sizes are + * equal, and if corresponding elements compare equal. + */ + template + inline bool + operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { + typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = __x.end(); + const_iterator __end2 = __y.end(); + + const_iterator __i1 = __x.begin(); + const_iterator __i2 = __y.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; + } + + /** + * @brief List ordering relation. + * @param x A %list. + * @param y A %list of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * lists. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + + /// Based on operator== + template + inline bool + operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::list::swap(). + template + inline void + swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _LIST_H */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_map.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_map.h new file mode 100644 index 00000000000..8535ae5f268 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_map.h @@ -0,0 +1,694 @@ +// Map implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_map.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MAP_H +#define _MAP_H 1 + +#include + +namespace _GLIBCXX_STD +{ + /** + * @brief A standard container made up of (key,value) pairs, which can be + * retrieved based on a key, in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using unique keys). + * For a @c map the key_type is Key, the mapped_type is T, and the + * value_type is std::pair. + * + * Maps support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for map and + * multimap; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template , + typename _Alloc = allocator > > + class map + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function + { + friend class map<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.1.1] construct/copy/destroy + // (get_allocator() is normally listed in this section, but seems to have + // been accidentally omitted in the printed standard) + /** + * @brief Default constructor creates no elements. + */ + map() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + map(const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Map copy constructor. + * @param x A %map of identical element and allocator types. + * + * The newly-created %map uses a copy of the allocation object used + * by @a x. + */ + map(const map& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_unique(__first, __last); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief Map assignment operator. + * @param x A %map of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + map& + operator=(const map& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %map. + * Iteration is done in ascending order according to the keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %map. Iteration is done in ascending order according to the + * keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %map. Iteration is done in ascending order according to the keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %map. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %map. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %map. Iteration is done in descending + * order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %map is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %map. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %map. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // [23.3.1.2] element access + /** + * @brief Subscript ( @c [] ) access to %map data. + * @param k The key for which data should be retrieved. + * @return A reference to the data of the (key,data) %pair. + * + * Allows for easy lookup with the subscript ( @c [] ) operator. Returns + * data associated with the key specified in subscript. If the key does + * not exist, a pair with that key is created using default values, which + * is then returned. + * + * Lookup requires logarithmic time. + */ + mapped_type& + operator[](const key_type& __k) + { + // concept requirements + __glibcxx_function_requires(_DefaultConstructibleConcept) + + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, mapped_type())); + return (*__i).second; + } + + // modifiers + /** + * @brief Attempts to insert a std::pair into the %map. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted pair, and the second is a bool that + * is true if the pair was actually inserted. + * + * This function attempts to insert a (key, value) %pair into the %map. + * A %map relies on unique keys and thus a %pair is only inserted if its + * first element (the key) is not already present in the %map. + * + * Insertion requires logarithmic time. + */ + pair + insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + + /** + * @brief Attempts to insert a std::pair into the %map. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return An iterator that points to the element with key of @a x (may + * or may not be the %pair passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument + * insert() does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %map. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %map. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %map. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %map. + * @param x A %map of the same element and allocator types. + * + * This exchanges the elements between two maps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(map& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %map. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %map was + * constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %map was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // [23.3.1.3] map operations + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + * + * This function only makes sense for multimaps; for map the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + + template + friend bool + operator< (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + }; + + /** + * @brief Map equality comparison. + * @param x A %map. + * @param y A %map of the same type as @a x. + * @return True iff the size and elements of the maps are equal. + * + * This is an equivalence relation. It is linear in the size of the + * maps. Maps are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Map ordering relation. + * @param x A %map. + * @param y A %map of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Based on operator== + template + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::map::swap(). + template + inline void + swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _MAP_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multimap.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multimap.h new file mode 100644 index 00000000000..e080f9aaba7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multimap.h @@ -0,0 +1,677 @@ +// Multimap implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_multimap.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MULTIMAP_H +#define _MULTIMAP_H 1 + +#include + +namespace _GLIBCXX_STD +{ + // Forward declaration of operators < and ==, needed for friend declaration. + + template , + typename _Alloc = allocator > > + class multimap; + + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of (key,value) pairs, which can be + * retrieved based on a key, in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using equivalent + * keys). For a @c multimap the key_type is Key, the mapped_type + * is T, and the value_type is std::pair. + * + * Multimaps support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for map and + * multimap; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template + class multimap + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function + { + friend class multimap<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.2] construct/copy/destroy + // (get_allocator() is also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + multimap() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief %Multimap copy constructor. + * @param x A %multimap of identical element and allocator types. + * + * The newly-created %multimap uses a copy of the allocation object used + * by @a x. + */ + multimap(const multimap& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_equal(__first, __last); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief %Multimap assignment operator. + * @param x A %multimap of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multimap& + operator=(const multimap& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %multimap. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %multimap. Iteration is done in ascending order according + * to the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %multimap. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %multimap. Iteration is done in + * descending order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %multimap is empty. */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %multimap. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %multimap. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // modifiers + /** + * @brief Inserts a std::pair into the %multimap. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts a std::pair into the %multimap. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t.insert_equal(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multimap. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multimap. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multimap. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multimap. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multimap. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %multimap. + * @param x A %multimap of the same element and allocator types. + * + * This exchanges the elements between two multimaps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(multimap& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %multimap. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %multimap + * was constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %multimap was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // multimap operations + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to sought-after element, + * or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful the iterator will point + * to the next greatest element or, if no such greater element exists, to + * end(). + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); + + template + friend bool + operator< (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); + }; + + /** + * @brief Multimap equality comparison. + * @param x A %multimap. + * @param y A %multimap of the same type as @a x. + * @return True iff the size and elements of the maps are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multimaps. Multimaps are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Multimap ordering relation. + * @param x A %multimap. + * @param y A %multimap of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * multimaps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Based on operator== + template + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::multimap::swap(). + template + inline void + swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, + multimap<_Key,_Tp,_Compare,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _MULTIMAP_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multiset.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multiset.h new file mode 100644 index 00000000000..c82dee68e4e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_multiset.h @@ -0,0 +1,585 @@ +// Multiset implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_multiset.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _MULTISET_H +#define _MULTISET_H 1 + +#include + +namespace _GLIBCXX_STD +{ + + // Forward declaration of operators < and ==, needed for friend declaration. + template , + class _Alloc = allocator<_Key> > + class multiset; + + template + inline bool + operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + + template + inline bool + operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of elements, which can be retrieved + * in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using equivalent + * keys). For a @c multiset the key_type and value_type are Key. + * + * Multisets support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template + class multiset + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + + private: + /// @if maint This turns a red-black tree into a [multi]set. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + /** + * @brief Default constructor creates no elements. + */ + multiset() + : _M_t(_Compare(), allocator_type()) { } + + explicit + multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief %Multiset copy constructor. + * @param x A %multiset of identical element and allocator types. + * + * The newly-created %multiset uses a copy of the allocation object used + * by @a x. + */ + multiset(const multiset<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief %Multiset assignment operator. + * @param x A %multiset of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %multiset. + * @param x A %multiset of the same element and allocator types. + * + * This exchanges the elements between two multisets in constant time. + * (It is only swapping a pointer, an integer, and an instance of the @c + * Compare type (which itself is often stateless and empty), so it should + * be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(multiset<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Inserts an element into the %multiset. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts an element into the %multiset. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); + } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multiset. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multiset. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multiset. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multiset. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multiset. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %multiset. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // multiset operations: + + /** + * @brief Finds the number of elements with given key. + * @param x Key of elements to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + + template + friend bool + operator< (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + }; + + /** + * @brief Multiset equality comparison. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff the size and elements of the multisets are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multisets. + * Multisets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + template + inline bool + operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Multiset ordering relation. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Returns !(x == y). + template + inline bool + operator!=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template + inline bool + operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template + inline bool + operator<=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template + inline bool + operator>=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::multiset::swap(). + template + inline void + swap(multiset<_Key,_Compare,_Alloc>& __x, + multiset<_Key,_Compare,_Alloc>& __y) + { __x.swap(__y); } + +} // namespace std + +#endif /* _MULTISET_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_numeric.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_numeric.h new file mode 100644 index 00000000000..58762a40a7d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_numeric.h @@ -0,0 +1,326 @@ +// Numeric functions implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_numeric.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_NUMERIC_H +#define _STL_NUMERIC_H 1 + +#include + +namespace std +{ + + /** + * @brief Accumulate values in a range. + * + * Accumulates the values in the range [first,last) using operator+(). The + * initial value is @a init. The values are processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @return The final sum. + */ + template + _Tp + accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; + } + + /** + * @brief Accumulate values in a range with operation. + * + * Accumulates the values in the range [first,last) using the function + * object @a binary_op. The initial value is @a init. The values are + * processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @param binary_op Function object to accumulate with. + * @return The final sum. + */ + template + _Tp + accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; + } + + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, multiplies successive + * elements from the two ranges and adds each product into the accumulated + * value using operator+(). The values in the ranges are processed in + * order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @return The final inner product. + */ + template + _Tp + inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; + } + + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, applies @a binary_op2 to + * successive elements from the two ranges and accumulates each result into + * the accumulated value using @a binary_op1. The values in the ranges are + * processed in order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @param binary_op1 Function object to accumulate with. + * @param binary_op2 Function object to apply to pairs of input values. + * @return The final inner product. + */ + template + _Tp + inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; + } + + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + __value = __value + *__first; + *++__result = __value; + } + return ++__result; + } + + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + __value = __binary_op(__value, *__first); + *++__result = __value; + } + return ++__result; + } + + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using operator-() and writes the result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + adjacent_difference(_InputIterator __first, + _InputIterator __last, _OutputIterator __result) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + _ValueType __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; + } + return ++__result; + } + + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using the function object @a binary_op and writes the + * result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ + template + _OutputIterator + adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) return __result; + *__result = *__first; + _ValueType __value = *__first; + while (++__first != __last) { + _ValueType __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; + } + return ++__result; + } + +} // namespace std + +#endif /* _STL_NUMERIC_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_pair.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_pair.h new file mode 100644 index 00000000000..d5146bb5943 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_pair.h @@ -0,0 +1,147 @@ +// Pair implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_pair.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _PAIR_H +#define _PAIR_H 1 + +namespace std +{ + /// pair holds two objects of arbitrary type. + template + struct pair + { + typedef _T1 first_type; ///< @c first_type is the first bound type + typedef _T2 second_type; ///< @c second_type is the second bound type + + _T1 first; ///< @c first is a copy of the first object + _T2 second; ///< @c second is a copy of the second object + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 265. std::pair::pair() effects overly restrictive + /** The default constructor creates @c first and @c second using their + * respective default constructors. */ + pair() + : first(), second() { } + + /** Two objects may be passed to a @c pair constructor to be copied. */ + pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + /** There is also a templated copy ctor for the @c pair class itself. */ + template + pair(const pair<_U1, _U2>& __p) + : first(__p.first), second(__p.second) { } + }; + + /// Two pairs of the same type are equal iff their members are equal. + template + inline bool + operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first == __y.first && __x.second == __y.second; } + + /// + template + inline bool + operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __x.first < __y.first + || (!(__y.first < __x.first) && __x.second < __y.second); } + + /// Uses @c operator== to find the result. + template + inline bool + operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x == __y); } + + /// Uses @c operator< to find the result. + template + inline bool + operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __y < __x; } + + /// Uses @c operator< to find the result. + template + inline bool + operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__y < __x); } + + /// Uses @c operator< to find the result. + template + inline bool + operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x < __y); } + + /** + * @brief A convenience wrapper for creating a pair from two objects. + * @param x The first object. + * @param y The second object. + * @return A newly-constructed pair<> object of the appropriate type. + * + * The standard requires that the objects be passed by reference-to-const, + * but LWG issue #181 says they should be passed by const value. We follow + * the LWG by default. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 181. make_pair() unintended behavior + template + inline pair<_T1, _T2> + make_pair(_T1 __x, _T2 __y) { return pair<_T1, _T2>(__x, __y); } +} // namespace std + +#endif /* _PAIR_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_queue.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_queue.h new file mode 100644 index 00000000000..3583547dbb4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_queue.h @@ -0,0 +1,472 @@ +// Queue implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_queue.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _QUEUE_H +#define _QUEUE_H 1 + +#include +#include + +namespace std +{ + // Forward declarations of operators < and ==, needed for friend declaration. + template > + class queue; + + template + inline bool + operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + + template + inline bool + operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + + /** + * @brief A standard container giving FIFO behavior. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets many of the requirements of a + * container, + * but does not define anything to do with iterators. Very few of the + * other standard container interfaces are defined. + * + * This is not a true container, but an @e adaptor. It holds another + * container, and provides a wrapper interface to that container. The + * wrapper is what enforces strict first-in-first-out %queue behavior. + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::deque, but it can be any type + * that supports @c front, @c back, @c push_back, and @c pop_front, + * such as std::list or an appropriate user-defined type. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c push and + * @c pop, which are standard %queue/FIFO operations. + */ + template + class queue + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template + friend bool + operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + template + friend bool + operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + /** + * 'c' is the underlying container. Maintainers wondering why + * this isn't uglified as per style guidelines should note that + * this name is specified in the standard, [23.2.3.1]. (Why? + * Presumably for the same reason that it's protected instead + * of private: to allow derivation. But none of the other + * containers allow for derivation. Odd.) + */ + _Sequence c; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + queue(const _Sequence& __c = _Sequence()) : c(__c) {} + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %queue. + */ + reference + front() + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + front() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read/write reference to the data at the last + * element of the %queue. + */ + reference + back() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %queue. + */ + const_reference + back() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the end of the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. The function creates an + * element at the end of the %queue and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue by one. + * The time complexity of the operation depends on the underlying + * sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_front(); + } + }; + + + /** + * @brief Queue equality comparison. + * @param x A %queue. + * @param y A %queue of the same type as @a x. + * @return True iff the size and elements of the queues are equal. + * + * This is an equivalence relation. Complexity and semantics depend on the + * underlying sequence type, but the expected rules are: this relation is + * linear in the size of the sequences, and queues are considered equivalent + * if their sequences compare equal. + */ + template + inline bool + operator==(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return __x.c == __y.c; } + + /** + * @brief Queue ordering relation. + * @param x A %queue. + * @param y A %queue of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the + * determination. + */ + template + inline bool + operator<(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + { return __x.c < __y.c; } + + /// Based on operator== + template + inline bool + operator!=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) + { return !(__x < __y); } + + /** + * @brief A standard container automatically sorting its contents. + * + * @ingroup Containers + * @ingroup Sequences + * + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces sorting and + * first-in-first-out %queue behavior. Very few of the standard + * container/sequence interface requirements are met (e.g., + * iterators). + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::vector, but it can be + * any type that supports @c front(), @c push_back, @c pop_back, + * and random-access iterators, such as std::deque or an + * appropriate user-defined type. + * + * The third template parameter supplies the means of making + * priority comparisons. It defaults to @c less but + * can be anything defining a strict weak ordering. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %queue/FIFO + * operations. + * + * @note No equality/comparison operators are provided for + * %priority_queue. + * + * @note Sorting of the elements takes place as they are added to, + * and removed from, the %priority_queue using the + * %priority_queue's member functions. If you access the elements + * by other means, and change their data such that the sorting + * order would be different, the %priority_queue will not re-sort + * the elements for you. (How could it know to do so?) + */ + template, + typename _Compare = less > + class priority_queue + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _SequenceConcept) + __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + __glibcxx_class_requires4(_Compare, bool, _Tp,_Tp,_BinaryFunctionConcept) + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on these names. + _Sequence c; + _Compare comp; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + priority_queue(const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { std::make_heap(c.begin(), c.end(), comp); } + + /** + * @brief Builds a %queue from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param x A comparison functor describing a strict weak ordering. + * @param s An initial sequence with which to start. + * + * Begins by copying @a s, inserting a copy of the elements + * from @a [first,last) into the copy of @a s, then ordering + * the copy according to @a x. + * + * For more information on function objects, see the + * documentation on @link s20_3_1_base functor base + * classes@endlink. + */ + template + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { + __glibcxx_requires_valid_range(__first, __last); + c.insert(c.end(), __first, __last); + std::make_heap(c.begin(), c.end(), comp); + } + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const { return c.size(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * @brief Add data to the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. + * The time complexity of the operation depends on the underlying + * sequence. + */ + void + push(const value_type& __x) + { + try + { + c.push_back(__x); + std::push_heap(c.begin(), c.end(), comp); + } + catch(...) + { + c.clear(); + __throw_exception_again; + } + } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + try + { + std::pop_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + catch(...) + { + c.clear(); + __throw_exception_again; + } + } + }; + + // No equality/comparison operators are provided for priority_queue. +} // namespace std + +#endif /* _QUEUE_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_raw_storage_iter.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_raw_storage_iter.h new file mode 100644 index 00000000000..732142e1e6b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_raw_storage_iter.h @@ -0,0 +1,113 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_raw_storage_iter.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_RAW_STORAGE_ITERATOR_H +#define _STL_RAW_STORAGE_ITERATOR_H 1 + +namespace std +{ + /** + * This iterator class lets algorithms store their results into + * uninitialized memory. + */ + template + class raw_storage_iterator + : public iterator + { + protected: + _ForwardIterator _M_iter; + + public: + explicit + raw_storage_iterator(_ForwardIterator __x) + : _M_iter(__x) {} + + raw_storage_iterator& + operator*() { return *this; } + + raw_storage_iterator& + operator=(const _Tp& __element) + { + std::_Construct(&*_M_iter, __element); + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp>& + operator++() + { + ++_M_iter; + return *this; + } + + raw_storage_iterator<_ForwardIterator, _Tp> + operator++(int) + { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; + } + }; +} // namespace std + +#endif + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_relops.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_relops.h new file mode 100644 index 00000000000..3e9f060f287 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_relops.h @@ -0,0 +1,137 @@ +// std::rel_ops implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * Copyright (c) 1996,1997 + * Silicon Graphics + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file stl_relops.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + * + * @if maint + * Inclusion of this file has been removed from + * all of the other STL headers for safety reasons, except std_utility.h. + * For more information, see the thread of about twenty messages starting + * with http://gcc.gnu.org/ml/libstdc++/2001-01/msg00223.html , or the + * FAQ at http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4 . + * + * Short summary: the rel_ops operators should be avoided for the present. + * @endif + */ + +#ifndef _STL_RELOPS_H +#define _STL_RELOPS_H 1 + +namespace std +{ + namespace rel_ops + { + /** @namespace std::rel_ops + * @brief The generated relational operators are sequestered here. + */ + + /** + * @brief Defines @c != for arbitrary types, in terms of @c ==. + * @param x A thing. + * @param y Another thing. + * @return x != y + * + * This function uses @c == to determine its result. + */ + template + inline bool + operator!=(const _Tp& __x, const _Tp& __y) + { return !(__x == __y); } + + /** + * @brief Defines @c > for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x > y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator>(const _Tp& __x, const _Tp& __y) + { return __y < __x; } + + /** + * @brief Defines @c <= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x <= y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator<=(const _Tp& __x, const _Tp& __y) + { return !(__y < __x); } + + /** + * @brief Defines @c >= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x >= y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator>=(const _Tp& __x, const _Tp& __y) + { return !(__x < __y); } + + } // namespace rel_ops +} // namespace std + +#endif /* _STL_RELOPS_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_set.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_set.h new file mode 100644 index 00000000000..bb28bddc7af --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_set.h @@ -0,0 +1,593 @@ +// Set implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_set.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SET_H +#define _SET_H 1 + +#include + +namespace _GLIBCXX_STD +{ + // Forward declarations of operators < and ==, needed for friend declaration. + template, + class _Alloc = allocator<_Key> > + class set; + + template + inline bool + operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + template + inline bool + operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of unique keys, which can be + * retrieved in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a container, a + * reversible container, and an + * associative container (using unique keys). + * + * Sets support bidirectional iterators. + * + * @param Key Type of key objects. + * @param Compare Comparison function object type, defaults to less. + * @param Alloc Allocator type, defaults to allocator. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template + class set + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + //@} + + private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set + public: + //@{ + /// Iterator-related typedefs. + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + //@} + + // allocation/deallocation + /// Default constructor creates no elements. + set() + : _M_t(_Compare(), allocator_type()) {} + + /** + * @brief Default constructor creates no elements. + * + * @param comp Comparator to use. + * @param a Allocator to use. + */ + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Set copy constructor. + * @param x A %set of identical element and allocator types. + * + * The newly-created %set uses a copy of the allocation object used + * by @a x. + */ + set(const set<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Set assignment operator. + * @param x A %set of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + set<_Key,_Compare,_Alloc>& + operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object with which the %set was constructed. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object with which the %set was constructed. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the allocator object with which the %set was constructed. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %set. Iteration is done in ascending order according to the keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %set. Iteration is done in ascending order according to the keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %set. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %set. + * @param x A %set of the same element and allocator types. + * + * This exchanges the elements between two sets in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(set<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Attempts to insert an element into the %set. + * @param x Element to be inserted. + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. + * + * This function attempts to insert an element into the %set. A %set + * relies on unique keys and thus an element is only inserted if it is + * not already present in the %set. + * + * Insertion requires logarithmic time. + */ + pair + insert(const value_type& __x) + { + pair __p = _M_t.insert_unique(__x); + return pair(__p.first, __p.second); + } + + /** + * @brief Attempts to insert an element into the %set. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the element with key of @a x (may + * or may not be the element passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument insert() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); + } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %set. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %set. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %set. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %set. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // set operations: + + /** + * @brief Finds the number of elements. + * @param x Element to located. + * @return Number of elements with specified key. + * + * This function only makes sense for multisets; for set the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + //@} + + template + friend bool + operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + + template + friend bool + operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + }; + + + /** + * @brief Set equality comparison. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff the size and elements of the sets are equal. + * + * This is an equivalence relation. It is linear in the size of the sets. + * Sets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + template + inline bool + operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __x._M_t == __y._M_t; } + + /** + * @brief Set ordering relation. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __x._M_t < __y._M_t; } + + /// Returns !(x == y). + template + inline bool + operator!=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template + inline bool + operator>(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template + inline bool + operator<=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template + inline bool + operator>=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::set::swap(). + template + inline void + swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y) + { __x.swap(__y); } + +} // namespace std + +#endif /* _SET_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_stack.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_stack.h new file mode 100644 index 00000000000..ada50ee350e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_stack.h @@ -0,0 +1,272 @@ +// Stack implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_stack.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STACK_H +#define _STACK_H 1 + +#include +#include + +namespace std +{ + // Forward declarations of operators == and <, needed for friend + // declaration. + template > + class stack; + + template + inline bool + operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + template + inline bool + operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + /** + * @brief A standard container giving FILO behavior. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets many of the requirements of a + * container, + * but does not define anything to do with iterators. Very few of the + * other standard container interfaces are defined. + * + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces strict + * first-in-last-out %stack behavior. + * + * The second template parameter defines the type of the underlying + * sequence/container. It defaults to std::deque, but it can be + * any type that supports @c back, @c push_back, and @c pop_front, + * such as std::list, std::vector, or an appropriate user-defined + * type. + * + * Members not found in "normal" containers are @c container_type, + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %stack/FILO + * operations. + */ + template + class stack + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template + friend bool + operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + template + friend bool + operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on this name. + _Sequence c; + + public: + // XXX removed old def ctor, added def arg to this one to match 14882 + /** + * @brief Default constructor creates no elements. + */ + explicit + stack(const _Sequence& __c = _Sequence()) + : c(__c) {} + + /** + * Returns true if the %stack is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %stack. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %stack. + */ + reference + top() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %stack. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the top of the %stack. + * @param x Data to be added. + * + * This is a typical %stack operation. The function creates an + * element at the top of the %stack and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %stack operation. It shrinks the %stack + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_back(); + } + }; + + /** + * @brief Stack equality comparison. + * @param x A %stack. + * @param y A %stack of the same type as @a x. + * @return True iff the size and elements of the stacks are equal. + * + * This is an equivalence relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, and + * stacks are considered equivalent if their sequences compare + * equal. + */ + template + inline bool + operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __x.c == __y.c; } + + /** + * @brief Stack ordering relation. + * @param x A %stack. + * @param y A %stack of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the + * determination. + */ + template + inline bool + operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __x.c < __y.c; } + + /// Based on operator== + template + inline bool + operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) + { return !(__x < __y); } +} // namespace std + +#endif /* _STACK_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tempbuf.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tempbuf.h new file mode 100644 index 00000000000..399cffb3311 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tempbuf.h @@ -0,0 +1,171 @@ +// Temporary buffer implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_tempbuf.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TEMPBUF_H +#define _TEMPBUF_H 1 + +#include + +namespace std +{ + /** + * @if maint + * This class is used in two places: stl_algo.h and ext/memory, + * where it is wrapped as the temporary_buffer class. See + * temporary_buffer docs for more notes. + * @endif + */ + template + class _Temporary_buffer + { + // concept requirements + __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef pointer iterator; + typedef ptrdiff_t size_type; + + protected: + size_type _M_original_len; + size_type _M_len; + pointer _M_buffer; + + void + _M_initialize_buffer(const _Tp&, __true_type) { } + + void + _M_initialize_buffer(const _Tp& val, __false_type) + { std::uninitialized_fill_n(_M_buffer, _M_len, val); } + + public: + /// As per Table mumble. + size_type + size() const + { return _M_len; } + + /// Returns the size requested by the constructor; may be >size(). + size_type + requested_size() const + { return _M_original_len; } + + /// As per Table mumble. + iterator + begin() + { return _M_buffer; } + + /// As per Table mumble. + iterator + end() + { return _M_buffer + _M_len; } + + /** + * Constructs a temporary buffer of a size somewhere between + * zero and the size of the given range. + */ + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); + + ~_Temporary_buffer() + { + std::_Destroy(_M_buffer, _M_buffer + _M_len); + std::return_temporary_buffer(_M_buffer); + } + + private: + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&); + + void + operator=(const _Temporary_buffer&); + }; + + + template + _Temporary_buffer<_ForwardIterator, _Tp>:: + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _M_original_len(std::distance(__first, __last)), + _M_len(0), _M_buffer(0) + { + // Workaround for a __type_traits bug in the pre-7.3 compiler. + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; + + try + { + pair __p(get_temporary_buffer< + value_type>(_M_original_len)); + _M_buffer = __p.first; + _M_len = __p.second; + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); + } + catch(...) + { + std::return_temporary_buffer(_M_buffer); + _M_buffer = 0; + _M_len = 0; + __throw_exception_again; + } + } +} // namespace std + +#endif /* _TEMPBUF_H */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_threads.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_threads.h new file mode 100644 index 00000000000..04baf0a08f9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_threads.h @@ -0,0 +1,150 @@ +// Threading support -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_threads.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_THREADS_H +#define _STL_THREADS_H 1 + +#include + +// The only supported threading model is GCC's own gthr.h abstraction +// layer. +#include "bits/gthr.h" + +namespace __gnu_internal +{ +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + extern __gthread_mutex_t _GLIBCXX_mutex; + extern __gthread_mutex_t *_GLIBCXX_mutex_address; + extern __gthread_once_t _GLIBCXX_once; + extern void _GLIBCXX_mutex_init(void); + extern void _GLIBCXX_mutex_address_init(void); +#endif +} // namespace __gnu_internal + +namespace __gnu_cxx +{ + // Locking class. Note that this class *does not have a + // constructor*. It must be initialized either statically, with + // __STL_MUTEX_INITIALIZER, or dynamically, by explicitly calling + // the _M_initialize member function. (This is similar to the ways + // that a pthreads mutex can be initialized.) There are explicit + // member functions for acquiring and releasing the lock. + + // There is no constructor because static initialization is + // essential for some uses, and only a class aggregate (see section + // 8.5.1 of the C++ standard) can be initialized that way. That + // means we must have no constructors, no base classes, no virtual + // functions, and no private or protected members. + struct _STL_mutex_lock + { + // The class must be statically initialized with __STL_MUTEX_INITIALIZER. +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + volatile int _M_init_flag; + __gthread_once_t _M_once; +#endif + __gthread_mutex_t _M_lock; + + void + _M_initialize() + { +#ifdef __GTHREAD_MUTEX_INIT + // There should be no code in this path given the usage rules above. +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) + if (_M_init_flag) return; + if (__gthread_once(&__gnu_internal::_GLIBCXX_once, + __gnu_internal::_GLIBCXX_mutex_init) != 0 + && __gthread_active_p()) + abort (); + __gthread_mutex_lock(&__gnu_internal::_GLIBCXX_mutex); + if (!_M_init_flag) + { + // Even though we have a global lock, we use __gthread_once to be + // absolutely certain the _M_lock mutex is only initialized once on + // multiprocessor systems. + __gnu_internal::_GLIBCXX_mutex_address = &_M_lock; + if (__gthread_once(&_M_once, + __gnu_internal::_GLIBCXX_mutex_address_init) != 0 + && __gthread_active_p()) + abort(); + _M_init_flag = 1; + } + __gthread_mutex_unlock(&__gnu_internal::_GLIBCXX_mutex); +#endif + } + + void + _M_acquire_lock() + { +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + if (!_M_init_flag) _M_initialize(); +#endif + __gthread_mutex_lock(&_M_lock); + } + + void + _M_release_lock() + { +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + if (!_M_init_flag) _M_initialize(); +#endif + __gthread_mutex_unlock(&_M_lock); + } + }; + +#ifdef __GTHREAD_MUTEX_INIT +#define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT } +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) +#ifdef __GTHREAD_MUTEX_INIT_DEFAULT +#define __STL_MUTEX_INITIALIZER \ + = { 0, __GTHREAD_ONCE_INIT, __GTHREAD_MUTEX_INIT_DEFAULT } +#else +#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT } +#endif +#endif +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tree.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tree.h new file mode 100644 index 00000000000..cea16f12d25 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_tree.h @@ -0,0 +1,1283 @@ +// RB tree implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +/** @file stl_tree.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TREE_H +#define _TREE_H 1 + +#include +#include +#include +#include +#include + +namespace std +{ + // Red-black tree class, designed for use in implementing STL + // associative containers (set, multiset, map, and multimap). The + // insertion and deletion algorithms are based on those in Cormen, + // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, + // 1990), except that + // + // (1) the header cell is maintained with links not only to the root + // but also to the leftmost node of the tree, to enable constant + // time begin(), and to the rightmost node of the tree, to enable + // linear time performance when used with the generic set algorithms + // (set_union, etc.) + // + // (2) when a node being deleted has two children its successor node + // is relinked into its place, rather than copied, so that the only + // iterators invalidated are those referring to the deleted node. + + enum _Rb_tree_color { _S_red = false, _S_black = true }; + + struct _Rb_tree_node_base + { + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } + }; + + template + struct _Rb_tree_node : public _Rb_tree_node_base + { + typedef _Rb_tree_node<_Val>* _Link_type; + _Val _M_value_field; + }; + + _Rb_tree_node_base* + _Rb_tree_increment(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x); + + _Rb_tree_node_base* + _Rb_tree_decrement(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x); + + template + struct _Rb_tree_iterator + { + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_iterator() + : _M_node() { } + + _Rb_tree_iterator(_Link_type __x) + : _M_node(__x) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; + + typedef _Rb_tree_iterator<_Tp> iterator; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_const_iterator() + : _M_node() { } + + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) { } + + _Rb_tree_const_iterator(const iterator& __it) + : _M_node(__it._M_node) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; + }; + + template + inline bool + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template + inline bool + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + void + _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); + + void + _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); + + void + _Rb_tree_insert_and_rebalance(const bool __insert_left, + _Rb_tree_node_base* __x, + _Rb_tree_node_base* __p, + _Rb_tree_node_base& __header); + + _Rb_tree_node_base* + _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, + _Rb_tree_node_base& __header); + + + template > + class _Rb_tree + { + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other + _Node_allocator; + + protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + typedef _Rb_tree_node<_Val> _Rb_tree_node; + + public: + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node* _Link_type; + typedef const _Rb_tree_node* _Const_Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast(&this->_M_impl); } + + protected: + _Rb_tree_node* + _M_get_node() + { return _M_impl._Node_allocator::allocate(1); } + + void + _M_put_node(_Rb_tree_node* __p) + { _M_impl._Node_allocator::deallocate(__p, 1); } + + _Link_type + _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + try + { std::_Construct(&__tmp->_M_value_field, __x); } + catch(...) + { + _M_put_node(__tmp); + __throw_exception_again; + } + return __tmp; + } + + _Link_type + _M_clone_node(_Const_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; + } + + void + destroy_node(_Link_type __p) + { + std::_Destroy(&__p->_M_value_field); + _M_put_node(__p); + } + + protected: + template::_M_type> + struct _Rb_tree_impl : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + // Specialization for _Comparison types that are not capable of + // being base classes / super classes. + template + struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + _Rb_tree_impl<_Compare> _M_impl; + + protected: + _Base_ptr& + _M_root() + { return this->_M_impl._M_header._M_parent; } + + _Const_Base_ptr + _M_root() const + { return this->_M_impl._M_header._M_parent; } + + _Base_ptr& + _M_leftmost() + { return this->_M_impl._M_header._M_left; } + + _Const_Base_ptr + _M_leftmost() const + { return this->_M_impl._M_header._M_left; } + + _Base_ptr& + _M_rightmost() + { return this->_M_impl._M_header._M_right; } + + _Const_Base_ptr + _M_rightmost() const + { return this->_M_impl._M_header._M_right; } + + _Link_type + _M_begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } + + _Const_Link_type + _M_begin() const + { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_parent); } + + _Link_type + _M_end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } + + _Const_Link_type + _M_end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + + static const_reference + _S_value(_Const_Link_type __x) + { return __x->_M_value_field; } + + static const _Key& + _S_key(_Const_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Link_type + _S_left(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_left); } + + static _Const_Link_type + _S_left(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_left); } + + static _Link_type + _S_right(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_right); } + + static _Const_Link_type + _S_right(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_right); } + + static const_reference + _S_value(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x)->_M_value_field; } + + static const _Key& + _S_key(_Const_Base_ptr __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + public: + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_const_iterator const_iterator; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + private: + iterator + _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + + _Link_type + _M_copy(_Const_Link_type __x, _Link_type __p); + + void + _M_erase(_Link_type __x); + + public: + // allocation/deallocation + _Rb_tree() + { } + + _Rb_tree(const _Compare& __comp) + : _M_impl(allocator_type(), __comp) + { } + + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _M_impl(__a, __comp) + { } + + _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + : _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare) + { + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + + ~_Rb_tree() + { _M_erase(_M_begin()); } + + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x); + + // Accessors. + _Compare + key_comp() const + { return _M_impl._M_key_compare; } + + iterator + begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_left); } + + const_iterator + begin() const + { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_left); } + + iterator + end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } + + const_iterator + end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + bool + empty() const + { return _M_impl._M_node_count == 0; } + + size_type + size() const + { return _M_impl._M_node_count; } + + size_type + max_size() const + { return size_type(-1); } + + void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t); + + // Insert/erase. + pair + insert_unique(const value_type& __x); + + iterator + insert_equal(const value_type& __x); + + iterator + insert_unique(iterator __position, const value_type& __x); + + iterator + insert_equal(iterator __position, const value_type& __x); + + template + void + insert_unique(_InputIterator __first, _InputIterator __last); + + template + void + insert_equal(_InputIterator __first, _InputIterator __last); + + void + erase(iterator __position); + + size_type + erase(const key_type& __x); + + void + erase(iterator __first, iterator __last); + + void + erase(const key_type* __first, const key_type* __last); + + void + clear() + { + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_impl._M_node_count = 0; + } + + // Set operations. + iterator + find(const key_type& __x); + + const_iterator + find(const key_type& __x) const; + + size_type + count(const key_type& __x) const; + + iterator + lower_bound(const key_type& __x); + + const_iterator + lower_bound(const key_type& __x) const; + + iterator + upper_bound(const key_type& __x); + + const_iterator + upper_bound(const key_type& __x) const; + + pair + equal_range(const key_type& __x); + + pair + equal_range(const key_type& __x) const; + + // Debugging. + bool + __rb_verify() const; + }; + + template + inline bool + operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { + return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); + } + + template + inline bool + operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + template + inline bool + operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + template + inline bool + operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return __y < __x; } + + template + inline bool + operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + template + inline bool + operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + template + inline void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { __x.swap(__y); } + + template + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + { + if (this != &__x) + { + // Note that _Key may be a constant type. + clear(); + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + if (__x._M_root() != 0) + { + _M_root() = _M_copy(__x._M_begin(), _M_end()); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; + } + } + return *this; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v) + { + _Link_type __z = _M_create_node(__v); + bool __insert_left; + + __insert_left = __x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert(__x, __y, __v); + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t) + { + if (_M_root() == 0) + { + if (__t._M_root() != 0) + { + _M_root() = __t._M_root(); + _M_leftmost() = __t._M_leftmost(); + _M_rightmost() = __t._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __t._M_root() = 0; + __t._M_leftmost() = __t._M_end(); + __t._M_rightmost() = __t._M_end(); + } + } + else if (__t._M_root() == 0) + { + __t._M_root() = _M_root(); + __t._M_leftmost() = _M_leftmost(); + __t._M_rightmost() = _M_rightmost(); + __t._M_root()->_M_parent = __t._M_end(); + + _M_root() = 0; + _M_leftmost() = _M_end(); + _M_rightmost() = _M_end(); + } + else + { + std::swap(_M_root(),__t._M_root()); + std::swap(_M_leftmost(),__t._M_leftmost()); + std::swap(_M_rightmost(),__t._M_rightmost()); + + _M_root()->_M_parent = _M_end(); + __t._M_root()->_M_parent = __t._M_end(); + } + // No need to swap header's color as it does not change. + std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); + std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); + } + + template + pair::iterator, + bool> + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_unique(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + bool __comp = true; + while (__x != 0) + { + __y = __x; + __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert(__x, __y, __v), true); + return pair(__j, false); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_unique(iterator __position, const _Val& __v) + { + if (__position._M_node == _M_leftmost()) + { + // begin() + if (size() > 0 + && _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + else + return insert_unique(__v).first; + } + else if (__position._M_node == _M_end()) + { + // end() + if (_M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_unique(__v).first; + } + else + { + iterator __before = __position; + --__before; + if (_M_impl._M_key_compare(_S_key(__before._M_node), + _KeyOfValue()(__v)) + && _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + } + else + return insert_unique(__v).first; + } + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(iterator __position, const _Val& __v) + { + if (__position._M_node == _M_leftmost()) + { + // begin() + if (size() > 0 + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_equal(__v); + } + else if (__position._M_node == _M_end()) + { + // end() + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_equal(__v); + } + else + { + iterator __before = __position; + --__before; + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__before._M_node)) + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + } + else + return insert_equal(__v); + } + } + + template + template + void + _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: + insert_equal(_II __first, _II __last) + { + for ( ; __first != __last; ++__first) + insert_equal(*__first); + } + + template + template + void + _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: + insert_unique(_II __first, _II __last) + { + for ( ; __first != __last; ++__first) + insert_unique(*__first); + } + + template + inline void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node, + this->_M_impl._M_header)); + destroy_node(__y); + --_M_impl._M_node_count; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) + { + pair __p = equal_range(__x); + size_type __n = std::distance(__p.first, __p.second); + erase(__p.first, __p.second); + return __n; + } + + template + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>:: + _M_copy(_Const_Link_type __x, _Link_type __p) + { + // Structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + try + { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) + { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + catch(...) + { + _M_erase(__top); + __throw_exception_again; + } + return __top; + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x) + { + // Erase without rebalancing. + while (__x != 0) + { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; + } + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(iterator __first, iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) erase(__first++); + } + + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + iterator __j = iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + find(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + { + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + } + const_iterator __j = const_iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + count(const _Key& __k) const + { + pair __p = equal_range(__k); + const size_type __n = std::distance(__p.first, __p.second); + return __n; + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + lower_bound(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + lower_bound(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + upper_bound(const _Key& __k) + { + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); + } + + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + upper_bound(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); + } + + template + inline + pair::iterator, + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator> + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + equal_range(const _Key& __k) + { return pair(lower_bound(__k), upper_bound(__k)); } + + template + inline + pair::const_iterator, + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + equal_range(const _Key& __k) const + { return pair(lower_bound(__k), + upper_bound(__k)); } + + unsigned int + _Rb_tree_black_count(const _Rb_tree_node_base* __node, + const _Rb_tree_node_base* __root); + + template + bool + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const + { + if (_M_impl._M_node_count == 0 || begin() == end()) + return _M_impl._M_node_count == 0 && begin() == end() + && this->_M_impl._M_header._M_left == _M_end() + && this->_M_impl._M_header._M_right == _M_end(); + + unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) + { + _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); + _Const_Link_type __L = _S_left(__x); + _Const_Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_red) + if ((__L && __L->_M_color == _S_red) + || (__R && __R->_M_color == _S_red)) + return false; + + if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + return true; + } +} // namespace std + +#endif + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_uninitialized.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_uninitialized.h new file mode 100644 index 00000000000..f4f8d187f64 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_uninitialized.h @@ -0,0 +1,297 @@ +// Raw memory manipulators -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_uninitialized.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STL_UNINITIALIZED_H +#define _STL_UNINITIALIZED_H 1 + +#include + +namespace std +{ + // uninitialized_copy + template + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + __true_type) + { return std::copy(__first, __last, __result); } + + template + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, + __false_type) + { + _ForwardIterator __cur = __result; + try + { + for ( ; __first != __last; ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * + * Like copy(), but does not require an initialized output range. + */ + template + inline _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; + return std::__uninitialized_copy_aux(__first, __last, __result, + _Is_POD()); + } + + inline char* + uninitialized_copy(const char* __first, const char* __last, char* __result) + { + std::memmove(__result, __first, __last - __first); + return __result + (__last - __first); + } + + inline wchar_t* + uninitialized_copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) + { + std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); + } + + // Valid if copy construction is equivalent to assignment, and if the + // destructor is trivial. + template + inline void + __uninitialized_fill_aux(_ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __x, __true_type) + { std::fill(__first, __last, __x); } + + template + void + __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x, __false_type) + { + _ForwardIterator __cur = __first; + try + { + for ( ; __cur != __last; ++__cur) + std::_Construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the value x into the range [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @param x The source value. + * @return Nothing. + * + * Like fill(), but does not require an initialized output range. + */ + template + inline void + uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; + std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); + } + + // Valid if copy construction is equivalent to assignment, and if the + // destructor is trivial. + template + inline _ForwardIterator + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + const _Tp& __x, __true_type) + { return std::fill_n(__first, __n, __x); } + + template + _ForwardIterator + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, + const _Tp& __x, __false_type) + { + _ForwardIterator __cur = __first; + try + { + for ( ; __n > 0; --__n, ++__cur) + std::_Construct(&*__cur, __x); + return __cur; + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + + /** + * @brief Copies the value x into the range [first,first+n). + * @param first An input iterator. + * @param n The number of copies to make. + * @param x The source value. + * @return first+n + * + * Like fill_n(), but does not require an initialized output range. + */ + template + inline _ForwardIterator + uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) + { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; + return std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); + } + + // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, + // __uninitialized_fill_copy. + + // __uninitialized_copy_copy + // Copies [first1, last1) into [result, result + (last1 - first1)), and + // copies [first2, last2) into + // [result, result + (last1 - first1) + (last2 - first2)). + + template + inline _ForwardIterator + __uninitialized_copy_copy(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result) + { + _ForwardIterator __mid = std::uninitialized_copy(__first1, __last1, + __result); + try + { + return std::uninitialized_copy(__first2, __last2, __mid); + } + catch(...) + { + std::_Destroy(__result, __mid); + __throw_exception_again; + } + } + + // __uninitialized_fill_copy + // Fills [result, mid) with x, and copies [first, last) into + // [mid, mid + (last - first)). + template + inline _ForwardIterator + __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, + const _Tp& __x, _InputIterator __first, + _InputIterator __last) + { + std::uninitialized_fill(__result, __mid, __x); + try + { + return std::uninitialized_copy(__first, __last, __mid); + } + catch(...) + { + std::_Destroy(__result, __mid); + __throw_exception_again; + } + } + + // __uninitialized_copy_fill + // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and + // fills [first2 + (last1 - first1), last2) with x. + template + inline void + __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, + _ForwardIterator __last2, const _Tp& __x) + { + _ForwardIterator __mid2 = std::uninitialized_copy(__first1, __last1, + __first2); + try + { + std::uninitialized_fill(__mid2, __last2, __x); + } + catch(...) + { + std::_Destroy(__first2, __mid2); + __throw_exception_again; + } + } + +} // namespace std + +#endif /* _STL_UNINITIALIZED_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_vector.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_vector.h new file mode 100644 index 00000000000..fee413dc6f0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stl_vector.h @@ -0,0 +1,932 @@ +// Vector implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stl_vector.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VECTOR_H +#define _VECTOR_H 1 + +#include +#include +#include + +namespace _GLIBCXX_STD +{ + /** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif + */ + template + struct _Vector_base + { + struct _Vector_impl + : public _Alloc { + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + _Vector_impl (_Alloc const& __a) + : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast(&this->_M_impl); } + + _Vector_base(const allocator_type& __a) : _M_impl(__a) + { } + + _Vector_base(size_t __n, const allocator_type& __a) + : _M_impl(__a) + { + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + + ~_Vector_base() + { _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } + + public: + _Vector_impl _M_impl; + + _Tp* + _M_allocate(size_t __n) { return _M_impl.allocate(__n); } + + void + _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_impl.deallocate(__p, __n); } + }; + + + /** + * @brief A standard container which offers fixed time access to + * individual elements in any order. + * + * @ingroup Containers + * @ingroup Sequences + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence, including the + * optional sequence requirements with the + * %exception of @c push_front and @c pop_front. + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ + template > + class vector : protected _Vector_base<_Tp, _Alloc> + { + // Concept requirements. + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef vector<_Tp, _Alloc> vector_type; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + /** @if maint + * These two functions and three data members are all from the + * base class. They should be pretty self-explanatory, as + * %vector uses a simple contiguous allocation scheme. @endif + */ + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_impl; + + public: + // [23.2.4.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + vector(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + /** + * @brief Create a %vector with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %vector with @a n copies of @a value. + */ + vector(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, __value); } + + /** + * @brief Create a %vector with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %vector with @a n copies of a + * default-constructed element. + */ + explicit + vector(size_type __n) + : _Base(__n, allocator_type()) + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, value_type()); } + + /** + * @brief %Vector copy constructor. + * @param x A %vector of identical element and allocator types. + * + * The newly-created %vector uses a copy of the allocation + * object used by @a x. All the elements of @a x are copied, + * but any extra memory in + * @a x (for fast expansion) will not be copied. + */ + vector(const vector& __x) + : _Base(__x.size(), __x.get_allocator()) + { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(), + this->_M_impl._M_start); + } + + /** + * @brief Builds a %vector from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %vector consisting of copies of the elements from + * [first,last). + * + * If the iterators are forward, bidirectional, or + * random-access, then this will call the elements' copy + * constructor N times (where N is distance(first,last)) and do + * no memory reallocation. But if only input iterators are + * used, then this will do at most 2N calls to the copy + * constructor, and logN memory reallocations. + */ + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } + + /** + * @brief %Vector assignment operator. + * @param x A %vector of identical element and allocator types. + * + * All the elements of @a x are copied, but any extra memory in + * @a x (for fast expansion) will not be copied. Unlike the + * copy constructor, the allocator object is not copied. + */ + vector& + operator=(const vector& __x); + + /** + * @brief Assigns a given value to a %vector. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %vector with @a n copies of the given + * value. Note that the assignment completely changes the + * %vector and that the resulting %vector's size is the same as + * the number of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %vector with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %vector and + * that the resulting %vector's size is the same as the number + * of elements assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + using _Base::get_allocator; + + // iterators + /** + * Returns a read/write iterator that points to the first + * element in the %vector. Iteration is done in ordinary + * element order. + */ + iterator + begin() { return iterator (this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %vector. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const { return const_iterator (this->_M_impl._M_start); } + + /** + * Returns a read/write iterator that points one past the last + * element in the %vector. Iteration is done in ordinary + * element order. + */ + iterator + end() { return iterator (this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %vector. Iteration is done in + * ordinary element order. + */ + const_iterator + end() const { return const_iterator (this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to the + * last element in the %vector. Iteration is done in reverse + * element order. + */ + reverse_iterator + rbegin() { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last element in the %vector. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %vector. Iteration is done + * in reverse element order. + */ + reverse_iterator + rend() { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first element in the %vector. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const { return const_reverse_iterator(begin()); } + + // [23.2.4.2] capacity + /** Returns the number of elements in the %vector. */ + size_type + size() const { return size_type(end() - begin()); } + + /** Returns the size() of the largest possible %vector. */ + size_type + max_size() const { return size_type(-1) / sizeof(value_type); } + + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %vector to the specified + * number of elements. If the number is smaller than the + * %vector's current size the %vector is truncated, otherwise + * the %vector is extended and new elements are populated with + * given data. + */ + void + resize(size_type __new_size, const value_type& __x) + { + if (__new_size < size()) + erase(begin() + __new_size, end()); + else + insert(end(), __new_size - size(), __x); + } + + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * + * This function will resize the %vector to the specified + * number of elements. If the number is smaller than the + * %vector's current size the %vector is truncated, otherwise + * the %vector is extended and new elements are + * default-constructed. + */ + void + resize(size_type __new_size) { resize(__new_size, value_type()); } + + /** + * Returns the total number of elements that the %vector can + * hold before needing to allocate more memory. + */ + size_type + capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); } + + /** + * Returns true if the %vector is empty. (Thus begin() would + * equal end().) + */ + bool + empty() const { return begin() == end(); } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * elements. + * @param n Number of elements required. + * @throw std::length_error If @a n exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %vector to hold the specified number of elements. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the number of elements + * that will be required, the user can reserve the memory in + * %advance, and thus prevent a possible reallocation of memory + * and copying of %vector data. + */ + void + reserve(size_type __n); + + // element access + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + reference + operator[](size_type __n) { return *(begin() + __n); } + + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[](size_type __n) const { return *(begin() + __n); } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range(__N("vector::_M_range_check")); + } + + public: + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. + */ + reference + at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } + + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be + * accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } + + /** + * Returns a read/write reference to the data at the first + * element of the %vector. + */ + reference + front() { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %vector. + */ + const_reference + front() const { return *begin(); } + + /** + * Returns a read/write reference to the data at the last + * element of the %vector. + */ + reference + back() { return *(end() - 1); } + + /** + * Returns a read-only (constant) reference to the data at the + * last element of the %vector. + */ + const_reference + back() const { return *(end() - 1); } + + // [23.2.4.3] modifiers + /** + * @brief Add data to the end of the %vector. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %vector and assigns the given data + * to it. Due to the nature of a %vector this operation can be + * done in constant time if the %vector has preallocated space + * available. + */ + void + push_back(const value_type& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(end(), __x); + } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %vector by one. + * + * Note that no data is returned, and if the last element's + * data is needed, it should be retrieved before pop_back() is + * called. + */ + void + pop_back() + { + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); + } + + /** + * @brief Inserts given value into %vector before specified iterator. + * @param position An iterator into the %vector. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Note that this kind of operation + * could be expensive for a %vector and if it is frequently + * used the user should consider using std::list. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %vector. + * @param position An iterator into the %vector. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of + * the given data before the location specified by @a position. + * + * Note that this kind of operation could be expensive for a + * %vector and if it is frequently used the user should + * consider using std::list. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %vector. + * @param position An iterator into the %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range + * [first,last) into the %vector before the location specified + * by @a pos. + * + * Note that this kind of operation could be expensive for a + * %vector and if it is frequently used the user should + * consider using std::list. + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %vector by one. + * + * Note This operation could be expensive and if it is + * frequently used the user should consider using std::list. + * The user is also cautioned that this function only erases + * the element, and that if the element is itself a pointer, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %vector accordingly. + * + * Note This operation could be expensive and if it is + * frequently used the user should consider using std::list. + * The user is also cautioned that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %vector. + * @param x A %vector of the same element and allocator types. + * + * This exchanges the elements between two vectors in constant time. + * (Three pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(v1,v2) will feed to this function. + */ + void + swap(vector& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); + } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() { erase(begin(), end()); } + + protected: + /** + * @if maint + * Memory expansion handler. Uses the member allocation function to + * obtain @a n bytes of memory, and then copies [first,last) into it. + * @endif + */ + template + pointer + _M_allocate_and_copy(size_type __n, + _ForwardIterator __first, _ForwardIterator __last) + { + pointer __result = this->_M_allocate(__n); + try + { + std::uninitialized_copy(__first, __last, __result); + return __result; + } + catch(...) + { + _M_deallocate(__result, __n); + __throw_exception_again; + } + } + + + // Internal constructor functions follow. + + // Called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) + { + this->_M_impl._M_start = _M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, __value); + } + + // Called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // Called by the second initialize_dispatch above + template + void + _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + // Called by the second initialize_dispatch above + template + void + _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + size_type __n = std::distance(__first, __last); + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_copy(__first, __last, + this->_M_impl._M_start); + } + + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // Called by the second assign_dispatch above + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // Called by the second assign_dispatch above + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__val)); + } + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _InputIterator __first, + _InputIterator __last, __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert(__pos, __first, __last, _IterCategory()); + } + + // Called by the second insert_dispatch above + template + void + _M_range_insert(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag); + + // Called by the second insert_dispatch above + template + void + _M_range_insert(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // Called by insert(p,x) + void + _M_insert_aux(iterator __position, const value_type& __x); + }; + + + /** + * @brief Vector equality comparison. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff the size and elements of the vectors are equal. + * + * This is an equivalence relation. It is linear in the size of the + * vectors. Vectors are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. + */ + template + inline bool + operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { + return __x.size() == __y.size() && + std::equal(__x.begin(), __x.end(), __y.begin()); + } + + /** + * @brief Vector ordering relation. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * vectors. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + template + inline bool + operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); + } + + /// Based on operator== + template + inline bool + operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return !(__x == __y); } + + /// Based on operator< + template + inline bool + operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return __y < __x; } + + /// Based on operator< + template + inline bool + operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return !(__y < __x); } + + /// Based on operator< + template + inline bool + operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::vector::swap(). + template + inline void + swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _VECTOR_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stream_iterator.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stream_iterator.h new file mode 100644 index 00000000000..fa11bd6b28f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stream_iterator.h @@ -0,0 +1,214 @@ +// Stream iterators + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file stream_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STREAM_ITERATOR_H +#define _STREAM_ITERATOR_H 1 + +#pragma GCC system_header + +#include + +namespace std +{ + /// Provides input iterator semantics for streams. + template, typename _Dist = ptrdiff_t> + class istream_iterator + : public iterator + { + public: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT, _Traits> istream_type; + + private: + istream_type* _M_stream; + _Tp _M_value; + bool _M_ok; + + public: + /// Construct end of input stream iterator. + istream_iterator() + : _M_stream(0), _M_ok(false) {} + + /// Construct start of input stream iterator. + istream_iterator(istream_type& __s) + : _M_stream(&__s) + { _M_read(); } + + istream_iterator(const istream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_value(__obj._M_value), + _M_ok(__obj._M_ok) + { } + + const _Tp& + operator*() const + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_deref_istream) + ._M_iterator(*this)); + return _M_value; + } + + const _Tp* + operator->() const { return &(operator*()); } + + istream_iterator& + operator++() + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + _M_read(); + return *this; + } + + istream_iterator + operator++(int) + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + istream_iterator __tmp = *this; + _M_read(); + return __tmp; + } + + bool + _M_equal(const istream_iterator& __x) const + { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } + + private: + void + _M_read() + { + _M_ok = (_M_stream && *_M_stream) ? true : false; + if (_M_ok) + { + *_M_stream >> _M_value; + _M_ok = *_M_stream ? true : false; + } + } + }; + + /// Return true if x and y are both end or not end, or x and y are the same. + template + inline bool + operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + { return __x._M_equal(__y); } + + /// Return false if x and y are both end or not end, or x and y are the same. + template + inline bool + operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + { return !__x._M_equal(__y); } + + /** + * @brief Provides output iterator semantics for streams. + * + * This class provides an iterator to write to an ostream. The type Tp is + * the only type written by this iterator and there must be an + * operator<<(Tp) defined. + * + * @param Tp The type to write to the ostream. + * @param CharT The ostream char_type. + * @param Traits The ostream char_traits. + */ + template > + class ostream_iterator + : public iterator + { + public: + //@{ + /// Public typedef + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} + + private: + ostream_type* _M_stream; + const _CharT* _M_string; + + public: + /// Construct from an ostream. + ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} + + /** + * Construct from an ostream. + * + * The delimiter string @a c is written to the stream after every Tp + * written to the stream. The delimiter is not copied, and thus must + * not be destroyed while this iterator is in use. + * + * @param s Underlying ostream to write to. + * @param c CharT delimiter string to insert. + */ + ostream_iterator(ostream_type& __s, const _CharT* __c) + : _M_stream(&__s), _M_string(__c) { } + + /// Copy constructor. + ostream_iterator(const ostream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } + + /// Writes @a value to underlying ostream using operator<<. If + /// constructed with delimiter string, writes delimiter to ostream. + ostream_iterator& + operator=(const _Tp& __value) + { + __glibcxx_requires_cond(_M_stream != 0, + _M_message(__gnu_debug::__msg_output_ostream) + ._M_iterator(*this)); + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; + return *this; + } + + ostream_iterator& + operator*() + { return *this; } + + ostream_iterator& + operator++() + { return *this; } + + ostream_iterator& + operator++(int) + { return *this; } + }; +} // namespace std +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf.tcc new file mode 100644 index 00000000000..554d0617899 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf.tcc @@ -0,0 +1,163 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#ifndef _STREAMBUF_TCC +#define _STREAMBUF_TCC 1 + +#pragma GCC system_header + +namespace std +{ + template + streamsize + basic_streambuf<_CharT, _Traits>:: + xsgetn(char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const size_t __buf_len = this->egptr() - this->gptr(); + if (__buf_len) + { + const size_t __remaining = __n - __ret; + const size_t __len = std::min(__buf_len, __remaining); + traits_type::copy(__s, this->gptr(), __len); + __ret += __len; + __s += __len; + this->gbump(__len); + } + + if (__ret < __n) + { + const int_type __c = this->uflow(); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + traits_type::assign(*__s++, traits_type::to_char_type(__c)); + ++__ret; + } + else + break; + } + } + return __ret; + } + + template + streamsize + basic_streambuf<_CharT, _Traits>:: + xsputn(const char_type* __s, streamsize __n) + { + streamsize __ret = 0; + while (__ret < __n) + { + const size_t __buf_len = this->epptr() - this->pptr(); + if (__buf_len) + { + const size_t __remaining = __n - __ret; + const size_t __len = std::min(__buf_len, __remaining); + traits_type::copy(this->pptr(), __s, __len); + __ret += __len; + __s += __len; + this->pbump(__len); + } + + if (__ret < __n) + { + int_type __c = this->overflow(traits_type::to_int_type(*__s)); + if (!traits_type::eq_int_type(__c, traits_type::eof())) + { + ++__ret; + ++__s; + } + else + break; + } + } + return __ret; + } + + // Conceivably, this could be used to implement buffer-to-buffer + // copies, if this was ever desired in an un-ambiguous way by the + // standard. If so, then checks for __ios being zero would be + // necessary. + template + streamsize + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + streamsize __ret = 0; + typename _Traits::int_type __c = __sbin->sgetc(); + while (!_Traits::eq_int_type(__c, _Traits::eof())) + { + const size_t __n = __sbin->egptr() - __sbin->gptr(); + if (__n > 1) + { + const size_t __wrote = __sbout->sputn(__sbin->gptr(), __n); + __sbin->gbump(__wrote); + __ret += __wrote; + if (__wrote < __n) + break; + __c = __sbin->underflow(); + } + else + { + __c = __sbout->sputc(_Traits::to_char_type(__c)); + if (_Traits::eq_int_type(__c, _Traits::eof())) + break; + ++__ret; + __c = __sbin->snextc(); + } + } + return __ret; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class basic_streambuf; + extern template + streamsize + __copy_streambufs(basic_streambuf*, basic_streambuf*); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class basic_streambuf; + extern template + streamsize + __copy_streambufs(basic_streambuf*, basic_streambuf*); +#endif +#endif +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf_iterator.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf_iterator.h new file mode 100644 index 00000000000..970933578c7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/streambuf_iterator.h @@ -0,0 +1,258 @@ +// Streambuf iterators + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file streambuf_iterator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STREAMBUF_ITERATOR_H +#define _STREAMBUF_ITERATOR_H 1 + +#pragma GCC system_header + +#include +#include + +// NB: Should specialize copy, find algorithms for streambuf iterators. + +namespace std +{ + // 24.5.3 Template class istreambuf_iterator + /// Provides input iterator semantics for streambufs. + template + class istreambuf_iterator + : public iterator + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + //@} + + private: + // 24.5.3 istreambuf_iterator + // p 1 + // If the end of stream is reached (streambuf_type::sgetc() + // returns traits_type::eof()), the iterator becomes equal to + // the "end of stream" iterator value. + // NB: This implementation assumes the "end of stream" value + // is EOF, or -1. + mutable streambuf_type* _M_sbuf; + int_type _M_c; + + public: + /// Construct end of input stream iterator. + istreambuf_iterator() throw() + : _M_sbuf(0), _M_c(traits_type::eof()) { } + + /// Construct start of input stream iterator. + istreambuf_iterator(istream_type& __s) throw() + : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } + + /// Construct start of streambuf iterator. + istreambuf_iterator(streambuf_type* __s) throw() + : _M_sbuf(__s), _M_c(traits_type::eof()) { } + + /// Return the current character pointed to by iterator. This returns + /// streambuf.sgetc(). It cannot be assigned. NB: The result of + /// operator*() on an end of stream is undefined. + char_type + operator*() const + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + // Dereferencing a past-the-end istreambuf_iterator is a + // libstdc++ extension + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_deref_istreambuf) + ._M_iterator(*this)); +#endif + return traits_type::to_char_type(_M_get()); + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator& + operator++() + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + const int_type __eof = traits_type::eof(); + if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) + _M_sbuf = 0; + else + _M_c = __eof; + return *this; + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator + operator++(int) + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + + const int_type __eof = traits_type::eof(); + istreambuf_iterator __old = *this; + if (_M_sbuf + && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), + __eof)) + _M_sbuf = 0; + else + _M_c = __eof; + return __old; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 110 istreambuf_iterator::equal not const + // NB: there is also number 111 (NAD, Future) pending on this function. + /// Return true both iterators are end or both are not end. + bool + equal(const istreambuf_iterator& __b) const + { + const bool __thiseof = _M_at_eof(); + const bool __beof = __b._M_at_eof(); + return (__thiseof && __beof || (!__thiseof && !__beof)); + } + + private: + int_type + _M_get() const + { + const int_type __eof = traits_type::eof(); + int_type __ret = __eof; + if (_M_sbuf) + { + if (!traits_type::eq_int_type(_M_c, __eof)) + __ret = _M_c; + else if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), + __eof)) + _M_sbuf = 0; + } + return __ret; + } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); + } + }; + + template + inline bool + operator==(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return __a.equal(__b); } + + template + inline bool + operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, + const istreambuf_iterator<_CharT, _Traits>& __b) + { return !__a.equal(__b); } + + /// Provides output iterator semantics for streambufs. + template + class ostreambuf_iterator + : public iterator + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} + + private: + streambuf_type* _M_sbuf; + bool _M_failed; + + public: + /// Construct output iterator from ostream. + ostreambuf_iterator(ostream_type& __s) throw () + : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } + + /// Construct output iterator from streambuf. + ostreambuf_iterator(streambuf_type* __s) throw () + : _M_sbuf(__s), _M_failed(!_M_sbuf) { } + + /// Write character to streambuf. Calls streambuf.sputc(). + ostreambuf_iterator& + operator=(_CharT __c) + { + if (!_M_failed && + _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) + _M_failed = true; + return *this; + } + + /// Return *this. + ostreambuf_iterator& + operator*() + { return *this; } + + /// Return *this. + ostreambuf_iterator& + operator++(int) + { return *this; } + + /// Return *this. + ostreambuf_iterator& + operator++() + { return *this; } + + /// Return true if previous operator=() failed. + bool + failed() const throw() + { return _M_failed; } + + ostreambuf_iterator& + _M_put(const _CharT* __ws, streamsize __len) + { + if (__builtin_expect(!_M_failed, true) + && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, + false)) + _M_failed = true; + return *this; + } + }; +} // namespace std +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/stringfwd.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stringfwd.h new file mode 100644 index 00000000000..99d3ce3a534 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/stringfwd.h @@ -0,0 +1,69 @@ +// String support -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file stringfwd.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _STRINGFWD_H +#define _STRINGFWD_H 1 + +#pragma GCC system_header + +#include + +namespace std +{ + template + class allocator; + + template + struct char_traits; + + template, + typename _Alloc = allocator<_CharT> > + class basic_string; + + template<> struct char_traits; + + typedef basic_string string; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> struct char_traits; + + typedef basic_string wstring; +#endif +} // namespace std + +#endif // _STRINGFWD_H diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/type_traits.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/type_traits.h new file mode 100644 index 00000000000..9b91e5c5cdf --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/type_traits.h @@ -0,0 +1,405 @@ +// Type traits implementation -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file type_traits.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _TYPE_TRAITS_H +#define _TYPE_TRAITS_H 1 + +#pragma GCC system_header + +#include + +/* +This header file provides a framework for allowing compile time dispatch +based on type attributes. This is useful when writing template code. +For example, when making a copy of an array of an unknown type, it helps +to know if the type has a trivial copy constructor or not, to help decide +if a memcpy can be used. + +The class template __type_traits provides a series of typedefs each of +which is either __true_type or __false_type. The argument to +__type_traits can be any type. The typedefs within this template will +attain their correct values by one of these means: + 1. The general instantiation contain conservative values which work + for all types. + 2. Specializations may be declared to make distinctions between types. + 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers) + will automatically provide the appropriate specializations for all + types. + +EXAMPLE: + +//Copy an array of elements which have non-trivial copy constructors +template void + copy(_Tp* __source,_Tp* __destination,int __n,__false_type); +//Copy an array of elements which have trivial copy constructors. Use memcpy. +template void + copy(_Tp* __source,_Tp* __destination,int __n,__true_type); + +//Copy an array of any type by using the most efficient copy mechanism +template inline void copy(_Tp* __source,_Tp* __destination,int __n) { + copy(__source,__destination,__n, + typename __type_traits<_Tp>::has_trivial_copy_constructor()); +} +*/ + +struct __true_type {}; +struct __false_type {}; + +template + struct __type_traits + { + typedef __true_type this_dummy_member_must_be_first; + /* Do not remove this member. It informs a compiler which + automatically specializes __type_traits that this + __type_traits template is special. It just makes sure that + things work if an implementation is using a template + called __type_traits for something unrelated. */ + + /* The following restrictions should be observed for the sake of + compilers which automatically produce type specific specializations + of this class: + - You may reorder the members below if you wish + - You may remove any of the members below if you wish + - You must not rename members without making the corresponding + name change in the compiler + - Members you add will be treated like regular members unless + you add the appropriate support in the compiler. */ + + + typedef __false_type has_trivial_default_constructor; + typedef __false_type has_trivial_copy_constructor; + typedef __false_type has_trivial_assignment_operator; + typedef __false_type has_trivial_destructor; + typedef __false_type is_POD_type; + }; + + +// Provide some specializations. + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template + struct __type_traits<_Tp*> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +// The following could be written in terms of numeric_limits. +// We're doing it separately to reduce the number of dependencies. + +template + struct _Is_integer + { + typedef __false_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer + { + typedef __true_type _Integral; + }; + +template + struct _Is_normal_iterator + { + typedef __false_type _Normal; + }; + +// Forward declaration hack, should really include this from somewhere. +namespace __gnu_cxx +{ + template + class __normal_iterator; +} + +template + struct _Is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, + _Container> > + { + typedef __true_type _Normal; + }; + +#endif /* _TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_after.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_after.h new file mode 100644 index 00000000000..b74cab5dbac --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_after.h @@ -0,0 +1,499 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray_meta.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_AFTER_H +#define _VALARRAY_AFTER_H 1 + +#pragma GCC system_header + +namespace std +{ + + // + // gslice_array closure. + // + template class _GBase { + public: + typedef typename _Dom::value_type value_type; + + _GBase (const _Dom& __e, const valarray& __i) + : _M_expr (__e), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray& _M_index; + }; + + template class _GBase<_Array<_Tp> > { + public: + typedef _Tp value_type; + + _GBase (_Array<_Tp> __a, const valarray& __i) + : _M_array (__a), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + + private: + const _Array<_Tp> _M_array; + const valarray& _M_index; + }; + + template struct _GClos<_Expr,_Dom> : _GBase<_Dom> { + typedef _GBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _GClos (const _Dom& __e, const valarray& __i) + : _Base (__e, __i) {} + }; + + template + struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { + typedef _GBase<_Array<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _GClos (_Array<_Tp> __a, const valarray& __i) + : _Base (__a, __i) {} + }; + + // + // indirect_array closure + // + template class _IBase { + public: + typedef typename _Dom::value_type value_type; + + _IBase (const _Dom& __e, const valarray& __i) + : _M_expr (__e), _M_index (__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size() const { return _M_index.size(); } + + private: + const _Dom& _M_expr; + const valarray& _M_index; + }; + + template struct _IClos<_Expr,_Dom> : _IBase<_Dom> { + typedef _IBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _IClos (const _Dom& __e, const valarray& __i) + : _Base (__e, __i) {} + }; + + template + struct _IClos<_ValArray,_Tp> : _IBase > { + typedef _IBase > _Base; + typedef _Tp value_type; + + _IClos (const valarray<_Tp>& __a, const valarray& __i) + : _Base (__a, __i) {} + }; + + // + // class _Expr + // + template + class _Expr + { + public: + typedef _Tp value_type; + + _Expr(const _Clos&); + + const _Clos& operator()() const; + + value_type operator[](size_t) const; + valarray operator[](slice) const; + valarray operator[](const gslice&) const; + valarray operator[](const valarray&) const; + valarray operator[](const valarray&) const; + + _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type> + operator+() const; + + _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type> + operator-() const; + + _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type> + operator~() const; + + _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool> + operator!() const; + + size_t size() const; + value_type sum() const; + + valarray shift(int) const; + valarray cshift(int) const; + + value_type min() const; + value_type max() const; + + valarray apply(value_type (*)(const value_type&)) const; + valarray apply(value_type (*)(value_type)) const; + + private: + const _Clos _M_closure; + }; + + template + inline + _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} + + template + inline const _Clos& + _Expr<_Clos,_Tp>::operator()() const + { return _M_closure; } + + template + inline _Tp + _Expr<_Clos,_Tp>::operator[](size_t __i) const + { return _M_closure[__i]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](slice __s) const + { return _M_closure[__s]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const + { return _M_closure[__gs]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](const valarray& __m) const + { return _M_closure[__m]; } + + template + inline valarray<_Tp> + _Expr<_Clos,_Tp>::operator[](const valarray& __i) const + { return _M_closure[__i]; } + + template + inline size_t + _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::shift(int __n) const + { return valarray<_Tp>(_M_closure).shift(__n); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::cshift(int __n) const + { return valarray<_Tp>(_M_closure).cshift(__n); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + template + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + // XXX: replace this with a more robust summation algorithm. + template + inline _Tp + _Expr<_Clos,_Tp>::sum() const + { + size_t __n = _M_closure.size(); + if (__n == 0) + return _Tp(); + else + { + _Tp __s = _M_closure[--__n]; + while (__n != 0) + __s += _M_closure[--__n]; + return __s; + } + } + + template + inline _Tp + _Expr<_Clos, _Tp>::min() const + { return __valarray_min(_M_closure); } + + template + inline _Tp + _Expr<_Clos, _Tp>::max() const + { return __valarray_max(_M_closure); } + + template + inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool> + _Expr<_Dom,_Tp>::operator!() const + { + typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure; + return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); + } + +#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \ + _Expr<_Dom,_Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \ + } + + _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) + _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) + _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) + +#undef _DEFINE_EXPR_UNARY_OPERATOR + + +#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ + typename __fun<_Name, typename _Dom1::value_type>::result_type>\ + operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ + { \ + typedef typename _Dom1::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \ + } \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__t, __v())); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename __fun<_Name, _Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\ + typename __fun<_Name, typename _Dom::value_type>::result_type>\ +operator _Op(const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef typename __fun<_Name, _Tp>::result_type _Value; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) + _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) + _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) + _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) + _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) + _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) + _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) + _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) + _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) + _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) + _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) + _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) + _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(<, __less) + _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) + _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) + _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ + template \ + inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\ + _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e())); \ + } \ + \ + template \ + inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \ + _Name(const valarray<_Tp>& __v) \ + { \ + typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v)); \ + } + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(tanh) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ + template \ + inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \ + typename _Dom1::value_type> \ + _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ + { \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\ + return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ + typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ + _Fun(const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \ + typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ + _Fun(const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ + _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ + { \ + typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ + _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ + { \ + typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ + _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ + { \ + typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \ + } + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +} // std:: + + +#endif /* _CPP_VALARRAY_AFTER_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.h new file mode 100644 index 00000000000..e18e8e8e9e8 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.h @@ -0,0 +1,625 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray_array.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_ARRAY_H +#define _VALARRAY_ARRAY_H 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include + +namespace std +{ + // + // Helper functions on raw pointers + // + + // We get memory by the old fashion way + inline void* + __valarray_get_memory(size_t __n) + { return operator new(__n); } + + template + inline _Tp*__restrict__ + __valarray_get_storage(size_t __n) + { + return static_cast<_Tp*__restrict__> + (std::__valarray_get_memory(__n * sizeof(_Tp))); + } + + // Return memory to the system + inline void + __valarray_release_memory(void* __p) + { operator delete(__p); } + + // Turn a raw-memory into an array of _Tp filled with _Tp() + // This is required in 'valarray v(n);' + template + struct _Array_default_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { while (__b != __e) new(__b++) _Tp(); } + }; + + template + struct _Array_default_ctor<_Tp, true> + { + // For fundamental types, it suffices to say 'memset()' + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { std::memset(__b, 0, (__e - __b)*sizeof(_Tp)); } + }; + + template + inline void + __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e); + } + + // Turn a raw-memory into an array of _Tp filled with __t + // This is the required in valarray v(n, t). Also + // used in valarray<>::resize(). + template + struct _Array_init_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { while (__b != __e) new(__b++) _Tp(__t); } + }; + + template + struct _Array_init_ctor<_Tp, true> + { + inline static void + _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) + { while (__b != __e) *__b++ = __t; } + }; + + template + inline void + __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e, + const _Tp __t) + { + _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e, __t); + } + + // + // copy-construct raw array [__o, *) from plain array [__b, __e) + // We can't just say 'memcpy()' + // + template + struct _Array_copy_ctor + { + // Please note that this isn't exception safe. But + // valarrays aren't required to be exception safe. + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { while (__b != __e) new(__o++) _Tp(*__b++); } + }; + + template + struct _Array_copy_ctor<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } + }; + + template + inline void + __valarray_copy_construct(const _Tp* __restrict__ __b, + const _Tp* __restrict__ __e, + _Tp* __restrict__ __o) + { + _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__b, __e, __o); + } + + // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] + template + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, + size_t __s, _Tp* __restrict__ __o) + { + if (__is_fundamental<_Tp>::_M_type) + while (__n--) { *__o++ = *__a; __a += __s; } + else + while (__n--) { new(__o++) _Tp(*__a); __a += __s; } + } + + // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] + template + inline void + __valarray_copy_construct (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __o, size_t __n) + { + if (__is_fundamental<_Tp>::_M_type) + while (__n--) *__o++ = __a[*__i++]; + else + while (__n--) new (__o++) _Tp(__a[*__i++]); + } + + // Do the necessary cleanup when we're done with arrays. + template + inline void + __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e) + { + if (!__is_fundamental<_Tp>::_M_type) + while (__b != __e) { __b->~_Tp(); ++__b; } + } + + // Fill a plain array __a[<__n>] with __t + template + inline void + __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) + { while (__n--) *__a++ = __t; } + + // fill strided array __a[<__n-1 : __s>] with __t + template + inline void + __valarray_fill (_Tp* __restrict__ __a, size_t __n, + size_t __s, const _Tp& __t) + { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } + + // fill indir ect array __a[__i[<__n>]] with __i + template + inline void + __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, + size_t __n, const _Tp& __t) + { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } + + // copy plain array __a[<__n>] in __b[<__n>] + // For non-fundamental types, it is wrong to say 'memcpy()' + template + struct _Array_copier + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { while (__n--) *__b++ = *__a++; } + }; + + template + struct _Array_copier<_Tp, true> + { + inline static void + _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) + { std::memcpy (__b, __a, __n * sizeof (_Tp)); } + }; + + // Copy a plain array __a[<__n>] into a play array __b[<>] + template + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b) + { + _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>:: + _S_do_it(__a, __n, __b); + } + + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] + template + inline void + __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, + _Tp* __restrict__ __b) + { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } + + // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] + template + inline void + __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, + size_t __n, size_t __s) + { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } + + // Copy strided array __src[<__n : __s1>] into another + // strided array __dst[< : __s2>]. Their sizes must match. + template + inline void + __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, + _Tp* __restrict__ __dst, size_t __s2) + { + for (size_t __i = 0; __i < __n; ++__i) + __dst[__i * __s2] = __src [ __i * __s1]; + } + + + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] + template + inline void + __valarray_copy (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __b, size_t __n) + { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } + + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] + template + inline void + __valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b, const size_t* __restrict__ __i) + { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } + + // Copy the __n first elements of an indexed array __src[<__i>] into + // another indexed array __dst[<__j>]. + template + inline void + __valarray_copy(const _Tp* __restrict__ __src, size_t __n, + const size_t* __restrict__ __i, + _Tp* __restrict__ __dst, const size_t* __restrict__ __j) + { + for (size_t __k = 0; __k < __n; ++__k) + __dst[*__j++] = __src[*__i++]; + } + + // + // Compute the sum of elements in range [__f, __l) + // This is a naive algorithm. It suffers from cancelling. + // In the future try to specialize + // for _Tp = float, double, long double using a more accurate + // algorithm. + // + template + inline _Tp + __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(); + while (__f != __l) __r += *__f++; + return __r; + } + + // Compute the product of all elements in range [__f, __l) + template + inline _Tp + __valarray_product(const _Tp* __restrict__ __f, + const _Tp* __restrict__ __l) + { + _Tp __r = _Tp(1); + while (__f != __l) __r = __r * *__f++; + return __r; + } + + // Compute the min/max of an array-expression + template + inline typename _Ta::value_type + __valarray_min(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t < __r) + __r = __t; + } + return __r; + } + + template + inline typename _Ta::value_type + __valarray_max(const _Ta& __a) + { + size_t __s = __a.size(); + typedef typename _Ta::value_type _Value_type; + _Value_type __r = __s == 0 ? _Value_type() : __a[0]; + for (size_t __i = 1; __i < __s; ++__i) + { + _Value_type __t = __a[__i]; + if (__t > __r) + __r = __t; + } + return __r; + } + + // + // Helper class _Array, first layer of valarray abstraction. + // All operations on valarray should be forwarded to this class + // whenever possible. -- gdr + // + + template + struct _Array + { + explicit _Array (size_t); + explicit _Array (_Tp* const __restrict__); + explicit _Array (const valarray<_Tp>&); + _Array (const _Tp* __restrict__, size_t); + + _Tp* begin () const; + + _Tp* const __restrict__ _M_data; + }; + + template + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) + { std::__valarray_fill (__a._M_data, __n, __t); } + + template + inline void + __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) + { std::__valarray_fill (__a._M_data, __n, __s, __t); } + + template + inline void + __valarray_fill (_Array<_Tp> __a, _Array __i, + size_t __n, const _Tp& __t) + { std::__valarray_fill (__a._M_data, __i._M_data, __n, __t); } + + // Copy a plain array __a[<__n>] into a play array __b[<>] + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) + { std::__valarray_copy(__a._M_data, __n, __b._M_data); } + + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) + { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } + + // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] + template + inline void + __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) + { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } + + // Copy strided array __src[<__n : __s1>] into another + // strided array __dst[< : __s2>]. Their sizes must match. + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, + _Array<_Tp> __b, size_t __s2) + { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } + + + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] + template + inline void + __valarray_copy(_Array<_Tp> __a, _Array __i, + _Array<_Tp> __b, size_t __n) + { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } + + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] + template + inline void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array __i) + { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } + + // Copy the __n first elements of an indexed array __src[<__i>] into + // another indexed array __dst[<__j>]. + template + inline void + __valarray_copy(_Array<_Tp> __src, size_t __n, _Array __i, + _Array<_Tp> __dst, _Array __j) + { + std::__valarray_copy(__src._M_data, __n, __i._M_data, + __dst._M_data, __j._M_data); + } + + template + inline + _Array<_Tp>::_Array (size_t __n) + : _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_default_construct(_M_data, _M_data + __n); } + + template + inline + _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} + + template + inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) + : _M_data (__v._M_data) {} + + template + inline + _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) + : _M_data(__valarray_get_storage<_Tp>(__s)) + { std::__valarray_copy_construct(__b, __s, _M_data); } + + template + inline _Tp* + _Array<_Tp>::begin () const + { return _M_data; } + +#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ +{ \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ + *__p _Op##= __t; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ +{ \ + _Tp* __p = __a._M_data; \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ + _Array<_Tp> __b) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ + size_t __n, size_t __s) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __i, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + _Tp* __q (__b._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ + __a._M_data[*__j] _Op##= *__q; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array __i) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ + *__p _Op##= __b._M_data[*__j]; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __i, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + size_t* __j (__i._M_data); \ + for (size_t __k=0; __k<__n; ++__k, ++__j) \ + __a._M_data[*__j] _Op##= __e[__k]; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __m, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array __m) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ + while (! *ok) { \ + ++ok; \ + ++__q; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __m, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + bool* ok(__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= __e[__i]; \ + } \ +} + + _DEFINE_ARRAY_FUNCTION(+, __plus) + _DEFINE_ARRAY_FUNCTION(-, __minus) + _DEFINE_ARRAY_FUNCTION(*, __multiplies) + _DEFINE_ARRAY_FUNCTION(/, __divides) + _DEFINE_ARRAY_FUNCTION(%, __modulus) + _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) + _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) + _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) + _DEFINE_ARRAY_FUNCTION(<<, __shift_left) + _DEFINE_ARRAY_FUNCTION(>>, __shift_right) + +#undef _DEFINE_VALARRAY_FUNCTION +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif /* _ARRAY_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.tcc new file mode 100644 index 00000000000..fac5de6399b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_array.tcc @@ -0,0 +1,240 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef _VALARRAY_ARRAY_TCC +#define _VALARRAY_ARRAY_TCC 1 + +namespace std +{ + template + void + __valarray_fill(_Array<_Tp> __a, size_t __n, _Array __m, + const _Tp& __t) + { + _Tp* __p = __a._M_data; + bool* __ok (__m._M_data); + for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p) + { + while (!*__ok) + { + ++__ok; + ++__p; + } + *__p = __t; + } + } + + // Copy n elements of a into consecutive elements of b. When m is + // false, the corresponding element of a is skipped. m must contain + // at least n true elements. a must contain at least n elements and + // enough elements to match up with m through the nth true element + // of m. I.e. if n is 10, m has 15 elements with 5 false followed + // by 10 true, a must have 15 elements. + template + void + __valarray_copy(_Array<_Tp> __a, _Array __m, _Array<_Tp> __b, + size_t __n) + { + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; + ++__q, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + *__q = *__p; + } + } + + // Copy n consecutive elements from a into elements of b. Elements + // of b are skipped if the corresponding element of m is false. m + // must contain at least n true elements. b must have at least as + // many elements as the index of the nth true element of m. I.e. if + // m has 15 elements with 5 false followed by 10 true, b must have + // at least 15 elements. + template + void + __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array __m) + { + _Tp* __q (__b._M_data); + bool* __ok (__m._M_data); + for (_Tp* __p = __a._M_data; __p < __a._M_data+__n; + ++__p, ++__ok, ++__q) + { + while (! *__ok) + { + ++__ok; + ++__q; + } + *__q = *__p; + } + } + + // Copy n elements from a into elements of b. Elements of a are + // skipped if the corresponding element of m is false. Elements of + // b are skipped if the corresponding element of k is false. m and + // k must contain at least n true elements. a and b must have at + // least as many elements as the index of the nth true element of m. + template + void + __valarray_copy(_Array<_Tp> __a, _Array __m, size_t __n, + _Array<_Tp> __b, _Array __k) + { + _Tp* __p (__a._M_data); + _Tp* __q (__b._M_data); + bool* __srcok (__m._M_data); + bool* __dstok (__k._M_data); + for (size_t __i = 0; __i < __n; + ++__srcok, ++__p, ++__dstok, ++__q, ++__i) + { + while (! *__srcok) + { + ++__srcok; + ++__p; + } + while (! *__dstok) + { + ++__dstok; + ++__q; + } + *__q = *__p; + } + } + + // Copy n consecutive elements of e into consecutive elements of a. + // I.e. a[i] = e[i]. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__p) + *__p = __e[__i]; + } + + // Copy n consecutive elements of e into elements of a using stride + // s. I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2]. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, size_t __s) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, __p += __s) + *__p = __e[__i]; + } + + // Copy n consecutive elements of e into elements of a indexed by + // contents of i. I.e., a[i[0]] = e[0]. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array __i) + { + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j) + __a._M_data[*__j] = __e[__k]; + } + + // Copy n elements of e indexed by contents of f into elements of a + // indexed by contents of i. I.e., a[i[0]] = e[f[0]]. + template + void + __valarray_copy(_Array<_Tp> __e, _Array __f, + size_t __n, + _Array<_Tp> __a, _Array __i) + { + size_t* __g (__f._M_data); + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) + __a._M_data[*__j] = __e._M_data[*__g]; + } + + // Copy n consecutive elements of e into elements of a. Elements of + // a are skipped if the corresponding element of m is false. m must + // have at least n true elements and a must have at least as many + // elements as the index of the nth true element of m. I.e. if m + // has 5 false followed by 10 true elements and n == 10, a must have + // at least 15 elements. + template + void + __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array __m) + { + bool* __ok (__m._M_data); + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + *__p = __e[__i]; + } + } + + + template + void + __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a) + { + _Tp* __p (__a._M_data); + for (size_t __i = 0; __i < __n; ++__i, ++__p) + new (__p) _Tp(__e[__i]); + } + + + template + void + __valarray_copy_construct(_Array<_Tp> __a, _Array __m, + _Array<_Tp> __b, size_t __n) + { + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p) + { + while (! *__ok) + { + ++__ok; + ++__p; + } + new (__q) _Tp(*__p); + } + } +} // namespace std + +#endif /* _VALARRAY_ARRAY_TCC */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_before.h b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_before.h new file mode 100644 index 00000000000..263ac2f0e22 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/valarray_before.h @@ -0,0 +1,701 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray_meta.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_BEFORE_H +#define _VALARRAY_BEFORE_H 1 + +#pragma GCC system_header + +#include + +namespace std +{ + // + // Implementing a loosened valarray return value is tricky. + // First we need to meet 26.3.1/3: we should not add more than + // two levels of template nesting. Therefore we resort to template + // template to "flatten" loosened return value types. + // At some point we use partial specialization to remove one level + // template nesting due to _Expr<> + // + + // This class is NOT defined. It doesn't need to. + template class _Constant; + + // Implementations of unary functions applied to valarray<>s. + // I use hard-coded object functions here instead of a generic + // approach like pointers to function: + // 1) correctness: some functions take references, others values. + // we can't deduce the correct type afterwards. + // 2) efficiency -- object functions can be easily inlined + // 3) be Koenig-lookup-friendly + + struct __abs + { + template + _Tp operator()(const _Tp& __t) const { return abs(__t); } + }; + + struct __cos + { + template + _Tp operator()(const _Tp& __t) const { return cos(__t); } + }; + + struct __acos + { + template + _Tp operator()(const _Tp& __t) const { return acos(__t); } + }; + + struct __cosh + { + template + _Tp operator()(const _Tp& __t) const { return cosh(__t); } + }; + + struct __sin + { + template + _Tp operator()(const _Tp& __t) const { return sin(__t); } + }; + + struct __asin + { + template + _Tp operator()(const _Tp& __t) const { return asin(__t); } + }; + + struct __sinh + { + template + _Tp operator()(const _Tp& __t) const { return sinh(__t); } + }; + + struct __tan + { + template + _Tp operator()(const _Tp& __t) const { return tan(__t); } + }; + + struct __atan + { + template + _Tp operator()(const _Tp& __t) const { return atan(__t); } + }; + + struct __tanh + { + template + _Tp operator()(const _Tp& __t) const { return tanh(__t); } + }; + + struct __exp + { + template + _Tp operator()(const _Tp& __t) const { return exp(__t); } + }; + + struct __log + { + template + _Tp operator()(const _Tp& __t) const { return log(__t); } + }; + + struct __log10 + { + template + _Tp operator()(const _Tp& __t) const { return log10(__t); } + }; + + struct __sqrt + { + template + _Tp operator()(const _Tp& __t) const { return sqrt(__t); } + }; + + // In the past, we used to tailor operator applications semantics + // to the specialization of standard function objects (i.e. plus<>, etc.) + // That is incorrect. Therefore we provide our own surrogates. + + struct __unary_plus + { + template + _Tp operator()(const _Tp& __t) const { return +__t; } + }; + + struct __negate + { + template + _Tp operator()(const _Tp& __t) const { return -__t; } + }; + + struct __bitwise_not + { + template + _Tp operator()(const _Tp& __t) const { return ~__t; } + }; + + struct __plus + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + struct __minus + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + struct __multiplies + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + struct __divides + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + struct __modulus + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + struct __bitwise_xor + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x ^ __y; } + }; + + struct __bitwise_and + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x & __y; } + }; + + struct __bitwise_or + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x | __y; } + }; + + struct __shift_left + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x << __y; } + }; + + struct __shift_right + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x >> __y; } + }; + + struct __logical_and + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + struct __logical_or + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + struct __logical_not + { + template + bool operator()(const _Tp& __x) const { return !__x; } + }; + + struct __equal_to + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + struct __not_equal_to + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + struct __less + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + struct __greater + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + struct __less_equal + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + + struct __greater_equal + { + template + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + // The few binary functions we miss. + struct __atan2 + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return atan2(__x, __y); } + }; + + struct __pow + { + template + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return pow(__x, __y); } + }; + + + // We need these bits in order to recover the return type of + // some functions/operators now that we're no longer using + // function templates. + template + struct __fun + { + typedef _Tp result_type; + }; + + // several specializations for relational operators. + template + struct __fun<__logical_not, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__logical_and, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__logical_or, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__less, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__greater, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__less_equal, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__greater_equal, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__equal_to, _Tp> + { + typedef bool result_type; + }; + + template + struct __fun<__not_equal_to, _Tp> + { + typedef bool result_type; + }; + + // + // Apply function taking a value/const reference closure + // + + template + class _FunBase + { + public: + typedef typename _Dom::value_type value_type; + + _FunBase(const _Dom& __e, value_type __f(_Arg)) + : _M_expr(__e), _M_func(__f) {} + + value_type operator[](size_t __i) const + { return _M_func (_M_expr[__i]); } + + size_t size() const { return _M_expr.size ();} + + private: + const _Dom& _M_expr; + value_type (*_M_func)(_Arg); + }; + + template + struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> + { + typedef _FunBase<_Dom, typename _Dom::value_type> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} + }; + + template + struct _ValFunClos<_ValArray,_Tp> : _FunBase, _Tp> + { + typedef _FunBase, _Tp> _Base; + typedef _Tp value_type; + + _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} + }; + + template + struct _RefFunClos<_Expr,_Dom> : + _FunBase<_Dom, const typename _Dom::value_type&> + { + typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) + : _Base(__e, __f) {} + }; + + template + struct _RefFunClos<_ValArray,_Tp> : _FunBase, const _Tp&> + { + typedef _FunBase, const _Tp&> _Base; + typedef _Tp value_type; + + _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) + : _Base(__v, __f) {} + }; + + // + // Unary expression closure. + // + + template + class _UnBase + { + public: + typedef typename _Arg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _UnBase(const _Arg& __e) : _M_expr(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr[__i]); } + + size_t size() const { return _M_expr.size(); } + + private: + const _Arg& _M_expr; + }; + + template + struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> + { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + template + struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > + { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + + // + // Binary expression closure. + // + + template + class _BinBase + { + public: + typedef typename _FirstArg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1(__e1), _M_expr2(__e2) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; + }; + + + template + class _BinBase2 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase2(const _Clos& __e, const _Vt& __t) + : _M_expr1(__e), _M_expr2(__t) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; + }; + + template + class _BinBase1 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase1(const _Vt& __t, const _Clos& __e) + : _M_expr1(__t), _M_expr2(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1, _M_expr2[__i]); } + + size_t size() const { return _M_expr2.size(); } + + private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; + }; + + template + struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper,_Dom1,_Dom2> + { + typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> + : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > + { + typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base(__v, __w) {} + }; + + template + struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinBase<_Oper,_Dom,valarray > + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) + : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinBase<_Oper,valarray,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) + : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinBase2<_Oper,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> + : _BinBase1<_Oper,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} + }; + + template + struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> + : _BinBase2<_Oper,valarray<_Tp> > + { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} + }; + + template + struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> + : _BinBase1<_Oper,valarray<_Tp> > + { + typedef _BinBase1<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} + }; + + + // + // slice_array closure. + // + template class _SBase { + public: + typedef typename _Dom::value_type value_type; + + _SBase (const _Dom& __e, const slice& __s) + : _M_expr (__e), _M_slice (__s) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } + size_t size() const { return _M_slice.size (); } + + private: + const _Dom& _M_expr; + const slice& _M_slice; + }; + + template class _SBase<_Array<_Tp> > { + public: + typedef _Tp value_type; + + _SBase (_Array<_Tp> __a, const slice& __s) + : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), + _M_stride (__s.stride()) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[__i * _M_stride]; } + size_t size() const { return _M_size; } + + private: + const _Array<_Tp> _M_array; + const size_t _M_size; + const size_t _M_stride; + }; + + template struct _SClos<_Expr,_Dom> : _SBase<_Dom> { + typedef _SBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} + }; + + template + struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { + typedef _SBase<_Array<_Tp> > _Base; + typedef _Tp value_type; + + _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} + }; + +} // std:: + + +#endif /* _CPP_VALARRAY_BEFORE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bits/vector.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/bits/vector.tcc new file mode 100644 index 00000000000..786afab2ec9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bits/vector.tcc @@ -0,0 +1,414 @@ +// Vector implementation (out of line) -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file vector.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VECTOR_TCC +#define _VECTOR_TCC 1 + +namespace _GLIBCXX_STD +{ + template + void + vector<_Tp,_Alloc>:: + reserve(size_type __n) + { + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + const size_type __old_size = size(); + pointer __tmp = _M_allocate_and_copy(__n, + this->_M_impl._M_start, + this->_M_impl._M_finish); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = __tmp + __old_size; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + } + + template + typename vector<_Tp,_Alloc>::iterator + vector<_Tp,_Alloc>:: + insert(iterator __position, const value_type& __x) + { + size_type __n = __position - begin(); + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) + { + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; + } + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + + template + typename vector<_Tp,_Alloc>::iterator + vector<_Tp,_Alloc>:: + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); + return __position; + } + + template + typename vector<_Tp,_Alloc>::iterator + vector<_Tp,_Alloc>:: + erase(iterator __first, iterator __last) + { + iterator __i(std::copy(__last, end(), __first)); + std::_Destroy(__i, end()); + this->_M_impl._M_finish = this->_M_impl._M_finish - (__last - __first); + return __first; + } + + template + vector<_Tp,_Alloc>& + vector<_Tp,_Alloc>:: + operator=(const vector<_Tp,_Alloc>& __x) + { + if (&__x != this) + { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) + { + pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; + } + else if (size() >= __xlen) + { + iterator __i(std::copy(__x.begin(), __x.end(), begin())); + std::_Destroy(__i, end()); + } + else + { + std::copy(__x.begin(), __x.begin() + size(), this->_M_impl._M_start); + std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_impl._M_finish); + } + this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; + } + return *this; + } + + template + void + vector<_Tp,_Alloc>:: + _M_fill_assign(size_t __n, const value_type& __val) + { + if (__n > capacity()) + { + vector __tmp(__n, __val, get_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) + { + std::fill(begin(), end(), __val); + this->_M_impl._M_finish + = std::uninitialized_fill_n(this->_M_impl._M_finish, __n - size(), __val); + } + else + erase(fill_n(begin(), __n, __val), end()); + } + + template template + void + vector<_Tp,_Alloc>:: + _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag) + { + iterator __cur(begin()); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template template + void + vector<_Tp,_Alloc>:: + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + size_type __len = std::distance(__first, __last); + + if (__len > capacity()) + { + pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_finish = this->_M_impl._M_start + __len; + } + else if (size() >= __len) + { + iterator __new_finish(std::copy(__first, __last, this->_M_impl._M_start)); + std::_Destroy(__new_finish, end()); + this->_M_impl._M_finish = __new_finish.base(); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, this->_M_impl._M_start); + this->_M_impl._M_finish = std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); + } + } + + template + void + vector<_Tp,_Alloc>:: + _M_insert_aux(iterator __position, const _Tp& __x) + { + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) + { + std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1)); + ++this->_M_impl._M_finish; + _Tp __x_copy = __x; + std::copy_backward(__position, + iterator(this->_M_impl._M_finish-2), + iterator(this->_M_impl._M_finish-1)); + *__position = __x_copy; + } + else + { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start(this->_M_allocate(__len)); + iterator __new_finish(__new_start); + try + { + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), + __position, + __new_start); + std::_Construct(__new_finish.base(), __x); + ++__new_finish; + __new_finish = std::uninitialized_copy(__position, + iterator(this->_M_impl._M_finish), + __new_finish); + } + catch(...) + { + std::_Destroy(__new_start,__new_finish); + _M_deallocate(__new_start.base(),__len); + __throw_exception_again; + } + std::_Destroy(begin(), end()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; + } + } + + template + void + vector<_Tp,_Alloc>:: + _M_fill_insert(iterator __position, size_type __n, const value_type& __x) + { + if (__n != 0) + { + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) + { + value_type __x_copy = __x; + const size_type __elems_after = end() - __position; + iterator __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; + std::copy_backward(__position, __old_finish - __n, __old_finish); + std::fill(__position, __position + __n, __x_copy); + } + else + { + std::uninitialized_fill_n(this->_M_impl._M_finish, + __n - __elems_after, + __x_copy); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; + std::fill(__position, __old_finish, __x_copy); + } + } + else + { + const size_type __old_size = size(); + const size_type __len = __old_size + std::max(__old_size, __n); + iterator __new_start(this->_M_allocate(__len)); + iterator __new_finish(__new_start); + try + { + __new_finish = std::uninitialized_copy(begin(), __position, + __new_start); + __new_finish = std::uninitialized_fill_n(__new_finish, __n, __x); + __new_finish = std::uninitialized_copy(__position, end(), + __new_finish); + } + catch(...) + { + std::_Destroy(__new_start,__new_finish); + _M_deallocate(__new_start.base(),__len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; + } + } + } + + template template + void + vector<_Tp,_Alloc>:: + _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) + { + for ( ; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template template + void + vector<_Tp,_Alloc>:: + _M_range_insert(iterator __position,_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) + { + const size_type __elems_after = end() - __position; + iterator __old_finish(this->_M_impl._M_finish); + if (__elems_after > __n) + { + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; + std::copy_backward(__position, __old_finish - __n, __old_finish); + std::copy(__first, __last, __position); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elems_after); + std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; + std::copy(__first, __mid, __position); + } + } + else + { + const size_type __old_size = size(); + const size_type __len = __old_size + std::max(__old_size, __n); + iterator __new_start(this->_M_allocate(__len)); + iterator __new_finish(__new_start); + try + { + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), + __position, __new_start); + __new_finish = std::uninitialized_copy(__first, __last, + __new_finish); + __new_finish = std::uninitialized_copy(__position, + iterator(this->_M_impl._M_finish), + __new_finish); + } + catch(...) + { + std::_Destroy(__new_start,__new_finish); + _M_deallocate(__new_start.base(), __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; + } + } + } +} // namespace std + +#endif /* _VECTOR_TCC */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/bitset b/reactos/tools/ppc-build/core-headers/g++-v3/bitset new file mode 100644 index 00000000000..01e3f904e47 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/bitset @@ -0,0 +1,1229 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file bitset + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_BITSET +#define _GLIBCXX_BITSET 1 + +#pragma GCC system_header + +#include // For size_t +#include // For memset +#include // For numeric_limits +#include +#include // For invalid_argument, out_of_range, + // overflow_error +#include // For ostream (operator<<) +#include // For istream (operator>>) + +#define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits::digits +#define _GLIBCXX_BITSET_WORDS(__n) \ + ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD) + +namespace _GLIBCXX_STD +{ + /** + * @if maint + * Base class, general case. It is a class inveriant that _Nw will be + * nonnegative. + * + * See documentation for bitset. + * @endif + */ + template + struct _Base_bitset + { + typedef unsigned long _WordT; + + /// 0 is the least significant word. + _WordT _M_w[_Nw]; + + _Base_bitset() { _M_do_reset(); } + _Base_bitset(unsigned long __val) + { + _M_do_reset(); + _M_w[0] = __val; + } + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& + _M_getword(size_t __pos) + { return _M_w[_S_whichword(__pos)]; } + + _WordT + _M_getword(size_t __pos) const + { return _M_w[_S_whichword(__pos)]; } + + _WordT& + _M_hiword() { return _M_w[_Nw - 1]; } + + _WordT + _M_hiword() const { return _M_w[_Nw - 1]; } + + void + _M_do_and(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] &= __x._M_w[__i]; + } + + void + _M_do_or(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] |= __x._M_w[__i]; + } + + void + _M_do_xor(const _Base_bitset<_Nw>& __x) + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] ^= __x._M_w[__i]; + } + + void + _M_do_left_shift(size_t __shift); + + void + _M_do_right_shift(size_t __shift); + + void + _M_do_flip() + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] = ~_M_w[__i]; + } + + void + _M_do_set() + { + for (size_t __i = 0; __i < _Nw; __i++) + _M_w[__i] = ~static_cast<_WordT>(0); + } + + void + _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); } + + bool + _M_is_equal(const _Base_bitset<_Nw>& __x) const + { + for (size_t __i = 0; __i < _Nw; ++__i) + { + if (_M_w[__i] != __x._M_w[__i]) + return false; + } + return true; + } + + bool + _M_is_any() const + { + for (size_t __i = 0; __i < _Nw; __i++) + { + if (_M_w[__i] != static_cast<_WordT>(0)) + return true; + } + return false; + } + + size_t + _M_do_count() const + { + size_t __result = 0; + for (size_t __i = 0; __i < _Nw; __i++) + __result += __builtin_popcountl(_M_w[__i]); + return __result; + } + + unsigned long + _M_do_to_ulong() const; + + // find first "on" bit + size_t + _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t + _M_do_find_next(size_t __prev, size_t __not_found) const; + }; + + // Definitions of non-inline functions from _Base_bitset. + template + void + _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; + + if (__offset == 0) + for (size_t __n = _Nw - 1; __n >= __wshift; --__n) + _M_w[__n] = _M_w[__n - __wshift]; + else + { + const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; + for (size_t __n = _Nw - 1; __n > __wshift; --__n) + _M_w[__n] = (_M_w[__n - __wshift] << __offset) | + (_M_w[__n - __wshift - 1] >> __sub_offset); + _M_w[__wshift] = _M_w[0] << __offset; + } + + std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); + } + } + + template + void + _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __limit = _Nw - __wshift - 1; + + if (__offset == 0) + for (size_t __n = 0; __n <= __limit; ++__n) + _M_w[__n] = _M_w[__n + __wshift]; + else + { + const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; + for (size_t __n = 0; __n < __limit; ++__n) + _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | + (_M_w[__n + __wshift + 1] << __sub_offset); + _M_w[__limit] = _M_w[_Nw-1] >> __offset; + } + + std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); + } + } + + template + unsigned long + _Base_bitset<_Nw>::_M_do_to_ulong() const + { + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); + return _M_w[0]; + } + + template + size_t + _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const + { + for (size_t __i = 0; __i < _Nw; __i++) + { + _WordT __thisword = _M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); + } + // not found, so return an indication of failure. + return __not_found; + } + + template + size_t + _Base_bitset<_Nw>::_M_do_find_next(size_t __prev, size_t __not_found) const + { + // make bound inclusive + ++__prev; + + // check out of bounds + if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = _M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); + + // check subsequent words + __i++; + for ( ; __i < _Nw; __i++ ) + { + __thisword = _M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); + } + // not found, so return an indication of failure. + return __not_found; + } // end _M_do_find_next + + + /** + * @if maint + * Base class, specialization for a single word. + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<1> + { + typedef unsigned long _WordT; + _WordT _M_w; + + _Base_bitset( void ) : _M_w(0) {} + _Base_bitset(unsigned long __val) : _M_w(__val) {} + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + _WordT& + _M_getword(size_t) { return _M_w; } + + _WordT + _M_getword(size_t) const { return _M_w; } + + _WordT& + _M_hiword() { return _M_w; } + + _WordT + _M_hiword() const { return _M_w; } + + void + _M_do_and(const _Base_bitset<1>& __x) { _M_w &= __x._M_w; } + + void + _M_do_or(const _Base_bitset<1>& __x) { _M_w |= __x._M_w; } + + void + _M_do_xor(const _Base_bitset<1>& __x) { _M_w ^= __x._M_w; } + + void + _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } + + void + _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } + + void + _M_do_flip() { _M_w = ~_M_w; } + + void + _M_do_set() { _M_w = ~static_cast<_WordT>(0); } + + void + _M_do_reset() { _M_w = 0; } + + bool + _M_is_equal(const _Base_bitset<1>& __x) const + { return _M_w == __x._M_w; } + + bool + _M_is_any() const { return _M_w != 0; } + + size_t + _M_do_count() const { return __builtin_popcountl(_M_w); } + + unsigned long + _M_do_to_ulong() const { return _M_w; } + + size_t + _M_do_find_first(size_t __not_found) const + { + if (_M_w != 0) + return __builtin_ctzl(_M_w); + else + return __not_found; + } + + // find the next "on" bit that follows "prev" + size_t + _M_do_find_next(size_t __prev, size_t __not_found) const + { + ++__prev; + if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) + return __not_found; + + _WordT __x = _M_w >> __prev; + if (__x != 0) + return __builtin_ctzl(__x) + __prev; + else + return __not_found; + } + }; + + + /** + * @if maint + * Base class, specialization for no storage (zero-length %bitset). + * + * See documentation for bitset. + * @endif + */ + template<> + struct _Base_bitset<0> + { + typedef unsigned long _WordT; + + _Base_bitset() {} + _Base_bitset(unsigned long) {} + + static size_t + _S_whichword(size_t __pos ) + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } + + static size_t + _S_whichbyte(size_t __pos ) + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } + + static size_t + _S_whichbit(size_t __pos ) + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } + + static _WordT + _S_maskbit(size_t __pos ) + { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } + + // This would normally give access to the data. The bounds-checking + // in the bitset class will prevent the user from getting this far, + // but (1) it must still return an lvalue to compile, and (2) the + // user might call _Unchecked_set directly, in which case this /needs/ + // to fail. Let's not penalize zero-length users unless they actually + // make an unchecked call; all the memory ugliness is therefore + // localized to this single should-never-get-this-far function. + _WordT& + _M_getword(size_t) const + { + __throw_out_of_range(__N("_Base_bitset::_M_getword")); + return *new _WordT; + } + + _WordT + _M_hiword() const { return 0; } + + void + _M_do_and(const _Base_bitset<0>&) { } + + void + _M_do_or(const _Base_bitset<0>&) { } + + void + _M_do_xor(const _Base_bitset<0>&) { } + + void + _M_do_left_shift(size_t) { } + + void + _M_do_right_shift(size_t) { } + + void + _M_do_flip() { } + + void + _M_do_set() { } + + void + _M_do_reset() { } + + // Are all empty bitsets equal to each other? Are they equal to + // themselves? How to compare a thing which has no state? What is + // the sound of one zero-length bitset clapping? + bool + _M_is_equal(const _Base_bitset<0>&) const { return true; } + + bool + _M_is_any() const { return false; } + + size_t + _M_do_count() const { return 0; } + + unsigned long + _M_do_to_ulong() const { return 0; } + + // Normally "not found" is the size, but that could also be + // misinterpreted as an index in this corner case. Oh well. + size_t + _M_do_find_first(size_t) const { return 0; } + + size_t + _M_do_find_next(size_t, size_t) const { return 0; } + }; + + + // Helper class to zero out the unused high-order bits in the highest word. + template + struct _Sanitize + { + static void _S_do_sanitize(unsigned long& __val) + { __val &= ~((~static_cast(0)) << _Extrabits); } + }; + + template<> + struct _Sanitize<0> + { static void _S_do_sanitize(unsigned long) { } }; + + + /** + * @brief The %bitset class represents a @e fixed-size sequence of bits. + * + * @ingroup Containers + * + * (Note that %bitset does @e not meet the formal requirements of a + * container. Mainly, it lacks iterators.) + * + * The template argument, @a Nb, may be any non-negative number, + * specifying the number of bits (e.g., "0", "12", "1024*1024"). + * + * In the general unoptimized case, storage is allocated in word-sized + * blocks. Let B be the number of bits in a word, then (Nb+(B-1))/B + * words will be used for storage. B - Nb%B bits are unused. (They are + * the high-order bits in the highest word.) It is a class invariant + * that those unused bits are always zero. + * + * If you think of %bitset as "a simple array of bits," be aware that + * your mental picture is reversed: a %bitset behaves the same way as + * bits in integers do, with the bit at index 0 in the "least significant + * / right-hand" position, and the bit at index Nb-1 in the "most + * significant / left-hand" position. Thus, unlike other containers, a + * %bitset's index "counts from right to left," to put it very loosely. + * + * This behavior is preserved when translating to and from strings. For + * example, the first line of the following program probably prints + * "b('a') is 0001100001" on a modern ASCII system. + * + * @code + * #include + * #include + * #include + * + * using namespace std; + * + * int main() + * { + * long a = 'a'; + * bitset<10> b(a); + * + * cout << "b('a') is " << b << endl; + * + * ostringstream s; + * s << b; + * string str = s.str(); + * cout << "index 3 in the string is " << str[3] << " but\n" + * << "index 3 in the bitset is " << b[3] << endl; + * } + * @endcode + * + * Also see http://gcc.gnu.org/onlinedocs/libstdc++/ext/sgiexts.html#ch23 + * for a description of extensions. + * + * @if maint + * Most of the actual code isn't contained in %bitset<> itself, but in the + * base class _Base_bitset. The base class works with whole words, not with + * individual bits. This allows us to specialize _Base_bitset for the + * important special case where the %bitset is only a single word. + * + * Extra confusion can result due to the fact that the storage for + * _Base_bitset @e is a regular array, and is indexed as such. This is + * carefully encapsulated. + * @endif + */ + template + class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> + { + private: + typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; + typedef unsigned long _WordT; + + void + _M_do_sanitize() + { + _Sanitize<_Nb%_GLIBCXX_BITSET_BITS_PER_WORD>:: + _S_do_sanitize(this->_M_hiword()); + } + + public: + /** + * This encapsulates the concept of a single bit. An instance of this + * class is a proxy for an actual bit; this way the individual bit + * operations are done as faster word-size bitwise instructions. + * + * Most users will never need to use this class directly; conversions + * to and from bool are automatic and should be transparent. Overloaded + * operators help to preserve the illusion. + * + * (On a typical system, this "bit %reference" is 64 times the size of + * an actual bit. Ha.) + */ + class reference + { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + public: + reference(bitset& __b, size_t __pos) + { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _Base::_S_whichbit(__pos); + } + + ~reference() { } + + // For b[i] = __x; + reference& + operator=(bool __x) + { + if ( __x ) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // For b[i] = b[__j]; + reference& + operator=(const reference& __j) + { + if ( (*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos)) ) + *_M_wp |= _Base::_S_maskbit(_M_bpos); + else + *_M_wp &= ~_Base::_S_maskbit(_M_bpos); + return *this; + } + + // Flips the bit + bool + operator~() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } + + // For __x = b[i]; + operator bool() const + { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } + + // For b[i].flip(); + reference& + flip() + { + *_M_wp ^= _Base::_S_maskbit(_M_bpos); + return *this; + } + }; + friend class reference; + + // 23.3.5.1 constructors: + /// All bits set to zero. + bitset() { } + + /// Initial bits bitwise-copied from a single word (others set to zero). + bitset(unsigned long __val) : _Base(__val) + { _M_do_sanitize(); } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use; defaults + * to zero. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template + explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position = 0) : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, + basic_string<_CharT, _Traits, _Alloc>::npos); + } + + /** + * @brief Use a subset of a string. + * @param s A string of '0' and '1' characters. + * @param position Index of the first character in @a s to use. + * @param n The number of characters to copy. + * @throw std::out_of_range If @a pos is bigger the size of @a s. + * @throw std::invalid_argument If a character appears in the string + * which is neither '0' nor '1'. + */ + template + bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position, size_t __n) : _Base() + { + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, __n); + } + + // 23.3.5.2 bitset operations: + //@{ + /** + * @brief Operations on bitsets. + * @param rhs A same-sized bitset. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + this->_M_do_and(__rhs); + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + this->_M_do_or(__rhs); + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + this->_M_do_xor(__rhs); + return *this; + } + //@} + + //@{ + /** + * @brief Operations on bitsets. + * @param position The number of places to shift. + * + * These should be self-explanatory. + */ + bitset<_Nb>& + operator<<=(size_t __position) + { + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_left_shift(__position); + this->_M_do_sanitize(); + } + else + this->_M_do_reset(); + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __position) + { + if (__builtin_expect(__position < _Nb, 1)) + { + this->_M_do_right_shift(__position); + this->_M_do_sanitize(); + } + else + this->_M_do_reset(); + return *this; + } + //@} + + //@{ + /** + * These versions of single-bit set, reset, flip, and test are + * extensions from the SGI version. They do no range checking. + * @ingroup SGIextensions + */ + bitset<_Nb>& + _Unchecked_set(size_t __pos) + { + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_set(size_t __pos, int __val) + { + if (__val) + this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); + else + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_reset(size_t __pos) + { + this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); + return *this; + } + + bitset<_Nb>& + _Unchecked_flip(size_t __pos) + { + this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); + return *this; + } + + bool + _Unchecked_test(size_t __pos) const + { + return (this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) + != static_cast<_WordT>(0); + } + //@} + + // Set, reset, and flip. + /** + * @brief Sets every bit to true. + */ + bitset<_Nb>& + set() + { + this->_M_do_set(); + this->_M_do_sanitize(); + return *this; + } + + /** + * @brief Sets a given bit to a particular value. + * @param position The index of the bit. + * @param val Either true or false, defaults to true. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + set(size_t __position, bool __val = true) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::set")); + return _Unchecked_set(__position, __val); + } + + /** + * @brief Sets every bit to false. + */ + bitset<_Nb>& + reset() + { + this->_M_do_reset(); + return *this; + } + + /** + * @brief Sets a given bit to false. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + * + * Same as writing @c set(pos,false). + */ + bitset<_Nb>& + reset(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::reset")); + return _Unchecked_reset(__position); + } + + /** + * @brief Toggles every bit to its opposite value. + */ + bitset<_Nb>& + flip() + { + this->_M_do_flip(); + this->_M_do_sanitize(); + return *this; + } + + /** + * @brief Toggles a given bit to its opposite value. + * @param position The index of the bit. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bitset<_Nb>& + flip(size_t __position) + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::flip")); + return _Unchecked_flip(__position); + } + + /// See the no-argument flip(). + bitset<_Nb> + operator~() const { return bitset<_Nb>(*this).flip(); } + + //@{ + /** + * @brief Array-indexing support. + * @param position Index into the %bitset. + * @return A bool for a 'const %bitset'. For non-const bitsets, an + * instance of the reference proxy class. + * @note These operators do no range checking and throw no exceptions, + * as required by DR 11 to the standard. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already + * resolves DR 11 (items 1 and 2), but does not do the range-checking + * required by that DR's resolution. -pme + * The DR has since been changed: range-checking is a precondition + * (users' responsibility), and these functions must not throw. -pme + * @endif + */ + reference + operator[](size_t __position) { return reference(*this,__position); } + + bool + operator[](size_t __position) const { return _Unchecked_test(__position); } + //@} + + /** + * @brief Retuns a numerical interpretation of the %bitset. + * @return The integral equivalent of the bits. + * @throw std::overflow_error If there are too many bits to be + * represented in an @c unsigned @c long. + */ + unsigned long + to_ulong() const { return this->_M_do_to_ulong(); } + + /** + * @brief Retuns a character interpretation of the %bitset. + * @return The string equivalent of the bits. + * + * Note the ordering of the bits: decreasing character positions + * correspond to increasing bit positions (see the main class notes for + * an example). + * + * Also note that you must specify the string's template parameters + * explicitly. Given a bitset @c bs and a string @s: + * @code + * s = bs.to_string,allocator >(); + * @endcode + */ + template + basic_string<_CharT, _Traits, _Alloc> + to_string() const + { + basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } + + // Helper functions for string operations. + template + void + _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t, size_t); + + template + void + _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; + + /// Returns the number of bits which are set. + size_t + count() const { return this->_M_do_count(); } + + /// Returns the total number of bits. + size_t + size() const { return _Nb; } + + //@{ + /// These comparisons for equality/inequality are, well, @e bitwise. + bool + operator==(const bitset<_Nb>& __rhs) const + { return this->_M_is_equal(__rhs); } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return !this->_M_is_equal(__rhs); } + //@} + + /** + * @brief Tests the value of a bit. + * @param position The index of a bit. + * @return The value at @a pos. + * @throw std::out_of_range If @a pos is bigger the size of the %set. + */ + bool + test(size_t __position) const + { + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::test")); + return _Unchecked_test(__position); + } + + /** + * @brief Tests whether any of the bits are on. + * @return True if at least one bit is set. + */ + bool + any() const { return this->_M_is_any(); } + + /** + * @brief Tests whether any of the bits are on. + * @return True if none of the bits are set. + */ + bool + none() const { return !this->_M_is_any(); } + + //@{ + /// Self-explanatory. + bitset<_Nb> + operator<<(size_t __position) const + { return bitset<_Nb>(*this) <<= __position; } + + bitset<_Nb> + operator>>(size_t __position) const + { return bitset<_Nb>(*this) >>= __position; } + //@} + + /** + * @brief Finds the index of the first "on" bit. + * @return The index of the first bit set, or size() if not found. + * @ingroup SGIextensions + * @sa _Find_next + */ + size_t + _Find_first() const + { return this->_M_do_find_first(_Nb); } + + /** + * @brief Finds the index of the next "on" bit after prev. + * @return The index of the next bit set, or size() if not found. + * @param prev Where to start searching. + * @ingroup SGIextensions + * @sa _Find_first + */ + size_t + _Find_next(size_t __prev ) const + { return this->_M_do_find_next(__prev, _Nb); } + }; + + // Definitions of non-inline member functions. + template + template + void + bitset<_Nb>::_M_copy_from_string(const basic_string<_CharT, _Traits, + _Alloc>& __s, size_t __pos, size_t __n) + { + reset(); + const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos)); + for (size_t __i = 0; __i < __nbits; ++__i) + { + switch(__s[__pos + __nbits - __i - 1]) + { + case '0': + break; + case '1': + set(__i); + break; + default: + __throw_invalid_argument(__N("bitset::_M_copy_from_string")); + } + } + } + + template + template + void + bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits, + _Alloc>& __s) const + { + __s.assign(_Nb, '0'); + for (size_t __i = 0; __i < _Nb; ++__i) + if (_Unchecked_test(__i)) + __s[_Nb - 1 - __i] = '1'; + } + + // 23.3.5.3 bitset operations: + //@{ + /** + * @brief Global bitwise operations on bitsets. + * @param x A bitset. + * @param y A bitset of the same size as @a x. + * @return A new bitset. + * + * These should be self-explanatory. + */ + template + inline bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result &= __y; + return __result; + } + + template + inline bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result |= __y; + return __result; + } + + template + inline bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { + bitset<_Nb> __result(__x); + __result ^= __y; + return __result; + } + //@} + + //@{ + /** + * @brief Global I/O operators for bitsets. + * + * Direct I/O between streams and bitsets is supported. Output is + * straightforward. Input will skip whitespace, only accept '0' and '1' + * characters, and will only extract as many digits as the %bitset will + * hold. + */ + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { + typedef typename _Traits::char_type char_type; + basic_string<_CharT, _Traits> __tmp; + __tmp.reserve(_Nb); + + ios_base::iostate __state = ios_base::goodbit; + typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); + if (__sentry) + { + try + { + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 303. Bitset input operator underspecified + const char_type __zero = __is.widen('0'); + const char_type __one = __is.widen('1'); + for (size_t __i = 0; __i < _Nb; ++__i) + { + static typename _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) + { + __state |= ios_base::eofbit; + break; + } + else + { + char_type __c2 = _Traits::to_char_type(__c1); + if (__c2 == __zero) + __tmp.push_back('0'); + else if (__c2 == __one) + __tmp.push_back('1'); + else if (_Traits::eq_int_type(__buf->sputbackc(__c2), + __eof)) + { + __state |= ios_base::failbit; + break; + } + } + } + } + catch(...) + { __is._M_setstate(ios_base::badbit); } + } + + if (__tmp.empty() && _Nb) + __state |= ios_base::failbit; + else + __x._M_copy_from_string(__tmp, static_cast(0), _Nb); + if (__state) + __is.setstate(__state); + return __is; + } + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) + { + basic_string<_CharT, _Traits> __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; + } + //@} +} // namespace std + +#undef _GLIBCXX_BITSET_WORDS +#undef _GLIBCXX_BITSET_BITS_PER_WORD + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_BITSET */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cassert b/reactos/tools/ppc-build/core-headers/g++-v3/cassert new file mode 100644 index 00000000000..9fc1079b82a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cassert @@ -0,0 +1,48 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.2 Assertions +// + +/** @file cassert + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c assert.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +// No include guards on this header... + +#pragma GCC system_header + +#include diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cctype b/reactos/tools/ppc-build/core-headers/g++-v3/cctype new file mode 100644 index 00000000000..65a4214657c --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cctype @@ -0,0 +1,83 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: +// + +/** @file cctype + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c ctype.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CCTYPE +#define _GLIBCXX_CCTYPE 1 + +#pragma GCC system_header + +#include +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef isalnum +#undef isalpha +#undef iscntrl +#undef isdigit +#undef isgraph +#undef islower +#undef isprint +#undef ispunct +#undef isspace +#undef isupper +#undef isxdigit +#undef tolower +#undef toupper + +namespace std +{ + using ::isalnum; + using ::isalpha; + using ::iscntrl; + using ::isdigit; + using ::isgraph; + using ::islower; + using ::isprint; + using ::ispunct; + using ::isspace; + using ::isupper; + using ::isxdigit; + using ::tolower; + using ::toupper; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cerrno b/reactos/tools/ppc-build/core-headers/g++-v3/cerrno new file mode 100644 index 00000000000..7915e14ba27 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cerrno @@ -0,0 +1,55 @@ +// The -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.3 Error numbers +// + +/** @file cerrno + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c errno.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CERRNO +#define _GLIBCXX_CERRNO 1 + +#pragma GCC system_header + +#include + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef errno +#define errno errno +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cfloat b/reactos/tools/ppc-build/core-headers/g++-v3/cfloat new file mode 100644 index 00000000000..4c5bb00f204 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cfloat @@ -0,0 +1,50 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +/** @file cfloat + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c float.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CFLOAT +#define _GLIBCXX_CFLOAT 1 + +#pragma GCC system_header + +#include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ciso646 b/reactos/tools/ppc-build/core-headers/g++-v3/ciso646 new file mode 100644 index 00000000000..0993a0a7d6f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ciso646 @@ -0,0 +1,37 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ciso646 + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c iso646.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/climits b/reactos/tools/ppc-build/core-headers/g++-v3/climits new file mode 100644 index 00000000000..f4e1d8f77fa --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/climits @@ -0,0 +1,51 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +/** @file climits + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c limits.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CLIMITS +#define _GLIBCXX_CLIMITS 1 + +#pragma GCC system_header + +#include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/clocale b/reactos/tools/ppc-build/core-headers/g++-v3/clocale new file mode 100644 index 00000000000..988b84924af --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/clocale @@ -0,0 +1,62 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.2.2 Implementation properties: C library +// + +/** @file clocale + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c locale.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CLOCALE +#define _GLIBCXX_CLOCALE 1 + +#pragma GCC system_header + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef setlocale +#undef localeconv + +namespace std +{ + using ::lconv; + using ::setlocale; + using ::localeconv; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cmath b/reactos/tools/ppc-build/core-headers/g++-v3/cmath new file mode 100644 index 00000000000..66866b2cc3a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cmath @@ -0,0 +1,595 @@ +// -*- C++ -*- C forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 26.5 C library +// + +/** @file cmath + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c math.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CMATH +#define _GLIBCXX_CMATH 1 + +#pragma GCC system_header + +#include +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef abs +#undef div +#undef acos +#undef asin +#undef atan +#undef atan2 +#undef ceil +#undef cos +#undef cosh +#undef exp +#undef fabs +#undef floor +#undef fmod +#undef frexp +#undef ldexp +#undef log +#undef log10 +#undef modf +#undef pow +#undef sin +#undef sinh +#undef sqrt +#undef tan +#undef tanh + + +namespace std +{ + // Forward declaration of a helper function. This really should be + // an `exported' forward declaration. + template _Tp __cmath_power(_Tp, unsigned int); + + inline double + abs(double __x) + { return __builtin_fabs(__x); } + + inline float + abs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + abs(long double __x) + { return __builtin_fabsl(__x); } + + using ::acos; + + inline float + acos(float __x) + { return __builtin_acosf(__x); } + + inline long double + acos(long double __x) + { return __builtin_acosl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + acos(_Tp __x) + { + return __builtin_acos(__x); + } + + using ::asin; + + inline float + asin(float __x) + { return __builtin_asinf(__x); } + + inline long double + asin(long double __x) + { return __builtin_asinl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + asin(_Tp __x) + { return __builtin_asin(__x); } + + using ::atan; + + inline float + atan(float __x) + { return __builtin_atanf(__x); } + + inline long double + atan(long double __x) + { return __builtin_atanl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + atan(_Tp __x) + { return __builtin_atan(__x); } + + using ::atan2; + + inline float + atan2(float __y, float __x) + { return __builtin_atan2f(__y, __x); } + + inline long double + atan2(long double __y, long double __x) + { return __builtin_atan2l(__y, __x); } + + template + inline typename __enable_if::_M_type + && __is_integer<_Up>::_M_type>::_M_type + atan2(_Tp __y, _Up __x) + { return __builtin_atan2(__y, __x); } + + using ::ceil; + + inline float + ceil(float __x) + { return __builtin_ceilf(__x); } + + inline long double + ceil(long double __x) + { return __builtin_ceill(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + ceil(_Tp __x) + { return __builtin_ceil(__x); } + + using ::cos; + + inline float + cos(float __x) + { return __builtin_cosf(__x); } + + inline long double + cos(long double __x) + { return __builtin_cosl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + cos(_Tp __x) + { return __builtin_cos(__x); } + + using ::cosh; + + inline float + cosh(float __x) + { return __builtin_coshf(__x); } + + inline long double + cosh(long double __x) + { return __builtin_coshl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + cosh(_Tp __x) + { return __builtin_cosh(__x); } + + using ::exp; + + inline float + exp(float __x) + { return __builtin_expf(__x); } + + inline long double + exp(long double __x) + { return __builtin_expl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + exp(_Tp __x) + { return __builtin_exp(__x); } + + using ::fabs; + + inline float + fabs(float __x) + { return __builtin_fabsf(__x); } + + inline long double + fabs(long double __x) + { return __builtin_fabsl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + fabs(_Tp __x) + { return __builtin_fabs(__x); } + + using ::floor; + + inline float + floor(float __x) + { return __builtin_floorf(__x); } + + inline long double + floor(long double __x) + { return __builtin_floorl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + floor(_Tp __x) + { return __builtin_floor(__x); } + + using ::fmod; + + inline float + fmod(float __x, float __y) + { return __builtin_fmodf(__x, __y); } + + inline long double + fmod(long double __x, long double __y) + { return __builtin_fmodl(__x, __y); } + + using ::frexp; + + inline float + frexp(float __x, int* __exp) + { return __builtin_frexpf(__x, __exp); } + + inline long double + frexp(long double __x, int* __exp) + { return __builtin_frexpl(__x, __exp); } + + template + inline typename __enable_if::_M_type>::_M_type + frexp(_Tp __x, int* __exp) + { return __builtin_frexp(__x, __exp); } + + using ::ldexp; + + inline float + ldexp(float __x, int __exp) + { return __builtin_ldexpf(__x, __exp); } + + inline long double + ldexp(long double __x, int __exp) + { return __builtin_ldexpl(__x, __exp); } + + template + inline typename __enable_if::_M_type>::_M_type + ldexp(_Tp __x, int __exp) + { return __builtin_ldexp(__x, __exp); } + + using ::log; + + inline float + log(float __x) + { return __builtin_logf(__x); } + + inline long double + log(long double __x) + { return __builtin_logl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + log(_Tp __x) + { return __builtin_log(__x); } + + using ::log10; + + inline float + log10(float __x) + { return __builtin_log10f(__x); } + + inline long double + log10(long double __x) + { return __builtin_log10l(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + log10(_Tp __x) + { return __builtin_log10(__x); } + + using ::modf; + + inline float + modf(float __x, float* __iptr) + { return __builtin_modff(__x, __iptr); } + + inline long double + modf(long double __x, long double* __iptr) + { return __builtin_modfl(__x, __iptr); } + + template + inline _Tp + __pow_helper(_Tp __x, int __n) + { + return __n < 0 + ? _Tp(1)/__cmath_power(__x, -__n) + : __cmath_power(__x, __n); + } + + using ::pow; + + inline float + pow(float __x, float __y) + { return __builtin_powf(__x, __y); } + + inline long double + pow(long double __x, long double __y) + { return __builtin_powl(__x, __y); } + + inline double + pow(double __x, int __i) + { return __pow_helper(__x, __i); } + + inline float + pow(float __x, int __n) + { return __pow_helper(__x, __n); } + + inline long double + pow(long double __x, int __n) + { return __pow_helper(__x, __n); } + + using ::sin; + + inline float + sin(float __x) + { return __builtin_sinf(__x); } + + inline long double + sin(long double __x) + { return __builtin_sinl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + sin(_Tp __x) + { return __builtin_sin(__x); } + + using ::sinh; + + inline float + sinh(float __x) + { return __builtin_sinhf(__x); } + + inline long double + sinh(long double __x) + { return __builtin_sinhl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + sinh(_Tp __x) + { return __builtin_sinh(__x); } + + using ::sqrt; + + inline float + sqrt(float __x) + { return __builtin_sqrtf(__x); } + + inline long double + sqrt(long double __x) + { return __builtin_sqrtl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + sqrt(_Tp __x) + { return __builtin_sqrt(__x); } + + using ::tan; + + inline float + tan(float __x) + { return __builtin_tanf(__x); } + + inline long double + tan(long double __x) + { return __builtin_tanl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + tan(_Tp __x) + { return __builtin_tan(__x); } + + using ::tanh; + + inline float + tanh(float __x) + { return __builtin_tanhf(__x); } + + inline long double + tanh(long double __x) + { return __builtin_tanhl(__x); } + + template + inline typename __enable_if::_M_type>::_M_type + tanh(_Tp __x) + { return __builtin_tanh(__x); } +} + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +// These are possible macros imported from C99-land. For strict +// conformance, remove possible C99-injected names from the global +// namespace, and sequester them in the __gnu_cxx extension namespace. +namespace __gnu_cxx +{ + template + int + __capture_fpclassify(_Tp __f) { return fpclassify(__f); } + + template + int + __capture_isfinite(_Tp __f) { return isfinite(__f); } + + template + int + __capture_isinf(_Tp __f) { return isinf(__f); } + + template + int + __capture_isnan(_Tp __f) { return isnan(__f); } + + template + int + __capture_isnormal(_Tp __f) { return isnormal(__f); } + + template + int + __capture_signbit(_Tp __f) { return signbit(__f); } + + template + int + __capture_isgreater(_Tp __f1, _Tp __f2) + { return isgreater(__f1, __f2); } + + template + int + __capture_isgreaterequal(_Tp __f1, _Tp __f2) + { return isgreaterequal(__f1, __f2); } + + template + int + __capture_isless(_Tp __f1, _Tp __f2) { return isless(__f1, __f2); } + + template + int + __capture_islessequal(_Tp __f1, _Tp __f2) + { return islessequal(__f1, __f2); } + + template + int + __capture_islessgreater(_Tp __f1, _Tp __f2) + { return islessgreater(__f1, __f2); } + + template + int + __capture_isunordered(_Tp __f1, _Tp __f2) + { return isunordered(__f1, __f2); } +} + +// Only undefine the C99 FP macros, if actually captured for namespace movement +#undef fpclassify +#undef isfinite +#undef isinf +#undef isnan +#undef isnormal +#undef signbit +#undef isgreater +#undef isgreaterequal +#undef isless +#undef islessequal +#undef islessgreater +#undef isunordered +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ +#endif + +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +namespace __gnu_cxx +{ + template + int + fpclassify(_Tp __f) { return __capture_fpclassify(__f); } + + template + int + isfinite(_Tp __f) { return __capture_isfinite(__f); } + + template + int + isinf(_Tp __f) { return __capture_isinf(__f); } + + template + int + isnan(_Tp __f) { return __capture_isnan(__f); } + + template + int + isnormal(_Tp __f) { return __capture_isnormal(__f); } + + template + int + signbit(_Tp __f) { return __capture_signbit(__f); } + + template + int + isgreater(_Tp __f1, _Tp __f2) { return __capture_isgreater(__f1, __f2); } + + template + int + isgreaterequal(_Tp __f1, _Tp __f2) + { return __capture_isgreaterequal(__f1, __f2); } + + template + int + isless(_Tp __f1, _Tp __f2) { return __capture_isless(__f1, __f2); } + + template + int + islessequal(_Tp __f1, _Tp __f2) + { return __capture_islessequal(__f1, __f2); } + + template + int + islessgreater(_Tp __f1, _Tp __f2) + { return __capture_islessgreater(__f1, __f2); } + + template + int + isunordered(_Tp __f1, _Tp __f2) + { return __capture_isunordered(__f1, __f2); } +} + +namespace std +{ + using __gnu_cxx::fpclassify; + using __gnu_cxx::isfinite; + using __gnu_cxx::isinf; + using __gnu_cxx::isnan; + using __gnu_cxx::isnormal; + using __gnu_cxx::signbit; + using __gnu_cxx::isgreater; + using __gnu_cxx::isgreaterequal; + using __gnu_cxx::isless; + using __gnu_cxx::islessequal; + using __gnu_cxx::islessgreater; + using __gnu_cxx::isunordered; +} +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ +#endif + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/complex b/reactos/tools/ppc-build/core-headers/g++-v3/complex new file mode 100644 index 00000000000..244ed284f69 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/complex @@ -0,0 +1,1226 @@ +// The template and inlines for the -*- C++ -*- complex number classes. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 26.2 Complex Numbers +// Note: this is not a conforming implementation. +// Initially implemented by Ulrich Drepper +// Improved by Gabriel Dos Reis +// + +/** @file complex + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_COMPLEX +#define _GLIBCXX_COMPLEX 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +namespace std +{ + // Forward declarations + template class complex; + template<> class complex; + template<> class complex; + template<> class complex; + + /// Return magnitude of @a z. + template _Tp abs(const complex<_Tp>&); + /// Return phase angle of @a z. + template _Tp arg(const complex<_Tp>&); + /// Return @a z magnitude squared. + template _Tp norm(const complex<_Tp>&); + + /// Return complex conjugate of @a z. + template complex<_Tp> conj(const complex<_Tp>&); + /// Return complex with magnitude @a rho and angle @a theta. + template complex<_Tp> polar(const _Tp&, const _Tp& = 0); + + // Transcendentals: + /// Return complex cosine of @a z. + template complex<_Tp> cos(const complex<_Tp>&); + /// Return complex hyperbolic cosine of @a z. + template complex<_Tp> cosh(const complex<_Tp>&); + /// Return complex base e exponential of @a z. + template complex<_Tp> exp(const complex<_Tp>&); + /// Return complex natural logarithm of @a z. + template complex<_Tp> log(const complex<_Tp>&); + /// Return complex base 10 logarithm of @a z. + template complex<_Tp> log10(const complex<_Tp>&); + /// Return complex cosine of @a z. + template complex<_Tp> pow(const complex<_Tp>&, int); + /// Return @a x to the @a y'th power. + template complex<_Tp> pow(const complex<_Tp>&, const _Tp&); + /// Return @a x to the @a y'th power. + template complex<_Tp> pow(const complex<_Tp>&, + const complex<_Tp>&); + /// Return @a x to the @a y'th power. + template complex<_Tp> pow(const _Tp&, const complex<_Tp>&); + /// Return complex sine of @a z. + template complex<_Tp> sin(const complex<_Tp>&); + /// Return complex hyperbolic sine of @a z. + template complex<_Tp> sinh(const complex<_Tp>&); + /// Return complex square root of @a z. + template complex<_Tp> sqrt(const complex<_Tp>&); + /// Return complex tangent of @a z. + template complex<_Tp> tan(const complex<_Tp>&); + /// Return complex hyperbolic tangent of @a z. + template complex<_Tp> tanh(const complex<_Tp>&); + //@} + + + // 26.2.2 Primary template class complex + /** + * Template to represent complex numbers. + * + * Specializations for float, double, and long double are part of the + * library. Results with any other type are not guaranteed. + * + * @param Tp Type of real and imaginary values. + */ + template + class complex + { + public: + /// Value typedef. + typedef _Tp value_type; + + /// Default constructor. First parameter is x, second parameter is y. + /// Unspecified parameters default to 0. + complex(const _Tp& = _Tp(), const _Tp & = _Tp()); + + // Lets the compiler synthesize the copy constructor + // complex (const complex<_Tp>&); + /// Copy constructor. + template + complex(const complex<_Up>&); + + /// Return real part of complex number. + _Tp& real(); + /// Return real part of complex number. + const _Tp& real() const; + /// Return imaginary part of complex number. + _Tp& imag(); + /// Return imaginary part of complex number. + const _Tp& imag() const; + + /// Assign this complex number to scalar @a t. + complex<_Tp>& operator=(const _Tp&); + /// Add @a t to this complex number. + complex<_Tp>& operator+=(const _Tp&); + /// Subtract @a t from this complex number. + complex<_Tp>& operator-=(const _Tp&); + /// Multiply this complex number by @a t. + complex<_Tp>& operator*=(const _Tp&); + /// Divide this complex number by @a t. + complex<_Tp>& operator/=(const _Tp&); + + // Lets the compiler synthesize the + // copy and assignment operator + // complex<_Tp>& operator= (const complex<_Tp>&); + /// Assign this complex number to complex @a z. + template + complex<_Tp>& operator=(const complex<_Up>&); + /// Add @a z to this complex number. + template + complex<_Tp>& operator+=(const complex<_Up>&); + /// Subtract @a z from this complex number. + template + complex<_Tp>& operator-=(const complex<_Up>&); + /// Multiply this complex number by @a z. + template + complex<_Tp>& operator*=(const complex<_Up>&); + /// Divide this complex number by @a z. + template + complex<_Tp>& operator/=(const complex<_Up>&); + + private: + _Tp _M_real; + _Tp _M_imag; + }; + + template + inline _Tp& + complex<_Tp>::real() { return _M_real; } + + template + inline const _Tp& + complex<_Tp>::real() const { return _M_real; } + + template + inline _Tp& + complex<_Tp>::imag() { return _M_imag; } + + template + inline const _Tp& + complex<_Tp>::imag() const { return _M_imag; } + + template + inline + complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) + : _M_real(__r), _M_imag(__i) { } + + template + template + inline + complex<_Tp>::complex(const complex<_Up>& __z) + : _M_real(__z.real()), _M_imag(__z.imag()) { } + + template + complex<_Tp>& + complex<_Tp>::operator=(const _Tp& __t) + { + _M_real = __t; + _M_imag = _Tp(); + return *this; + } + + // 26.2.5/1 + template + inline complex<_Tp>& + complex<_Tp>::operator+=(const _Tp& __t) + { + _M_real += __t; + return *this; + } + + // 26.2.5/3 + template + inline complex<_Tp>& + complex<_Tp>::operator-=(const _Tp& __t) + { + _M_real -= __t; + return *this; + } + + // 26.2.5/5 + template + complex<_Tp>& + complex<_Tp>::operator*=(const _Tp& __t) + { + _M_real *= __t; + _M_imag *= __t; + return *this; + } + + // 26.2.5/7 + template + complex<_Tp>& + complex<_Tp>::operator/=(const _Tp& __t) + { + _M_real /= __t; + _M_imag /= __t; + return *this; + } + + template + template + complex<_Tp>& + complex<_Tp>::operator=(const complex<_Up>& __z) + { + _M_real = __z.real(); + _M_imag = __z.imag(); + return *this; + } + + // 26.2.5/9 + template + template + complex<_Tp>& + complex<_Tp>::operator+=(const complex<_Up>& __z) + { + _M_real += __z.real(); + _M_imag += __z.imag(); + return *this; + } + + // 26.2.5/11 + template + template + complex<_Tp>& + complex<_Tp>::operator-=(const complex<_Up>& __z) + { + _M_real -= __z.real(); + _M_imag -= __z.imag(); + return *this; + } + + // 26.2.5/13 + // XXX: This is a grammar school implementation. + template + template + complex<_Tp>& + complex<_Tp>::operator*=(const complex<_Up>& __z) + { + const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); + _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); + _M_real = __r; + return *this; + } + + // 26.2.5/15 + // XXX: This is a grammar school implementation. + template + template + complex<_Tp>& + complex<_Tp>::operator/=(const complex<_Up>& __z) + { + const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); + const _Tp __n = std::norm(__z); + _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; + _M_real = __r / __n; + return *this; + } + + // Operators: + //@{ + /// Return new complex value @a x plus @a y. + template + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r += __y; + return __r; + } + + template + inline complex<_Tp> + operator+(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r.real() += __y; + return __r; + } + + template + inline complex<_Tp> + operator+(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __y; + __r.real() += __x; + return __r; + } + //@} + + //@{ + /// Return new complex value @a x minus @a y. + template + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r -= __y; + return __r; + } + + template + inline complex<_Tp> + operator-(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r.real() -= __y; + return __r; + } + + template + inline complex<_Tp> + operator-(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r(__x, -__y.imag()); + __r.real() -= __y.real(); + return __r; + } + //@} + + //@{ + /// Return new complex value @a x times @a y. + template + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } + + template + inline complex<_Tp> + operator*(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } + + template + inline complex<_Tp> + operator*(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __y; + __r *= __x; + return __r; + } + //@} + + //@{ + /// Return new complex value @a x divided by @a y. + template + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + + template + inline complex<_Tp> + operator/(const complex<_Tp>& __x, const _Tp& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + + template + inline complex<_Tp> + operator/(const _Tp& __x, const complex<_Tp>& __y) + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + //@} + + /// Return @a x. + template + inline complex<_Tp> + operator+(const complex<_Tp>& __x) + { return __x; } + + /// Return complex negation of @a x. + template + inline complex<_Tp> + operator-(const complex<_Tp>& __x) + { return complex<_Tp>(-__x.real(), -__x.imag()); } + + //@{ + /// Return true if @a x is equal to @a y. + template + inline bool + operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() == __y.real() && __x.imag() == __y.imag(); } + + template + inline bool + operator==(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() == __y && __x.imag() == _Tp(); } + + template + inline bool + operator==(const _Tp& __x, const complex<_Tp>& __y) + { return __x == __y.real() && _Tp() == __y.imag(); } + //@} + + //@{ + /// Return false if @a x is equal to @a y. + template + inline bool + operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) + { return __x.real() != __y.real() || __x.imag() != __y.imag(); } + + template + inline bool + operator!=(const complex<_Tp>& __x, const _Tp& __y) + { return __x.real() != __y || __x.imag() != _Tp(); } + + template + inline bool + operator!=(const _Tp& __x, const complex<_Tp>& __y) + { return __x != __y.real() || _Tp() != __y.imag(); } + //@} + + /// Extraction operator for complex values. + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) + { + _Tp __re_x, __im_x; + _CharT __ch; + __is >> __ch; + if (__ch == '(') + { + __is >> __re_x >> __ch; + if (__ch == ',') + { + __is >> __im_x >> __ch; + if (__ch == ')') + __x = complex<_Tp>(__re_x, __im_x); + else + __is.setstate(ios_base::failbit); + } + else if (__ch == ')') + __x = __re_x; + else + __is.setstate(ios_base::failbit); + } + else + { + __is.putback(__ch); + __is >> __re_x; + __x = __re_x; + } + return __is; + } + + /// Insertion operator for complex values. + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) + { + basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << '(' << __x.real() << ',' << __x.imag() << ')'; + return __os << __s.str(); + } + + // Values + template + inline _Tp& + real(complex<_Tp>& __z) + { return __z.real(); } + + template + inline const _Tp& + real(const complex<_Tp>& __z) + { return __z.real(); } + + template + inline _Tp& + imag(complex<_Tp>& __z) + { return __z.imag(); } + + template + inline const _Tp& + imag(const complex<_Tp>& __z) + { return __z.imag(); } + + template + inline _Tp + abs(const complex<_Tp>& __z) + { + _Tp __x = __z.real(); + _Tp __y = __z.imag(); + const _Tp __s = std::max(abs(__x), abs(__y)); + if (__s == _Tp()) // well ... + return __s; + __x /= __s; + __y /= __s; + return __s * sqrt(__x * __x + __y * __y); + } + + template + inline _Tp + arg(const complex<_Tp>& __z) + { return atan2(__z.imag(), __z.real()); } + + // 26.2.7/5: norm(__z) returns the squared magintude of __z. + // As defined, norm() is -not- a norm is the common mathematical + // sens used in numerics. The helper class _Norm_helper<> tries to + // distinguish between builtin floating point and the rest, so as + // to deliver an answer as close as possible to the real value. + template + struct _Norm_helper + { + template + static inline _Tp _S_do_it(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return __x * __x + __y * __y; + } + }; + + template<> + struct _Norm_helper + { + template + static inline _Tp _S_do_it(const complex<_Tp>& __z) + { + _Tp __res = std::abs(__z); + return __res * __res; + } + }; + + template + inline _Tp + norm(const complex<_Tp>& __z) + { + return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); + } + + template + inline complex<_Tp> + polar(const _Tp& __rho, const _Tp& __theta) + { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } + + template + inline complex<_Tp> + conj(const complex<_Tp>& __z) + { return complex<_Tp>(__z.real(), -__z.imag()); } + + // Transcendentals + template + inline complex<_Tp> + cos(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); + } + + template + inline complex<_Tp> + cosh(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); + } + + template + inline complex<_Tp> + exp(const complex<_Tp>& __z) + { return std::polar(exp(__z.real()), __z.imag()); } + + template + inline complex<_Tp> + log(const complex<_Tp>& __z) + { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } + + template + inline complex<_Tp> + log10(const complex<_Tp>& __z) + { return std::log(__z) / log(_Tp(10.0)); } + + template + inline complex<_Tp> + sin(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); + } + + template + inline complex<_Tp> + sinh(const complex<_Tp>& __z) + { + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); + } + + template + complex<_Tp> + sqrt(const complex<_Tp>& __z) + { + _Tp __x = __z.real(); + _Tp __y = __z.imag(); + + if (__x == _Tp()) + { + _Tp __t = sqrt(abs(__y) / 2); + return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); + } + else + { + _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); + _Tp __u = __t / 2; + return __x > _Tp() + ? complex<_Tp>(__u, __y / __t) + : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); + } + } + + template + inline complex<_Tp> + tan(const complex<_Tp>& __z) + { + return std::sin(__z) / std::cos(__z); + } + + template + inline complex<_Tp> + tanh(const complex<_Tp>& __z) + { + return std::sinh(__z) / std::cosh(__z); + } + + template + inline complex<_Tp> + pow(const complex<_Tp>& __z, int __n) + { + return std::__pow_helper(__z, __n); + } + + template + complex<_Tp> + pow(const complex<_Tp>& __x, const _Tp& __y) + { + if (__x.imag() == _Tp() && __x.real() > _Tp()) + return pow(__x.real(), __y); + + complex<_Tp> __t = std::log(__x); + return std::polar(exp(__y * __t.real()), __y * __t.imag()); + } + + template + inline complex<_Tp> + pow(const complex<_Tp>& __x, const complex<_Tp>& __y) + { + return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); + } + + template + inline complex<_Tp> + pow(const _Tp& __x, const complex<_Tp>& __y) + { + return __x > _Tp() ? std::polar(pow(__x, __y.real()), + __y.imag() * log(__x)) + : std::pow(complex<_Tp>(__x, _Tp()), __y); + } + + // 26.2.3 complex specializations + // complex specialization + template<> class complex + { + public: + typedef float value_type; + + complex(float = 0.0f, float = 0.0f); + + explicit complex(const complex&); + explicit complex(const complex&); + + float& real(); + const float& real() const; + float& imag(); + const float& imag() const; + + complex& operator=(float); + complex& operator+=(float); + complex& operator-=(float); + complex& operator*=(float); + complex& operator/=(float); + + // Let's the compiler synthetize the copy and assignment + // operator. It always does a pretty good job. + // complex& operator= (const complex&); + template + complex&operator=(const complex<_Tp>&); + template + complex& operator+=(const complex<_Tp>&); + template + complex& operator-=(const complex<_Tp>&); + template + complex& operator*=(const complex<_Tp>&); + template + complex&operator/=(const complex<_Tp>&); + + private: + typedef __complex__ float _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex; + friend class complex; + }; + + inline float& + complex::real() + { return __real__ _M_value; } + + inline const float& + complex::real() const + { return __real__ _M_value; } + + inline float& + complex::imag() + { return __imag__ _M_value; } + + inline const float& + complex::imag() const + { return __imag__ _M_value; } + + inline + complex::complex(float r, float i) + { + __real__ _M_value = r; + __imag__ _M_value = i; + } + + inline complex& + complex::operator=(float __f) + { + __real__ _M_value = __f; + __imag__ _M_value = 0.0f; + return *this; + } + + inline complex& + complex::operator+=(float __f) + { + __real__ _M_value += __f; + return *this; + } + + inline complex& + complex::operator-=(float __f) + { + __real__ _M_value -= __f; + return *this; + } + + inline complex& + complex::operator*=(float __f) + { + _M_value *= __f; + return *this; + } + + inline complex& + complex::operator/=(float __f) + { + _M_value /= __f; + return *this; + } + + template + inline complex& + complex::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template + inline complex& + complex::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template + inline complex& + complex::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template + inline complex& + complex::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template + inline complex& + complex::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // 26.2.3 complex specializations + // complex specialization + template<> class complex + { + public: + typedef double value_type; + + complex(double = 0.0, double = 0.0); + + complex(const complex&); + explicit complex(const complex&); + + double& real(); + const double& real() const; + double& imag(); + const double& imag() const; + + complex& operator=(double); + complex& operator+=(double); + complex& operator-=(double); + complex& operator*=(double); + complex& operator/=(double); + + // The compiler will synthetize this, efficiently. + // complex& operator= (const complex&); + template + complex& operator=(const complex<_Tp>&); + template + complex& operator+=(const complex<_Tp>&); + template + complex& operator-=(const complex<_Tp>&); + template + complex& operator*=(const complex<_Tp>&); + template + complex& operator/=(const complex<_Tp>&); + + private: + typedef __complex__ double _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex; + friend class complex; + }; + + inline double& + complex::real() + { return __real__ _M_value; } + + inline const double& + complex::real() const + { return __real__ _M_value; } + + inline double& + complex::imag() + { return __imag__ _M_value; } + + inline const double& + complex::imag() const + { return __imag__ _M_value; } + + inline + complex::complex(double __r, double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline complex& + complex::operator=(double __d) + { + __real__ _M_value = __d; + __imag__ _M_value = 0.0; + return *this; + } + + inline complex& + complex::operator+=(double __d) + { + __real__ _M_value += __d; + return *this; + } + + inline complex& + complex::operator-=(double __d) + { + __real__ _M_value -= __d; + return *this; + } + + inline complex& + complex::operator*=(double __d) + { + _M_value *= __d; + return *this; + } + + inline complex& + complex::operator/=(double __d) + { + _M_value /= __d; + return *this; + } + + template + inline complex& + complex::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template + inline complex& + complex::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template + inline complex& + complex::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template + inline complex& + complex::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template + inline complex& + complex::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // 26.2.3 complex specializations + // complex specialization + template<> class complex + { + public: + typedef long double value_type; + + complex(long double = 0.0L, long double = 0.0L); + + complex(const complex&); + complex(const complex&); + + long double& real(); + const long double& real() const; + long double& imag(); + const long double& imag() const; + + complex& operator= (long double); + complex& operator+= (long double); + complex& operator-= (long double); + complex& operator*= (long double); + complex& operator/= (long double); + + // The compiler knows how to do this efficiently + // complex& operator= (const complex&); + template + complex& operator=(const complex<_Tp>&); + template + complex& operator+=(const complex<_Tp>&); + template + complex& operator-=(const complex<_Tp>&); + template + complex& operator*=(const complex<_Tp>&); + template + complex& operator/=(const complex<_Tp>&); + + private: + typedef __complex__ long double _ComplexT; + _ComplexT _M_value; + + complex(_ComplexT __z) : _M_value(__z) { } + + friend class complex; + friend class complex; + }; + + inline + complex::complex(long double __r, long double __i) + { + __real__ _M_value = __r; + __imag__ _M_value = __i; + } + + inline long double& + complex::real() + { return __real__ _M_value; } + + inline const long double& + complex::real() const + { return __real__ _M_value; } + + inline long double& + complex::imag() + { return __imag__ _M_value; } + + inline const long double& + complex::imag() const + { return __imag__ _M_value; } + + inline complex& + complex::operator=(long double __r) + { + __real__ _M_value = __r; + __imag__ _M_value = 0.0L; + return *this; + } + + inline complex& + complex::operator+=(long double __r) + { + __real__ _M_value += __r; + return *this; + } + + inline complex& + complex::operator-=(long double __r) + { + __real__ _M_value -= __r; + return *this; + } + + inline complex& + complex::operator*=(long double __r) + { + _M_value *= __r; + return *this; + } + + inline complex& + complex::operator/=(long double __r) + { + _M_value /= __r; + return *this; + } + + template + inline complex& + complex::operator=(const complex<_Tp>& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + return *this; + } + + template + inline complex& + complex::operator+=(const complex<_Tp>& __z) + { + __real__ _M_value += __z.real(); + __imag__ _M_value += __z.imag(); + return *this; + } + + template + inline complex& + complex::operator-=(const complex<_Tp>& __z) + { + __real__ _M_value -= __z.real(); + __imag__ _M_value -= __z.imag(); + return *this; + } + + template + inline complex& + complex::operator*=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value *= __t; + return *this; + } + + template + inline complex& + complex::operator/=(const complex<_Tp>& __z) + { + _ComplexT __t; + __real__ __t = __z.real(); + __imag__ __t = __z.imag(); + _M_value /= __t; + return *this; + } + + // These bits have to be at the end of this file, so that the + // specializations have all been defined. + // ??? No, they have to be there because of compiler limitation at + // inlining. It suffices that class specializations be defined. + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + { + __real__ _M_value = __z.real(); + __imag__ _M_value = __z.imag(); + } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } + + inline + complex::complex(const complex& __z) + : _M_value(_ComplexT(__z._M_value)) { } +} // namespace std + +#endif /* _GLIBCXX_COMPLEX */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/csetjmp b/reactos/tools/ppc-build/core-headers/g++-v3/csetjmp new file mode 100644 index 00000000000..d5fe073f0fc --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/csetjmp @@ -0,0 +1,65 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file csetjmp + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c setjmp.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSETJMP +#define _GLIBCXX_CSETJMP 1 + +#pragma GCC system_header + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef longjmp + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef setjmp +#define setjmp(env) setjmp (env) +#endif + +namespace std +{ + using ::jmp_buf; + using ::longjmp; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/csignal b/reactos/tools/ppc-build/core-headers/g++-v3/csignal new file mode 100644 index 00000000000..5734cf6d29a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/csignal @@ -0,0 +1,61 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file csignal + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c signal.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSIGNAL +#define _GLIBCXX_CSIGNAL 1 + +#pragma GCC system_header + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef raise + +namespace std +{ + using ::sig_atomic_t; + using ::signal; + using ::raise; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cstdarg b/reactos/tools/ppc-build/core-headers/g++-v3/cstdarg new file mode 100644 index 00000000000..ca362e4b412 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cstdarg @@ -0,0 +1,60 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file cstdarg + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdarg.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDARG +#define _GLIBCXX_CSTDARG 1 + +#pragma GCC system_header + +#include + +// Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 +#ifndef va_end +#define va_end(ap) va_end (ap) +#endif + +namespace std +{ + using ::va_list; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cstddef b/reactos/tools/ppc-build/core-headers/g++-v3/cstddef new file mode 100644 index 00000000000..4fa82c6aa9b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cstddef @@ -0,0 +1,56 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 18.1 Types +// + +/** @file cstddef + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stddef.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDDEF +#define _GLIBCXX_CSTDDEF 1 + +#pragma GCC system_header + +#include + +namespace std +{ + using ::ptrdiff_t; + using ::size_t; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cstdio b/reactos/tools/ppc-build/core-headers/g++-v3/cstdio new file mode 100644 index 00000000000..f31e58e6f24 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cstdio @@ -0,0 +1,185 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8.2 C Library files +// + +/** @file cstdio + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdio.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDIO +#define _GLIBCXX_CSTDIO 1 + +#pragma GCC system_header + +#include +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef clearerr +#undef fclose +#undef feof +#undef ferror +#undef fflush +#undef fgetc +#undef fgetpos +#undef fgets +#undef fopen +#undef fprintf +#undef fputc +#undef fputs +#undef fread +#undef freopen +#undef fscanf +#undef fseek +#undef fsetpos +#undef ftell +#undef fwrite +#undef getc +#undef getchar +#undef gets +#undef perror +#undef printf +#undef putc +#undef putchar +#undef puts +#undef remove +#undef rename +#undef rewind +#undef scanf +#undef setbuf +#undef setvbuf +#undef sprintf +#undef sscanf +#undef tmpfile +#undef tmpnam +#undef ungetc +#undef vfprintf +#undef vprintf +#undef vsprintf + +namespace std +{ + using ::FILE; + using ::fpos_t; + + using ::clearerr; + using ::fclose; + using ::feof; + using ::ferror; + using ::fflush; + using ::fgetc; + using ::fgetpos; + using ::fgets; + using ::fopen; + using ::fprintf; + using ::fputc; + using ::fputs; + using ::fread; + using ::freopen; + using ::fscanf; + using ::fseek; + using ::fsetpos; + using ::ftell; + using ::fwrite; + using ::getc; + using ::getchar; + using ::gets; + using ::perror; + using ::printf; + using ::putc; + using ::putchar; + using ::puts; + using ::remove; + using ::rename; + using ::rewind; + using ::scanf; + using ::setbuf; + using ::setvbuf; + using ::sprintf; + using ::sscanf; + using ::tmpfile; + using ::tmpnam; + using ::ungetc; + using ::vfprintf; + using ::vprintf; + using ::vsprintf; +} + +#if _GLIBCXX_USE_C99 + +#undef snprintf +#undef vfscanf +#undef vscanf +#undef vsnprintf +#undef vsscanf + +namespace __gnu_cxx +{ +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" int + (snprintf)(char * restrict, size_t, const char * restrict, ...); + extern "C" int + (vfscanf)(FILE * restrict, const char * restrict, __gnuc_va_list); + extern "C" int (vscanf)(const char * restrict, __gnuc_va_list); + extern "C" int + (vsnprintf)(char * restrict, size_t, const char * restrict, __gnuc_va_list); + extern "C" int + (vsscanf)(const char * restrict, const char * restrict, __gnuc_va_list); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::snprintf; + using ::vfscanf; + using ::vscanf; + using ::vsnprintf; + using ::vsscanf; +#endif +} + +namespace std +{ + using __gnu_cxx::snprintf; + using __gnu_cxx::vfscanf; + using __gnu_cxx::vscanf; + using __gnu_cxx::vsnprintf; + using __gnu_cxx::vsscanf; +} +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cstdlib b/reactos/tools/ppc-build/core-headers/g++-v3/cstdlib new file mode 100644 index 00000000000..d2d6e37064b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cstdlib @@ -0,0 +1,204 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file cstdlib + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c stdlib.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTDLIB +#define _GLIBCXX_CSTDLIB 1 + +#pragma GCC system_header + +#include +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef abort +#undef abs +#undef atexit +#undef atof +#undef atoi +#undef atol +#undef bsearch +#undef calloc +#undef div +#undef exit +#undef free +#undef getenv +#undef labs +#undef ldiv +#undef malloc +#undef mblen +#undef mbstowcs +#undef mbtowc +#undef qsort +#undef rand +#undef realloc +#undef srand +#undef strtod +#undef strtol +#undef strtoul +#undef system +#undef wcstombs +#undef wctomb + +namespace std +{ + using ::div_t; + using ::ldiv_t; + + using ::abort; + using ::abs; + using ::atexit; + using ::atof; + using ::atoi; + using ::atol; + using ::bsearch; + using ::calloc; + using ::div; + using ::exit; + using ::free; + using ::getenv; + using ::labs; + using ::ldiv; + using ::malloc; +#ifdef _GLIBCXX_HAVE_MBSTATE_T + using ::mblen; + using ::mbstowcs; + using ::mbtowc; +#endif // _GLIBCXX_HAVE_MBSTATE_T + using ::qsort; + using ::rand; + using ::realloc; + using ::srand; + using ::strtod; + using ::strtol; + using ::strtoul; + using ::system; +#ifdef _GLIBCXX_USE_WCHAR_T + using ::wcstombs; + using ::wctomb; +#endif // _GLIBCXX_USE_WCHAR_T + + inline long + abs(long __i) { return labs(__i); } + + inline ldiv_t + div(long __i, long __j) { return ldiv(__i, __j); } +} + +#if _GLIBCXX_USE_C99 + +#undef _Exit +#undef llabs +#undef lldiv +#undef atoll +#undef strtoll +#undef strtoull +#undef strtof +#undef strtold + +namespace __gnu_cxx +{ +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::lldiv_t; +#endif +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" void (_Exit)(int); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::_Exit; +#endif + + inline long long + abs(long long __x) { return __x >= 0 ? __x : -__x; } + + inline long long + llabs(long long __x) { return __x >= 0 ? __x : -__x; } + +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + inline lldiv_t + div(long long __n, long long __d) + { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } + + inline lldiv_t + lldiv(long long __n, long long __d) + { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } +#endif + +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + extern "C" long long int (atoll)(const char *); + extern "C" long long int + (strtoll)(const char * restrict, char ** restrict, int); + extern "C" unsigned long long int + (strtoull)(const char * restrict, char ** restrict, int); +#endif +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::atoll; + using ::strtoll; + using ::strtoull; +#endif + using ::strtof; + using ::strtold; +} + +namespace std +{ +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using __gnu_cxx::lldiv_t; +#endif + using __gnu_cxx::_Exit; + using __gnu_cxx::abs; + using __gnu_cxx::llabs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using __gnu_cxx::div; + using __gnu_cxx::lldiv; +#endif + using __gnu_cxx::atoll; + using __gnu_cxx::strtof; + using __gnu_cxx::strtoll; + using __gnu_cxx::strtoull; + using __gnu_cxx::strtold; +} +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cstring b/reactos/tools/ppc-build/core-headers/g++-v3/cstring new file mode 100644 index 00000000000..dad40c290ad --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cstring @@ -0,0 +1,128 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.4.6 C library +// + +/** @file cstring + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c string.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 1 + +#pragma GCC system_header + +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef memcpy +#undef memmove +#undef strcpy +#undef strncpy +#undef strcat +#undef strncat +#undef memcmp +#undef strcmp +#undef strcoll +#undef strncmp +#undef strxfrm +#undef memchr +#undef strchr +#undef strcspn +#undef strpbrk +#undef strrchr +#undef strspn +#undef strstr +#undef strtok +#undef memset +#undef strerror +#undef strlen + +namespace std +{ + using ::memcpy; + using ::memmove; + using ::strcpy; + using ::strncpy; + using ::strcat; + using ::strncat; + using ::memcmp; + using ::strcmp; + using ::strcoll; + using ::strncmp; + using ::strxfrm; + using ::strcspn; + using ::strspn; + using ::strtok; + using ::memset; + using ::strerror; + using ::strlen; + + using ::memchr; + + inline void* + memchr(void* __p, int __c, size_t __n) + { return memchr(const_cast(__p), __c, __n); } + + using ::strchr; + + inline char* + strchr(char* __s1, int __n) + { return __builtin_strchr(const_cast(__s1), __n); } + + using ::strpbrk; + + inline char* + strpbrk(char* __s1, const char* __s2) + { return __builtin_strpbrk(const_cast(__s1), __s2); } + + using ::strrchr; + + inline char* + strrchr(char* __s1, int __n) + { return __builtin_strrchr(const_cast(__s1), __n); } + + using ::strstr; + + inline char* + strstr(char* __s1, const char* __s2) + { return __builtin_strstr(const_cast(__s1), __s2); } +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ctime b/reactos/tools/ppc-build/core-headers/g++-v3/ctime new file mode 100644 index 00000000000..fe890dfd580 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ctime @@ -0,0 +1,81 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 20.5 Date and time +// + +/** @file ctime + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c time.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CTIME +#define _GLIBCXX_CTIME 1 + +#pragma GCC system_header + +#include + +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef clock +#undef difftime +#undef mktime +#undef time +#undef asctime +#undef ctime +#undef gmtime +#undef localtime +#undef strftime + +namespace std +{ + using ::clock_t; + using ::time_t; + using ::tm; + + using ::clock; + using ::difftime; + using ::mktime; + using ::time; + using ::asctime; + using ::ctime; + using ::gmtime; + using ::localtime; + using ::strftime; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cwchar b/reactos/tools/ppc-build/core-headers/g++-v3/cwchar new file mode 100644 index 00000000000..f633d8bd1ab --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cwchar @@ -0,0 +1,275 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21.4 +// + +/** @file cwchar + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c wchar.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CWCHAR +#define _GLIBCXX_CWCHAR 1 + +#pragma GCC system_header + +#include +#include +#include + +#if _GLIBCXX_HAVE_WCHAR_H +#include +#endif + +// Need to do a bit of trickery here with mbstate_t as char_traits +// assumes it is in wchar.h, regardless of wchar_t specializations. +#ifndef _GLIBCXX_HAVE_MBSTATE_T +extern "C" +{ + typedef struct + { + int __fill[6]; + } mbstate_t; +} +#endif + +namespace std +{ + using ::mbstate_t; +} + +// Get rid of those macros defined in in lieu of real functions. +#undef btowc +#undef fgetwc +#undef fgetws +#undef fputwc +#undef fputws +#undef fwide +#undef fwprintf +#undef fwscanf +#undef getwc +#undef getwchar +#undef mbrlen +#undef mbrtowc +#undef mbsinit +#undef mbsrtowcs +#undef putwc +#undef putwchar +#undef swprintf +#undef swscanf +#undef ungetwc +#undef vfwprintf +#if _GLIBCXX_HAVE_VFWSCANF +# undef vfwscanf +#endif +#undef vswprintf +#if _GLIBCXX_HAVE_VSWSCANF +# undef vswscanf +#endif +#undef vwprintf +#if _GLIBCXX_HAVE_VWSCANF +# undef vwscanf +#endif +#undef wcrtomb +#undef wcscat +#undef wcschr +#undef wcscmp +#undef wcscoll +#undef wcscpy +#undef wcscspn +#undef wcsftime +#undef wcslen +#undef wcsncat +#undef wcsncmp +#undef wcsncpy +#undef wcspbrk +#undef wcsrchr +#undef wcsrtombs +#undef wcsspn +#undef wcsstr +#undef wcstod +#if _GLIBCXX_HAVE_WCSTOF +# undef wcstof +#endif +#undef wcstok +#undef wcstol +#undef wcstoul +#undef wcsxfrm +#undef wctob +#undef wmemchr +#undef wmemcmp +#undef wmemcpy +#undef wmemmove +#undef wmemset +#undef wprintf +#undef wscanf + +#if _GLIBCXX_USE_WCHAR_T +namespace std +{ + using ::wint_t; + + using ::btowc; + using ::fgetwc; + using ::fgetws; + using ::fputwc; + using ::fputws; + using ::fwide; + using ::fwprintf; + using ::fwscanf; + using ::getwc; + using ::getwchar; + using ::mbrlen; + using ::mbrtowc; + using ::mbsinit; + using ::mbsrtowcs; + using ::putwc; + using ::putwchar; + using ::swprintf; + using ::swscanf; + using ::ungetwc; + using ::vfwprintf; +#if _GLIBCXX_HAVE_VFWSCANF + using ::vfwscanf; +#endif + using ::vswprintf; +#if _GLIBCXX_HAVE_VSWSCANF + using ::vswscanf; +#endif + using ::vwprintf; +#if _GLIBCXX_HAVE_VWSCANF + using ::vwscanf; +#endif + using ::wcrtomb; + using ::wcscat; + using ::wcscmp; + using ::wcscoll; + using ::wcscpy; + using ::wcscspn; +#if _GLIBCXX_HAVE_WCSFTIME + using ::wcsftime; +#endif + using ::wcslen; + using ::wcsncat; + using ::wcsncmp; + using ::wcsncpy; + using ::wcsrtombs; + using ::wcsspn; + using ::wcstod; +#if _GLIBCXX_HAVE_WCSTOF + using ::wcstof; +#endif + using ::wcstok; + using ::wcstol; + using ::wcstoul; + using ::wcsxfrm; + using ::wctob; + using ::wmemcmp; + using ::wmemcpy; + using ::wmemmove; + using ::wmemset; + using ::wprintf; + using ::wscanf; + + using ::wcschr; + + inline wchar_t* + wcschr(wchar_t* __p, wchar_t __c) + { return wcschr(const_cast(__p), __c); } + + using ::wcspbrk; + + inline wchar_t* + wcspbrk(wchar_t* __s1, wchar_t* __s2) + { return wcspbrk(const_cast(__s1), __s2); } + + using ::wcsrchr; + + inline wchar_t* + wcsrchr(wchar_t* __p, wchar_t __c) + { return wcsrchr(const_cast(__p), __c); } + + using ::wcsstr; + + inline wchar_t* + wcsstr(wchar_t* __s1, const wchar_t* __s2) + { return wcsstr(const_cast(__s1), __s2); } + + using ::wmemchr; + + inline wchar_t* + wmemchr(wchar_t* __p, wchar_t __c, size_t __n) + { return wmemchr(const_cast(__p), __c, __n); } +} + +#if _GLIBCXX_USE_C99 + +#undef wcstold +#undef wcstoll +#undef wcstoull + +namespace __gnu_cxx +{ +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC + extern "C" long double + (wcstold)(const wchar_t * restrict, wchar_t ** restrict); +#endif +#if !_GLIBCXX_USE_C99_DYNAMIC + using ::wcstold; +#endif +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + extern "C" long long int + (wcstoll)(const wchar_t * restrict, wchar_t ** restrict, int); + extern "C" unsigned long long int + (wcstoull)(const wchar_t * restrict, wchar_t ** restrict, int); +#endif +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + using ::wcstoll; + using ::wcstoull; +#endif +} + +namespace std +{ + using __gnu_cxx::wcstold; + using __gnu_cxx::wcstoll; + using __gnu_cxx::wcstoull; +} +#endif + +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/cwctype b/reactos/tools/ppc-build/core-headers/g++-v3/cwctype new file mode 100644 index 00000000000..970c53a8f3d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/cwctype @@ -0,0 +1,110 @@ +// -*- C++ -*- forwarding header. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: +// + +/** @file cwctype + * This is a Standard C++ Library file. You should @c #include this file + * in your programs, rather than any of the "*.h" implementation files. + * + * This is the C++ version of the Standard C Library header @c wctype.h, + * and its contents are (mostly) the same as that header, but are all + * contained in the namespace @c std. + */ + +#ifndef _GLIBCXX_CWCTYPE +#define _GLIBCXX_CWCTYPE 1 + +#pragma GCC system_header + +#include + +#if _GLIBCXX_HAVE_WCTYPE_H +#include +#endif + +// Get rid of those macros defined in in lieu of real functions. +#undef iswalnum +#undef iswalpha +#if _GLIBCXX_HAVE_ISWBLANK +# undef iswblank +#endif +#undef iswcntrl +#undef iswdigit +#undef iswgraph +#undef iswlower +#undef iswprint +#undef iswprint +#undef iswpunct +#undef iswspace +#undef iswupper +#undef iswxdigit +#undef iswctype +#undef towlower +#undef towupper +#undef towctrans +#undef wctrans +#undef wctype + +#if _GLIBCXX_USE_WCHAR_T +namespace std +{ + using ::wint_t; // cwchar + + using ::wctype_t; + using ::wctrans_t; + + using ::iswalnum; + using ::iswalpha; +#if _GLIBCXX_HAVE_ISWBLANK + using ::iswblank; +#endif + using ::iswcntrl; + using ::iswdigit; + using ::iswgraph; + using ::iswlower; + using ::iswprint; + using ::iswprint; + using ::iswpunct; + using ::iswspace; + using ::iswupper; + using ::iswxdigit; + using ::iswctype; + using ::towlower; + using ::towupper; + using ::towctrans; + using ::wctrans; + using ::wctype; +} +#endif //_GLIBCXX_USE_WCHAR_T + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/bitset b/reactos/tools/ppc-build/core-headers/g++-v3/debug/bitset new file mode 100644 index 00000000000..2e2364ff930 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/bitset @@ -0,0 +1,299 @@ +// Debugging bitset implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_BITSET +#define _GLIBCXX_DEBUG_BITSET + +#include +#include +#include + +namespace __gnu_debug_def +{ + template + class bitset + : public _GLIBCXX_STD::bitset<_Nb>, + public __gnu_debug::_Safe_sequence_base + { + typedef _GLIBCXX_STD::bitset<_Nb> _Base; + typedef __gnu_debug::_Safe_sequence_base _Safe_base; + + public: + // bit reference: + class reference + : private _Base::reference, public __gnu_debug::_Safe_iterator_base + { + typedef typename _Base::reference _Base_ref; + + friend class bitset; + reference(); + + reference(const _Base_ref& __base, bitset* __seq) + : _Base_ref(__base), _Safe_iterator_base(__seq, false) + { } + + public: + reference(const reference& __x) + : _Base_ref(__x), _Safe_iterator_base(__x, false) + { } + + reference& + operator=(bool __x) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + reference& + operator=(const reference& __x) + { + _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(__x)); + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + bool + operator~() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return ~(*static_cast(this)); + } + + operator bool() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return *static_cast(this); + } + + reference& + flip() + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_flip) + ._M_iterator(*this)); + _Base_ref::flip(); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() : _Base() { } + + bitset(unsigned long __val) : _Base(__val) { } + + template + explicit + bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __pos = 0, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __n = (std::basic_string<_CharT,_Traits,_Allocator>::npos)) + : _Base(__str, __pos, __n) { } + + bitset(const _Base& __x) : _Base(__x), _Safe_base() { } + + // 23.3.5.2 bitset operations: + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + _M_base() &= __rhs; + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + _M_base() |= __rhs; + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + _M_base() ^= __rhs; + return *this; + } + + bitset<_Nb>& + operator<<=(size_t __pos) + { + _M_base() <<= __pos; + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __pos) + { + _M_base() >>= __pos; + return *this; + } + + bitset<_Nb>& + set() + { + _Base::set(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 186. bitset::set() second parameter should be bool + bitset<_Nb>& + set(size_t __pos, bool __val = true) + { + _Base::set(__pos, __val); + return *this; + } + + bitset<_Nb>& + reset() + { + _Base::reset(); + return *this; + } + + bitset<_Nb>& + reset(size_t __pos) + { + _Base::reset(__pos); + return *this; + } + + bitset<_Nb> operator~() const { return bitset(~_M_base()); } + + bitset<_Nb>& + flip() + { + _Base::flip(); + return *this; + } + + bitset<_Nb>& + flip(size_t __pos) + { + _Base::flip(__pos); + return *this; + } + + // element access: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + reference + operator[](size_t __pos) + { + __glibcxx_check_subscript(__pos); + return reference(_M_base()[__pos], this); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + bool + operator[](size_t __pos) const + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::to_ulong; + + template + std::basic_string<_CharT, _Traits, _Allocator> + to_string() const + { return _M_base().template to_string<_CharT, _Traits, _Allocator>(); } + + using _Base::count; + using _Base::size; + + bool + operator==(const bitset<_Nb>& __rhs) const + { return _M_base() == __rhs; } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return _M_base() != __rhs; } + + using _Base::test; + using _Base::any; + using _Base::none; + + bitset<_Nb> + operator<<(size_t __pos) const + { return bitset<_Nb>(_M_base() << __pos); } + + bitset<_Nb> + operator>>(size_t __pos) const + { return bitset<_Nb>(_M_base() >> __pos); } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template + bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) &= __y; } + + template + bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) |= __y; } + + template + bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) ^= __y; } + + template + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { return __is >> __x._M_base(); } + + template + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) + { return __os << __x._M_base(); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/debug.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/debug.h new file mode 100644 index 00000000000..87bbcfa4db6 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/debug.h @@ -0,0 +1,531 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEBUG_H +#define _GLIBCXX_DEBUG_DEBUG_H 1 + +/** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ +#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do { \ + if (! (_Condition)) \ + ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + +// Verify that [_First, _Last) forms a valid iterator range. +#define __glibcxx_check_valid_range(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ + _M_message(::__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. +*/ +#define __glibcxx_check_insert(_Position) \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * that it reference the sequence we are inserting into, and that the + * iterator range [_First, Last) is a valid (possibly empty) + * range. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + * + * @tbd We would like to be able to check for noninterference of + * _Position and the range [_First, _Last), but that can't (in + * general) be done. +*/ +#define __glibcxx_check_insert_range(_Position,_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. +*/ +#define __glibcxx_check_erase(_Position) \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(::__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. +*/ +#define __glibcxx_check_erase_range(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +// Verify that the subscript _N is less than the container's size. +#define __glibcxx_check_subscript(_N) \ +_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(::__gnu_debug::__msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + +// Verify that the container is nonempty +#define __glibcxx_check_nonempty() \ +_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(::__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) + +// Verify that the < operator for elements in the sequence is a +// StrictWeakOrdering by checking that it is irreflexive. +#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + +// Verify that the predicate is StrictWeakOrdering by checking that it +// is irreflexive. +#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + +// Verify that the iterator range [_First, _Last) is sorted +#define __glibcxx_check_sorted(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(::__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ +#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ +#define __glibcxx_check_partitioned(_First,_Last,_Value) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(::__gnu_debug::__msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ +#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(::__gnu_debug::__msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + +// Verify that the iterator range [_First, _Last) is a heap +#define __glibcxx_check_heap(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ + _M_message(::__gnu_debug::__msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ +#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) +# define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) +#else +# define __glibcxx_check_string(_String) +# define __glibcxx_check_string_len(_String,_Len) +#endif + +/** Macros used by the implementation outside of debug wrappers to + * verify certain properties. The __glibcxx_requires_xxx macros are + * merely wrappers around the __glibcxx_check_xxx wrappers when we + * are compiling with debug mode, but disappear when we are in + * release mode so that there is no checking performed in, e.g., the + * standard library algorithms. +*/ +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition) + +# ifdef _GLIBXX_DEBUG_PEDANTIC +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition) +# else +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# endif + +# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) \ + __glibcxx_check_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) \ + __glibcxx_check_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) \ + __glibcxx_check_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty() +# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) \ + __glibcxx_check_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) +#else +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define __glibcxx_requires_cond(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() +# define __glibcxx_requires_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) +#endif + +#include // TBD: temporary + +#include // for ptrdiff_t +#include // for iterator_traits, categories +#include // for _Is_integer + +namespace __gnu_debug +{ + template + class _Safe_iterator; + + // An arbitrary iterator pointer is not singular. + inline bool + __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template + inline bool + __valid_range_aux(const _Integral&, const _Integral&, __true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return __gnu_debug::__valid_range_aux(__first, __last, _Integral()); + } + + /** Safe iterators know how to check if they form a valid range. */ + template + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + /* Checks that [first, last) is a valid range, and then returns + * __first. This routine is useful when we can't use a separate + * assertion statement because, e.g., we are in a constructor. + */ + template + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last) + { + _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s, const _Integer& __n) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); +#endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); +#endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we + // can't step through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted. + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); + } + + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element. + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element. + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } +} // namespace __gnu_debug + +#ifdef _GLIBCXX_DEBUG +// We need the error formatter +# include +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/deque b/reactos/tools/ppc-build/core-headers/g++-v3/debug/deque new file mode 100644 index 00000000000..c39a49c0461 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/deque @@ -0,0 +1,386 @@ +// Debugging deque implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEQUE +#define _GLIBCXX_DEBUG_DEQUE 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template > + class deque + : public _GLIBCXX_STD::deque<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.1.1 construct/copy/destroy: + explicit deque(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit deque(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template + deque(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } + + deque(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~deque() { } + + deque<_Tp,_Allocator>& + operator=(const deque<_Tp,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.1.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + bool __invalidate_all = __sz > this->size(); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + + _Base::resize(__sz, __c); + + if (__invalidate_all) + this->_M_invalidate_all(); + } + + using _Base::empty; + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.1.3 modifiers: + void + push_front(const _Tp& __x) + { + _Base::push_front(__x); + this->_M_invalidate_all(); + } + + void + push_back(const _Tp& __x) + { + _Base::push_back(__x); + this->_M_invalidate_all(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __res = _Base::insert(__position.base(), __x); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + this->_M_invalidate_all(); + } + + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + this->_M_invalidate_all(); + } + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + if (__position == begin() || __position == end()-1) + { + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + else + { + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + if (__first == begin() || __last == end()) + { + this->_M_detach_singular(); + for (iterator __position = __first; __position != __last; ) + { + iterator __victim = __position++; + __victim._M_invalidate(); + } + try + { + return iterator(_Base::erase(__first.base(), __last.base()), + this); + } + catch (...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + else + { + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + void + swap(deque<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template + inline bool + operator==(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/formatter.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/formatter.h new file mode 100644 index 00000000000..db555b0030d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/formatter.h @@ -0,0 +1,391 @@ +// Debug-mode error formatting implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_FORMATTER_H +#define _GLIBCXX_DEBUG_FORMATTER_H 1 + +#include +#include + +namespace __gnu_debug +{ + using std::type_info; + + /** Determine if the two types are the same. */ + template + struct __is_same + { + static const bool value = false; + }; + + template + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template struct __truth { }; + + class _Safe_sequence_base; + + template + class _Safe_iterator; + + template + class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __msg_valid_range, + __msg_insert_singular, + __msg_insert_different, + __msg_erase_bad, + __msg_erase_different, + __msg_subscript_oob, + __msg_empty, + __msg_unpartitioned, + __msg_unpartitioned_pred, + __msg_unsorted, + __msg_unsorted_pred, + __msg_not_heap, + __msg_not_heap_pred, + // std::bitset checks + __msg_bad_bitset_write, + __msg_bad_bitset_read, + __msg_bad_bitset_flip, + // std::list checks + __msg_self_splice, + __msg_splice_alloc, + __msg_splice_bad, + __msg_splice_other, + __msg_splice_overlap, + // iterator checks + __msg_init_singular, + __msg_init_copy_singular, + __msg_init_const_singular, + __msg_copy_singular, + __msg_bad_deref, + __msg_bad_inc, + __msg_bad_dec, + __msg_iter_subscript_oob, + __msg_advance_oob, + __msg_retreat_oob, + __msg_iter_compare_bad, + __msg_compare_different, + __msg_iter_order_bad, + __msg_order_different, + __msg_distance_bad, + __msg_distance_different, + // istream_iterator + __msg_deref_istream, + __msg_inc_istream, + // ostream_iterator + __msg_output_ostream, + // istreambuf_iterator + __msg_deref_istreambuf, + __msg_inc_istreambuf + }; + + class _Error_formatter + { + /// Whether an iterator is constant, mutable, or unknown + enum _Constness + { + __unknown_constness, + __const_iterator, + __mutable_iterator, + __last_constness + }; + + // The state of the iterator (fine-grained), if we know it. + enum _Iterator_state + { + __unknown_state, + __singular, // singular, may still be attached to a sequence + __begin, // dereferenceable, and at the beginning + __middle, // dereferenceable, not at the beginning + __end, // past-the-end, may be at beginning if sequence empty + __last_state + }; + + // Tags denoting the type of parameter for construction + struct _Is_iterator { }; + struct _Is_sequence { }; + + // A parameter that may be referenced by an error message + struct _Parameter + { + enum + { + __unused_param, + __iterator, + __sequence, + __integer, + __string + } _M_kind; + + union + { + // When _M_kind == __iterator + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + _Constness _M_constness; + _Iterator_state _M_state; + const void* _M_sequence; + const type_info* _M_seq_type; + } _M_iterator; + + // When _M_kind == __sequence + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + } _M_sequence; + + // When _M_kind == __integer + struct + { + const char* _M_name; + long _M_value; + } _M_integer; + + // When _M_kind == __string + struct + { + const char* _M_name; + const char* _M_value; + } _M_string; + } _M_variant; + + _Parameter() : _M_kind(__unused_param), _M_variant() { } + + _Parameter(long __value, const char* __name) + : _M_kind(__integer), _M_variant() + { + _M_variant._M_integer._M_name = __name; + _M_variant._M_integer._M_value = __value; + } + + _Parameter(const char* __value, const char* __name) + : _M_kind(__string), _M_variant() + { + _M_variant._M_string._M_name = __name; + _M_variant._M_string._M_value = __value; + } + + template + _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = + __is_same<_Safe_iterator<_Iterator, _Sequence>, + typename _Sequence::iterator>:: + value? __mutable_iterator : __const_iterator; + _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); + _M_variant._M_iterator._M_seq_type = &typeid(_Sequence); + + if (__it._M_singular()) + _M_variant._M_iterator._M_state = __singular; + else + { + bool __is_begin = __it._M_is_begin(); + bool __is_end = __it._M_is_end(); + if (__is_end) + _M_variant._M_iterator._M_state = __end; + else if (__is_begin) + _M_variant._M_iterator._M_state = __begin; + else + _M_variant._M_iterator._M_state = __middle; + } + } + + template + _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(_Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __unknown_constness; + _M_variant._M_iterator._M_state = + __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template + _Parameter(const _Safe_sequence<_Sequence>& __seq, + const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = + static_cast(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template + _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = &__seq; + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + void + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const; + + void + _M_print_description(const _Error_formatter* __formatter) const; + }; + + friend struct _Parameter; + + public: + template + const _Error_formatter& + _M_iterator(const _Iterator& __it, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__it, __name, + _Is_iterator()); + return *this; + } + + const _Error_formatter& + _M_integer(long __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + const _Error_formatter& + _M_string(const char* __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + template + const _Error_formatter& + _M_sequence(const _Sequence& __seq, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, + _Is_sequence()); + return *this; + } + + const _Error_formatter& + _M_message(const char* __text) const + { _M_text = __text; return *this; } + + const _Error_formatter& + _M_message(_Debug_msg_id __id) const; + + void + _M_error() const; + + private: + _Error_formatter(const char* __file, size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { } + + template + void + _M_format_word(char*, int, const char*, _Tp) const; + + void + _M_print_word(const char* __word) const; + + void + _M_print_string(const char* __string) const; + + enum { __max_parameters = 9 }; + + const char* _M_file; + size_t _M_line; + mutable _Parameter _M_parameters[__max_parameters]; + mutable size_t _M_num_parameters; + mutable const char* _M_text; + mutable size_t _M_max_length; + enum { _M_indent = 4 } ; + mutable size_t _M_column; + mutable bool _M_first_line; + mutable bool _M_wordwrap; + + public: + static _Error_formatter + _M_at(const char* __file, size_t __line) + { return _Error_formatter(__file, __line); } + }; +} // namespace __gnu_debug + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map new file mode 100644 index 00000000000..570a9af6b69 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map @@ -0,0 +1,38 @@ +// Debugging hash_map/hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MAP +#define _GLIBCXX_DEBUG_HASH_MAP 1 + +#include +#include +#include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map.h new file mode 100644 index 00000000000..c2cd7b8ca69 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_map.h @@ -0,0 +1,270 @@ +// Debugging hash_map implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MAP_H +#define _GLIBCXX_DEBUG_HASH_MAP_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_map + : public __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_map() { } + + explicit hash_map(size_type __n) : _Base(__n) { } + + hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template + hash_map(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_map(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_map& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + std::pair + insert(const value_type& __obj) + { + std::pair __res = _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair + insert_noresize(const value_type& __obj) + { + std::pair __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::operator[]; + using _Base::count; + + std::pair + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multimap.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multimap.h new file mode 100644 index 00000000000..83b4425aaf0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multimap.h @@ -0,0 +1,261 @@ +// Debugging hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MULTIMAP_H +#define _GLIBCXX_DEBUG_HASH_MULTIMAP_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multimap + : public __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multimap() { } + + explicit hash_multimap(size_type __n) : _Base(__n) { } + + hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multimap& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + std::pair __victims = this->equal_range(__key); + size_t __num_victims = 0; + while (__victims.first != __victims.second) + { + this->erase(__victims.first++); + ++__num_victims; + } + return __num_victims; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multiset.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multiset.h new file mode 100644 index 00000000000..705d8da2532 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_multiset.h @@ -0,0 +1,236 @@ +// Debugging hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MULTISET_H +#define _GLIBCXX_DEBUG_HASH_MULTISET_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multiset + : public __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx:: hash_multiset<_Value,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multiset() { } + + explicit hash_multiset(size_type __n) : _Base(__n) { } + + hash_multiset(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multiset& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() const { return iterator(_Base::begin(), this); } + iterator end() const { return iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + size_type __count = 0; + std::pair __victims = this->equal_range(__key); + while (__victims.first != __victims.second) + { + this->erase(__victims++); + ++__count; + } + return __count; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + +template + inline bool + operator==(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + +template + inline bool + operator!=(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + +template + inline void + swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set new file mode 100644 index 00000000000..282cba27613 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set @@ -0,0 +1,38 @@ +// Debugging hash_set/hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_SET +#define _GLIBCXX_DEBUG_HASH_SET 1 + +#include +#include +#include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set.h new file mode 100644 index 00000000000..0f56d882935 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/hash_set.h @@ -0,0 +1,245 @@ +// Debugging hash_set implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_SET_H +#define _GLIBCXX_DEBUG_HASH_SET_H 1 + +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_set + : public __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence > + { + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_set() { } + + explicit hash_set(size_type __n) : _Base(__n) { } + + hash_set(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template + hash_set(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_set(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_set& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() const { return iterator(_Base::begin(), this); } + + iterator + end() const { return iterator(_Base::end(), this); } + + std::pair + insert(const value_type& __obj) + { + std::pair __res = + _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair + insert_noresize(const value_type& __obj) + { + std::pair __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template + inline void + swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/list b/reactos/tools/ppc-build/core-headers/g++-v3/debug/list new file mode 100644 index 00000000000..556c9d9acff --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/list @@ -0,0 +1,505 @@ +// Debugging list implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_LIST +#define _GLIBCXX_DEBUG_LIST 1 + +#include +#include +#include +#include + +namespace __gnu_debug_def +{ + template > + class list + : public _GLIBCXX_STD::list<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::list<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.2.1 construct/copy/destroy: + explicit list(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit list(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template + list(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + + list(const list& __x) : _Base(__x), _Safe_base() { } + + list(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~list() { } + + list& + operator=(const list& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.2.2 capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + this->_M_detach_singular(); + + // if __sz < size(), invalidate all iterators in [begin+__sz, end()) + iterator __victim = begin(); + iterator __end = end(); + for (size_type __i = __sz; __victim != __end && __i > 0; --__i) + ++__victim; + + while (__victim != __end) + { + iterator __real_victim = __victim++; + __real_victim._M_invalidate(); + } + + try + { + _Base::resize(__sz, __c); + } + catch(...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + + // element access: + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.2.3 modifiers: + using _Base::push_front; + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + using _Base::push_back; + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + } + + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + + iterator + erase(iterator __position, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__position, __last); + for (iterator __victim = __position; __victim != __last; ) + { + iterator __old = __victim; + ++__victim; + __old._M_invalidate(); + } + return iterator(_Base::erase(__position.base(), __last.base()), this); + } + + void + swap(list& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + // 23.2.2.4 list operations: + void + splice(iterator __position, list& __x) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this, + _M_message(::__gnu_debug::__msg_self_splice) + ._M_sequence(*this, "this")); + this->splice(__position, __x, __x.begin(), __x.end()); + } + + void + splice(iterator __position, list& __x, iterator __i) + { + __glibcxx_check_insert(__position); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x, "__x")); + _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(), + _M_message(::__gnu_debug::__msg_splice_bad) + ._M_iterator(__i, "__i")); + _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x), + _M_message(::__gnu_debug::__msg_splice_other) + ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__i); + _Base::splice(__position.base(), __x._M_base(), __i.base()); + } + + void + splice(iterator __position, list& __x, iterator __first, iterator __last) + { + __glibcxx_check_insert(__position); + __glibcxx_check_valid_range(__first, __last); + _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x), + _M_message(::__gnu_debug::__msg_splice_other) + ._M_sequence(__x, "x") + ._M_iterator(__first, "first")); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x)); + + for (iterator __tmp = __first; __tmp != __last; ) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position, + _M_message(::__gnu_debug::__msg_splice_overlap) + ._M_iterator(__tmp, "position") + ._M_iterator(__first, "first") + ._M_iterator(__last, "last")); + iterator __victim = __tmp++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__victim); + } + + _Base::splice(__position.base(), __x._M_base(), __first.base(), + __last.base()); + } + + void + remove(const _Tp& __value) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (*__x == __value) + __x = erase(__x); + else + ++__x; + } + } + + template + void + remove_if(_Predicate __pred) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (__pred(*__x)) + __x = erase(__x); + else + ++__x; + } + } + + void + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + template + void + unique(_BinaryPredicate __binary_pred) + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + void + merge(list& __x) + { + __glibcxx_check_sorted(_Base::begin(), _Base::end()); + __glibcxx_check_sorted(__x.begin().base(), __x.end().base()); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base()); + } + + template + void + merge(list& __x, _Compare __comp) + { + __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); + __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(), + __comp); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base(), __comp); + } + + void + sort() { _Base::sort(); } + + template + void + sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } + + using _Base::reverse; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/map b/reactos/tools/ppc-build/core-headers/g++-v3/debug/map new file mode 100644 index 00000000000..2c384048718 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/map @@ -0,0 +1,38 @@ +// Debugging map/multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MAP +#define _GLIBCXX_DEBUG_MAP 1 + +#include +#include +#include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/map.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/map.h new file mode 100644 index 00000000000..017158479d1 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/map.h @@ -0,0 +1,323 @@ +// Debugging map implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MAP_H +#define _GLIBCXX_DEBUG_MAP_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator > > + class map + : public _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit map(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a), _Safe_base() { } + + map(const map<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + map(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~map() { } + + map<_Key,_Tp,_Compare,_Allocator>& + operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 133. map missing get_allocator() + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // 23.3.1.2 element access: + using _Base::operator[]; + + // modifiers: + std::pair + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(map<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 map operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, + map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/multimap.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/multimap.h new file mode 100644 index 00000000000..4de1e3b58f4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/multimap.h @@ -0,0 +1,314 @@ +// Debugging multimap implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MULTIMAP_H +#define _GLIBCXX_DEBUG_MULTIMAP_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator > > + class multimap + : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit multimap(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multimap(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multimap() { } + + multimap<_Key,_Tp,_Compare,_Allocator>& + operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 multimap operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/multiset.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/multiset.h new file mode 100644 index 00000000000..92042fef68c --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/multiset.h @@ -0,0 +1,320 @@ +// Debugging multiset implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MULTISET_H +#define _GLIBCXX_DEBUG_MULTISET_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator<_Key> > + class multiset + : public _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit multiset(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multiset(const multiset<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multiset() { } + + multiset<_Key,_Compare,_Allocator>& + operator=(const multiset<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multiset<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // multiset operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + void + swap(multiset<_Key,_Compare,_Allocator>& __x, + multiset<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_base.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_base.h new file mode 100644 index 00000000000..a1af33ac5f7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_base.h @@ -0,0 +1,207 @@ +// Safe sequence/iterator base implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H +#define _GLIBCXX_DEBUG_SAFE_BASE_H 1 + +namespace __gnu_debug +{ + class _Safe_sequence_base; + + /** \brief Basic functionality for a "safe" iterator. + * + * The %_Safe_iterator_base base class implements the functionality + * of a safe iterator that is not specific to a particular iterator + * type. It contains a pointer back to the sequence it references + * along with iterator version information and pointers to form a + * doubly-linked list of iterators referenced by the container. + * + * This class must not perform any operations that can throw an + * exception, or the exception guarantees of derived iterators will + * be broken. + */ + class _Safe_iterator_base + { + public: + /** The sequence this iterator references; may be NULL to indicate + a singular iterator. */ + _Safe_sequence_base* _M_sequence; + + /** The version number of this iterator. The sentinel value 0 is + * used to indicate an invalidated iterator (i.e., one that is + * singular because of an operation on the container). This + * version number must equal the version number in the sequence + * referenced by _M_sequence for the iterator to be + * non-singular. + */ + unsigned int _M_version; + + /** Pointer to the previous iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_prior; + + /** Pointer to the next iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_next; + + protected: + /** Initializes the iterator and makes it singular. */ + _Safe_iterator_base() + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { } + + /** Initialize the iterator to reference the sequence pointed to + * by @p__seq. @p __constant is true when we are initializing a + * constant iterator, and false if it is a mutable iterator. Note + * that @p __seq may be NULL, in which case the iterator will be + * singular. Otherwise, the iterator will reference @p __seq and + * be nonsingular. + */ + _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); } + + /** Initializes the iterator to reference the same sequence that + @p __x does. @p __constant is true if this is a constant + iterator, and false if it is mutable. */ + _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(__x._M_sequence, __constant); } + + _Safe_iterator_base& + operator=(const _Safe_iterator_base&); + + explicit + _Safe_iterator_base(const _Safe_iterator_base&); + + ~_Safe_iterator_base() { this->_M_detach(); } + + public: + /** Attaches this iterator to the given sequence, detaching it + * from whatever sequence it was attached to originally. If the + * new sequence is the NULL pointer, the iterator is left + * unattached. + */ + void _M_attach(_Safe_sequence_base* __seq, bool __constant); + + /** Detach the iterator for whatever sequence it is attached to, + * if any. + */ + void _M_detach(); + + /** Determines if we are attached to the given sequence. */ + bool _M_attached_to(const _Safe_sequence_base* __seq) const + { return _M_sequence == __seq; } + + /** Is this iterator singular? */ + bool _M_singular() const; + + /** Can we compare this iterator to the given iterator @p __x? + Returns true if both iterators are nonsingular and reference + the same sequence. */ + bool _M_can_compare(const _Safe_iterator_base& __x) const; + }; + + /** + * @brief Base class that supports tracking of iterators that + * reference a sequence. + * + * The %_Safe_sequence_base class provides basic support for + * tracking iterators into a sequence. Sequences that track + * iterators must derived from %_Safe_sequence_base publicly, so + * that safe iterators (which inherit _Safe_iterator_base) can + * attach to them. This class contains two linked lists of + * iterators, one for constant iterators and one for mutable + * iterators, and a version number that allows very fast + * invalidation of all iterators that reference the container. + * + * This class must ensure that no operation on it may throw an + * exception, otherwise "safe" sequences may fail to provide the + * exception-safety guarantees required by the C++ standard. + */ + class _Safe_sequence_base + { + public: + /// The list of mutable iterators that reference this container + _Safe_iterator_base* _M_iterators; + + /// The list of constant iterators that reference this container + _Safe_iterator_base* _M_const_iterators; + + /// The container version number. This number may never be 0. + mutable unsigned int _M_version; + + protected: + // Initialize with a version number of 1 and no iterators + _Safe_sequence_base() + : _M_iterators(0), _M_const_iterators(0), _M_version(1) + { } + + /** Notify all iterators that reference this sequence that the + sequence is being destroyed. */ + ~_Safe_sequence_base() + { this->_M_detach_all(); } + + /** Detach all iterators, leaving them singular. */ + void + _M_detach_all(); + + /** Detach all singular iterators. + * @post for all iterators i attached to this sequence, + * i->_M_version == _M_version. + */ + void + _M_detach_singular(); + + /** Revalidates all attached singular iterators. This method may + * be used to validate iterators that were invalidated before + * (but for some reasion, such as an exception, need to become + * valid again). + */ + void + _M_revalidate_singular(); + + /** Swap this sequence with the given sequence. This operation + * also swaps ownership of the iterators, so that when the + * operation is complete all iterators that originally referenced + * one container now reference the other container. + */ + void + _M_swap(_Safe_sequence_base& __x); + + public: + /** Invalidates all iterators. */ + void + _M_invalidate_all() const + { if (++_M_version == 0) _M_version = 1; } + }; +} // namespace __gnu_debug + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.h new file mode 100644 index 00000000000..8a4123af694 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.h @@ -0,0 +1,618 @@ +// Safe iterator implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 + +#include +#include +#include +#include +#include + +namespace __gnu_debug +{ + using std::iterator_traits; + using std::pair; + + /** Iterators that derive from _Safe_iterator_base but that aren't + * _Safe_iterators can be determined singular or non-singular via + * _Safe_iterator_base. + */ + inline bool __check_singular_aux(const _Safe_iterator_base* __x) + { return __x->_M_singular(); } + + /** \brief Safe iterator wrapper. + * + * The class template %_Safe_iterator is a wrapper around an + * iterator that tracks the iterator's movement among sequences and + * checks that operations performed on the "safe" iterator are + * legal. In additional to the basic iterator operations (which are + * validated, and then passed to the underlying iterator), + * %_Safe_iterator has member functions for iterator invalidation, + * attaching/detaching the iterator from sequences, and querying + * the iterator's state. + */ + template + class _Safe_iterator : public _Safe_iterator_base + { + typedef _Safe_iterator _Self; + + /** The precision to which we can calculate the distance between + * two iterators. + */ + enum _Distance_precision + { + __dp_equality, //< Can compare iterator equality, only + __dp_sign, //< Can determine equality and ordering + __dp_exact //< Can determine distance precisely + }; + + /// The underlying iterator + _Iterator _M_current; + + /// Determine if this is a constant iterator. + bool + _M_constant() const + { + typedef typename _Sequence::const_iterator const_iterator; + return __is_same::value; + } + + typedef iterator_traits<_Iterator> _Traits; + + public: + typedef _Iterator _Base_iterator; + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; + + /// @post the iterator is singular and unattached + _Safe_iterator() : _M_current() { } + + /** + * @brief Safe iterator construction from an unsafe iterator and + * its sequence. + * + * @pre @p seq is not NULL + * @post this is not singular + */ + _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) + : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__msg_init_singular) + ._M_iterator(*this, "this")); + } + + /** + * @brief Copy construction. + * @pre @p x is not singular + */ + _Safe_iterator(const _Safe_iterator& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Converting constructor from a mutable iterator to a + * constant iterator. + * + * @pre @p x is not singular + */ + template + _Safe_iterator( + const _Safe_iterator<_MutableIterator, + typename std::__enable_if< + _Sequence, + (std::__are_same<_MutableIterator, + typename _Sequence::iterator::_Base_iterator>::_M_type) + >::_M_type>& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_const_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Copy assignment. + * @pre @p x is not singular + */ + _Safe_iterator& + operator=(const _Safe_iterator& __x) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + _M_current = __x._M_current; + this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); + return *this; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + */ + reference + operator*() const + { + + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return *_M_current; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + * @todo Make this correct w.r.t. iterators that return proxies + * @todo Use addressof() instead of & operator + */ + pointer + operator->() const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return &*_M_current; + } + + // ------ Input iterator requirements ------ + /** + * @brief Iterator preincrement + * @pre iterator is incrementable + */ + _Safe_iterator& + operator++() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + ++_M_current; + return *this; + } + + /** + * @brief Iterator postincrement + * @pre iterator is incrementable + */ + _Safe_iterator + operator++(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + ++_M_current; + return __tmp; + } + + // ------ Bidirectional iterator requirements ------ + /** + * @brief Iterator predecrement + * @pre iterator is decrementable + */ + _Safe_iterator& + operator--() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + --_M_current; + return *this; + } + + /** + * @brief Iterator postdecrement + * @pre iterator is decrementable + */ + _Safe_iterator + operator--(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + --_M_current; + return __tmp; + } + + // ------ Random access iterator requirements ------ + reference + operator[](const difference_type& __n) const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) + && this->_M_can_advance(__n+1), + _M_message(__msg_iter_subscript_oob) + ._M_iterator(*this)._M_integer(__n)); + + return _M_current[__n]; + } + + _Safe_iterator& + operator+=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), + _M_message(__msg_advance_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += __n; + return *this; + } + + _Safe_iterator + operator+(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp += __n; + return __tmp; + } + + _Safe_iterator& + operator-=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), + _M_message(__msg_retreat_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += -__n; + return *this; + } + + _Safe_iterator + operator-(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp -= __n; + return __tmp; + } + + // ------ Utilities ------ + /** + * @brief Return the underlying iterator + */ + _Iterator + base() const { return _M_current; } + + /** + * @brief Conversion to underlying non-debug iterator to allow + * better interaction with non-debug containers. + */ + operator _Iterator() const { return _M_current; } + + /** Attach iterator to the given sequence. */ + void + _M_attach(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), + _M_constant()); + } + + /** Invalidate the iterator, making it singular. */ + void + _M_invalidate(); + + /// Is the iterator dereferenceable? + bool + _M_dereferenceable() const + { return !this->_M_singular() && !_M_is_end(); } + + /// Is the iterator incrementable? + bool + _M_incrementable() const { return this->_M_dereferenceable(); } + + // Is the iterator decrementable? + bool + _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } + + // Can we advance the iterator @p __n steps (@p __n may be negative) + bool + _M_can_advance(const difference_type& __n) const; + + // Is the iterator range [*this, __rhs) valid? + template + bool + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; + + // The sequence this iterator references. + const _Sequence* + _M_get_sequence() const + { return static_cast(_M_sequence); } + + /** Determine the distance between two iterators with some known + * precision. + */ + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) + { + typedef typename iterator_traits<_Iterator1>::iterator_category + _Category; + return _M_get_distance(__lhs, __rhs, _Category()); + } + + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::random_access_iterator_tag) + { + return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); + } + + template + static pair + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::forward_iterator_tag) + { + return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, + __dp_equality); + } + + /// Is this iterator equal to the sequence's begin() iterator? + bool _M_is_begin() const + { return *this == static_cast(_M_sequence)->begin(); } + + /// Is this iterator equal to the sequence's end() iterator? + bool _M_is_end() const + { return *this == static_cast(_M_sequence)->end(); } + }; + + template + inline bool + operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template + inline bool + operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template + inline bool + operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template + inline bool + operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template + inline bool + operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template + inline bool + operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template + inline bool + operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template + inline bool + operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template + inline bool + operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template + inline bool + operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template + inline bool + operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + template + inline bool + operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template + inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type + operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template + inline _Safe_iterator<_Iterator, _Sequence> + operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, + const _Safe_iterator<_Iterator, _Sequence>& __i) + { return __i + __n; } +} // namespace __gnu_debug + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.tcc b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.tcc new file mode 100644 index 00000000000..cede969d168 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_iterator.tcc @@ -0,0 +1,140 @@ +// Debugging iterator implementation (out of line) -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file safe_iterator.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1 + +namespace __gnu_debug +{ + template + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_can_advance(const difference_type& __n) const + { + typedef typename _Sequence::const_iterator const_iterator; + + if (this->_M_singular()) + return false; + if (__n == 0) + return true; + if (__n < 0) + { + const_iterator __begin = + static_cast(_M_sequence)->begin(); + pair __dist = + this->_M_get_distance(__begin, *this); + bool __ok = (__dist.second == __dp_exact && __dist.first >= -__n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + else + { + const_iterator __end = + static_cast(_M_sequence)->end(); + pair __dist = + this->_M_get_distance(*this, __end); + bool __ok = (__dist.second == __dp_exact && __dist.first >= __n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + } + + template + template + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; + + /* Determine if we can order the iterators without the help of + the container */ + pair __dist = + this->_M_get_distance(*this, __rhs); + switch (__dist.second) { + case __dp_equality: + if (__dist.first == 0) + return true; + break; + + case __dp_sign: + case __dp_exact: + return __dist.first >= 0; + } + + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + if (_M_is_begin() || __rhs._M_is_end()) + return true; + else if (_M_is_end() || __rhs._M_is_begin()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } + + template + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate() + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + if (!this->_M_singular()) + { + for (_Safe_iterator_base* iter = _M_sequence->_M_iterators; iter; ) + { + iterator* __victim = static_cast(iter); + iter = iter->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + for (_Safe_iterator_base* iter2 = _M_sequence->_M_const_iterators; + iter2; /* increment in loop */) + { + const_iterator* __victim = static_cast(iter2); + iter2 = iter2->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + _M_version = 0; + } + } +} // namespace __gnu_debug + +#endif + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_sequence.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_sequence.h new file mode 100644 index 00000000000..f050530a997 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/safe_sequence.h @@ -0,0 +1,180 @@ +// Safe sequence implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H +#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 + +#include +#include + +namespace __gnu_debug +{ + template + class _Safe_iterator; + + /** A simple function object that returns true if the passed-in + * value is not equal to the stored value. It saves typing over + * using both bind1st and not_equal. + */ + template + class _Not_equal_to + { + _Type __value; + + public: + explicit _Not_equal_to(const _Type& __v) : __value(__v) { } + + bool + operator()(const _Type& __x) const + { return __value != __x; } + }; + + /** A function object that returns true when the given random access + iterator is at least @c n steps away from the given iterator. */ + template + class _After_nth_from + { + typedef typename std::iterator_traits<_Iterator>::difference_type + difference_type; + + _Iterator _M_base; + difference_type _M_n; + + public: + _After_nth_from(const difference_type& __n, const _Iterator& __base) + : _M_base(__base), _M_n(__n) { } + + bool + operator()(const _Iterator& __x) const + { return __x - _M_base >= _M_n; } + }; + + /** + * @brief Base class for constructing a "safe" sequence type that + * tracks iterators that reference it. + * + * The class template %_Safe_sequence simplifies the construction of + * "safe" sequences that track the iterators that reference the + * sequence, so that the iterators are notified of changes in the + * sequence that may affect their operation, e.g., if the container + * invalidates its iterators or is destructed. This class template + * may only be used by deriving from it and passing the name of the + * derived class as its template parameter via the curiously + * recurring template pattern. The derived class must have @c + * iterator and @const_iterator types that are instantiations of + * class template _Safe_iterator for this sequence. Iterators will + * then be tracked automatically. + */ + template + class _Safe_sequence : public _Safe_sequence_base + { + public: + /** Invalidates all iterators @c x that reference this sequence, + are not singular, and for which @c pred(x) returns @c + true. The user of this routine should be careful not to make + copies of the iterators passed to @p pred, as the copies may + interfere with the invalidation. */ + template + void + _M_invalidate_if(_Predicate __pred); + + /** Transfers all iterators that reference this memory location + to this sequence from whatever sequence they are attached + to. */ + template + void + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x); + }; + + template + template + void + _Safe_sequence<_Sequence>:: + _M_invalidate_if(_Predicate __pred) + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; ) + { + const_iterator* __victim = static_cast(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + } + + template + template + void + _Safe_sequence<_Sequence>:: + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x) + { + _Safe_sequence_base* __from = __x._M_sequence; + if (!__from) + return; + + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; ) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + + for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators; + __iter2;) + { + const_iterator* __victim = static_cast(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + } +} // namespace __gnu_debug + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/set b/reactos/tools/ppc-build/core-headers/g++-v3/debug/set new file mode 100644 index 00000000000..a1a69efb4f4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/set @@ -0,0 +1,38 @@ +// Debugging set/multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SET +#define _GLIBCXX_DEBUG_SET 1 + +#include +#include +#include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/set.h b/reactos/tools/ppc-build/core-headers/g++-v3/debug/set.h new file mode 100644 index 00000000000..8656cb0aff6 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/set.h @@ -0,0 +1,325 @@ +// Debugging set implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SET_H +#define _GLIBCXX_DEBUG_SET_H 1 + +#include +#include +#include + +namespace __gnu_debug_def +{ + template, + typename _Allocator = std::allocator<_Key> > + class set + : public _GLIBCXX_STD::set<_Key,_Compare,_Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::set<_Key,_Compare,_Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit set(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + set(const set<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + set(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~set() { } + + set<_Key,_Compare,_Allocator>& + operator=(const set<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + std::pair + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + while (__first != __last) + this->erase(__first++); + } + + void + swap(set<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // set operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template + inline bool + operator==(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + void + swap(set<_Key,_Compare,_Allocator>& __x, + set<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/string b/reactos/tools/ppc-build/core-headers/g++-v3/debug/string new file mode 100644 index 00000000000..a91c004e937 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/string @@ -0,0 +1,1001 @@ +// Debugging string implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_STRING +#define _GLIBCXX_DEBUG_STRING 1 + +#include +#include +#include + +namespace __gnu_debug +{ + template + class basic_string + : public std::basic_string<_CharT, _Traits, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + public: + // types: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::size_type size_type; + typedef typename _Allocator::difference_type difference_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator const_iterator; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + using _Base::npos; + + // 21.3.1 construct/copy/destroy: + explicit basic_string(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + // Provides conversion from a release-mode string to a debug-mode string + basic_string(const _Base& __base) : _Base(__base), _Safe_base() { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str) + : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base() + { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str, size_type __pos, + size_type __n = _Base::npos, + const _Allocator& __a = _Allocator()) + : _Base(__str, __pos, __n, __a) + { } + + basic_string(const _CharT* __s, size_type __n, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) + { } + + basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s), __a) + { this->assign(__s); } + + basic_string(size_type __n, _CharT __c, + const _Allocator& __a = _Allocator()) + : _Base(__n, __c, __a) + { } + + template + basic_string(_InputIterator __begin, _InputIterator __end, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a) + { } + + ~basic_string() { } + + basic_string& + operator=(const basic_string& __str) + { + *static_cast<_Base*>(this) = __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(const _CharT* __s) + { + __glibcxx_check_string(__s); + *static_cast<_Base*>(this) = __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(_CharT __c) + { + *static_cast<_Base*>(this) = __c; + this->_M_invalidate_all(); + return *this; + } + + // 21.3.2 iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 21.3.3 capacity: + using _Base::size; + using _Base::length; + using _Base::max_size; + + void + resize(size_type __n, _CharT __c) + { + _Base::resize(__n, __c); + this->_M_invalidate_all(); + } + + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + using _Base::capacity; + using _Base::reserve; + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::empty; + + // 21.3.4 element access: + const_reference + operator[](size_type __pos) const + { + _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), + _M_message(::__gnu_debug::__msg_subscript_oob) + ._M_sequence(*this, "this") + ._M_integer(__pos, "__pos") + ._M_integer(this->size(), "size")); + return _M_base()[__pos]; + } + + reference + operator[](size_type __pos) + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::at; + + // 21.3.5 modifiers: + basic_string& + operator+=(const basic_string& __str) + { + _M_base() += __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(const _CharT* __s) + { + __glibcxx_check_string(__s); + _M_base() += __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(_CharT __c) + { + _M_base() += __c; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str) + { + _Base::append(__str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::append(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::append(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::append(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(size_type __n, _CharT __c) + { + _Base::append(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + append(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::append(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 7. string clause minor problems + void + push_back(_CharT __c) + { + _Base::push_back(__c); + this->_M_invalidate_all(); + } + + basic_string& + assign(const basic_string& __x) + { + _Base::assign(__x); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::assign(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::assign(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::assign(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(size_type __n, _CharT __c) + { + _Base::assign(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str) + { + _Base::insert(__pos1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { + _Base::insert(__pos1, __str, __pos2, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { + _Base::insert(__pos, __n, __c); + this->_M_invalidate_all(); + return *this; + } + + iterator + insert(iterator __p, _CharT __c) + { + __glibcxx_check_insert(__p); + typename _Base::iterator __res = _Base::insert(__p.base(), __c); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __p, size_type __n, _CharT __c) + { + __glibcxx_check_insert(__p); + _Base::insert(__p.base(), __n, __c); + this->_M_invalidate_all(); + } + + template + void + insert(iterator __p, _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__p, __first, __last); + _Base::insert(__p.base(), __first, __last); + this->_M_invalidate_all(); + } + + basic_string& + erase(size_type __pos = 0, size_type __n = _Base::npos) + { + _Base::erase(__pos, __n); + this->_M_invalidate_all(); + return *this; + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str) + { + _Base::replace(__pos1, __n1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { + _Base::replace(__pos1, __n1, __str, __pos2, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_check_string_len(__s, __n2); + _Base::replace(__pos, __n1, __s, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::replace(__pos, __n1, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { + _Base::replace(__pos, __n1, __n2, __c); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string_len(__s, __n); + _Base::replace(__i1.base(), __i2.base(), __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string(__s); + _Base::replace(__i1.base(), __i2.base(), __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __n, __c); + this->_M_invalidate_all(); + return *this; + } + + template + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __j1, _InputIterator __j2) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_valid_range(__j1, __j2); + _Base::replace(__i1.base(), __i2.base(), __j1, __j2); + this->_M_invalidate_all(); + return *this; + } + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::copy(__s, __n, __pos); + } + + void + swap(basic_string<_CharT,_Traits,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + this->_M_invalidate_all(); + __x._M_invalidate_all(); + } + + // 21.3.6 string operations: + const _CharT* + c_str() const + { + const _CharT* __res = _Base::c_str(); + this->_M_invalidate_all(); + return __res; + } + + const _CharT* + data() const + { + const _CharT* __res = _Base::data(); + this->_M_invalidate_all(); + return __res; + } + + using _Base::get_allocator; + + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return _Base::find(__str, __pos); } + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos, __n); + } + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos); + } + + size_type + find(_CharT __c, size_type __pos = 0) const + { return _Base::find(__c, __pos); } + + size_type + rfind(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::rfind(__str, __pos); } + + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::rfind(__s, __pos, __n); + } + + size_type + rfind(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::rfind(__s, __pos); + } + + size_type + rfind(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::rfind(__c, __pos); } + + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_of(__str, __pos); } + + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos, __n); + } + + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos); + } + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_of(__c, __pos); } + + size_type + find_last_of(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__str, __pos); } + + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos, __n); + } + + size_type + find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos); + } + + size_type + find_last_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__c, __pos); } + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_not_of(__str, __pos); } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::find_first_not_of(__s, __pos, __n); + } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_not_of(__s, __pos); + } + + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_not_of(__c, __pos); } + + size_type + find_last_not_of(const basic_string& __str, + size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__str, __pos); } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos, __n); + } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos); + } + + size_type + find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__c, __pos); } + + basic_string + substr(size_type __pos = 0, size_type __n = _Base::npos) const + { return basic_string(_Base::substr(__pos, __n)); } + + int + compare(const basic_string& __str) const + { return _Base::compare(__str); } + + int + compare(size_type __pos1, size_type __n1, + const basic_string& __str) const + { return _Base::compare(__pos1, __n1, __str); } + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } + + int + compare(const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__pos1, __n1, __s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1,const _CharT* __s, + size_type __n2) const + { + __glibcxx_check_string_len(__s, __n2); + return _Base::compare(__pos1, __n1, __s, __n2); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + using _Safe_base::_M_invalidate_all; + }; + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(_CharT __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + _CharT __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs == __rhs._M_base(); + } + + template + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() == __rhs; + } + + template + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs != __rhs._M_base(); + } + + template + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() != __rhs; + } + + template + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs < __rhs._M_base(); + } + + template + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() < __rhs; + } + + template + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs <= __rhs._M_base(); + } + + template + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() <= __rhs; + } + + template + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs >= __rhs._M_base(); + } + + template + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() >= __rhs; + } + + template + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs > __rhs._M_base(); + } + + template + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() > __rhs; + } + + // 21.3.7.8: + template + inline void + swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, + basic_string<_CharT,_Traits,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + template + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Allocator>& __str) + { return __os << __str._M_base(); } + + template + std::basic_istream<_CharT,_Traits>& + operator>>(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); + __str._M_invalidate_all(); + return __res; + } + + template + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base(), + __delim); + __str._M_invalidate_all(); + return __res; + } + + template + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base()); + __str._M_invalidate_all(); + return __res; + } +} // namespace __gnu_debug + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/debug/vector b/reactos/tools/ppc-build/core-headers/g++-v3/debug/vector new file mode 100644 index 00000000000..0cc2997b975 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/debug/vector @@ -0,0 +1,412 @@ +// Debugging vector implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_VECTOR +#define _GLIBCXX_DEBUG_VECTOR 1 + +#include +#include +#include +#include + +namespace __gnu_debug_def +{ + template > + class vector + : public _GLIBCXX_STD::vector<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence > + { + typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence _Safe_base; + + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator + iterator; + typedef __gnu_debug::_Safe_iterator + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // 23.2.4.1 construct/copy/destroy: + explicit vector(const _Allocator& __a = _Allocator()) + : _Base(__a), _M_guaranteed_capacity(0) { } + + explicit vector(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } + + template + vector(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), + __last, __a), + _M_guaranteed_capacity(0) + { _M_update_guaranteed_capacity(); } + + vector(const vector<_Tp,_Allocator>& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + /// Construction from a release-mode vector + vector(const _Base& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + ~vector() { } + + vector<_Tp,_Allocator>& + operator=(const vector<_Tp,_Allocator>& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + return *this; + } + + template + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + assign(size_type __n, const _Tp& __u) + { + _Base::assign(__n, __u); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // 23.2.4.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + bool __realloc = _M_requires_reallocation(__sz); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + _Base::resize(__sz, __c); + if (__realloc) + this->_M_invalidate_all(); + } + + using _Base::capacity; + using _Base::empty; + + void + reserve(size_type __n) + { + bool __realloc = _M_requires_reallocation(__n); + _Base::reserve(__n); + if (__n > _M_guaranteed_capacity) + _M_guaranteed_capacity = __n; + if (__realloc) + this->_M_invalidate_all(); + } + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.4.3 modifiers: + void + push_back(const _Tp& __x) + { + bool __realloc = _M_requires_reallocation(this->size() + 1); + _Base::push_back(__x); + if (__realloc) + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end() - 1; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + 1); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::insert(__position.base(),__x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + __n); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __n, __x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + + /* Hard to guess if invalidation will occur, because __last + - __first can't be calculated in all cases, so we just + punt here by checking if it did occur. */ + typename _Base::iterator __old_begin = _M_base().begin(); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __first, __last); + + if (_M_base().begin() != __old_begin) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + difference_type __offset = __first - begin(); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + void + swap(vector<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + _M_guaranteed_capacity = 0; + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + size_type _M_guaranteed_capacity; + + bool + _M_requires_reallocation(size_type __elements) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + return __elements > this->capacity(); +#else + return __elements > _M_guaranteed_capacity; +#endif + } + + void + _M_update_guaranteed_capacity() + { + if (this->size() > _M_guaranteed_capacity) + _M_guaranteed_capacity = this->size(); + } + }; + + template + inline bool + operator==(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template + inline bool + operator!=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template + inline bool + operator<(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template + inline bool + operator<=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template + inline bool + operator>=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template + inline bool + operator>(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template + inline void + swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/deque b/reactos/tools/ppc-build/core-headers/g++-v3/deque new file mode 100644 index 00000000000..80817f632aa --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/deque @@ -0,0 +1,81 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file deque + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_DEQUE +#define _GLIBCXX_DEQUE 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_DEQUE */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/exception b/reactos/tools/ppc-build/core-headers/g++-v3/exception new file mode 100644 index 00000000000..6a1a1946036 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/exception @@ -0,0 +1,120 @@ +// Exception Handling support header for -*- C++ -*- + +// Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file exception + * This header defines several types and functions relating to the + * handling of exceptions in a C++ program. + */ + +#ifndef __EXCEPTION__ +#define __EXCEPTION__ + +extern "C++" { + +namespace std +{ + /** + * @brief Base class for all library exceptions. + * + * This is the base class for all exceptions thrown by the standard + * library, and by certain language expressions. You are free to derive + * your own %exception classes, or use a different hierarchy, or to + * throw non-class data (e.g., fundamental types). + */ + class exception + { + public: + exception() throw() { } + virtual ~exception() throw(); + /** Returns a C-style character string describing the general cause + * of the current error. */ + virtual const char* what() const throw(); + }; + + /** If an %exception is thrown which is not listed in a function's + * %exception specification, one of these may be thrown. */ + class bad_exception : public exception + { + public: + bad_exception() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_exception() throw(); + }; + + /// If you write a replacement %terminate handler, it must be of this type. + typedef void (*terminate_handler) (); + /// If you write a replacement %unexpected handler, it must be of this type. + typedef void (*unexpected_handler) (); + + /// Takes a new handler function as an argument, returns the old function. + terminate_handler set_terminate(terminate_handler) throw(); + /** The runtime will call this function if %exception handling must be + * abandoned for any reason. It can also be called by the user. */ + void terminate() __attribute__ ((__noreturn__)); + + /// Takes a new handler function as an argument, returns the old function. + unexpected_handler set_unexpected(unexpected_handler) throw(); + /** The runtime will call this function if an %exception is thrown which + * violates the function's %exception specification. */ + void unexpected() __attribute__ ((__noreturn__)); + + /** [18.6.4]/1: "Returns true after completing evaluation of a + * throw-expression until either completing initialization of the + * exception-declaration in the matching handler or entering @c unexpected() + * due to the throw; or after entering @c terminate() for any reason + * other than an explicit call to @c terminate(). [Note: This includes + * stack unwinding [15.2]. end note]" + * + * 2: "When @c uncaught_exception() is true, throwing an %exception can + * result in a call of @c terminate() (15.5.1)." + */ + bool uncaught_exception() throw(); +} // namespace std + +namespace __gnu_cxx +{ + /** A replacement for the standard terminate_handler which prints more + information about the terminating exception (if any) on stderr. Call + @code + std::set_terminate (__gnu_cxx::__verbose_terminate_handler) + @endcode + to use. For more info, see + http://gcc.gnu.org/onlinedocs/libstdc++/19_diagnostics/howto.html#4 + + In 3.4 and later, this is on by default. + */ + void __verbose_terminate_handler (); +} // namespace __gnu_cxx + +} // extern "C++" + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/exception_defines.h b/reactos/tools/ppc-build/core-headers/g++-v3/exception_defines.h new file mode 100644 index 00000000000..1466486dc6b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/exception_defines.h @@ -0,0 +1,47 @@ +// -fno-exceptions Support -*- C++ -*- + +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#ifndef _EXCEPTION_DEFINES_H +#define _EXCEPTION_DEFINES_H 1 + +#ifndef __EXCEPTIONS +// Iff -fno-exceptions, transform error handling code to work without it. +# define try if (true) +# define catch(X) if (false) +# define __throw_exception_again +#else +// Else proceed normally. +# define __throw_exception_again throw +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/algorithm b/reactos/tools/ppc-build/core-headers/g++-v3/ext/algorithm new file mode 100644 index 00000000000..07ac4cbe4d3 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/algorithm @@ -0,0 +1,518 @@ +// Algorithm extensions -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/algorithm + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _EXT_ALGORITHM +#define _EXT_ALGORITHM 1 + +#pragma GCC system_header + +#include + +namespace __gnu_cxx +{ + using std::ptrdiff_t; + using std::min; + using std::pair; + using std::input_iterator_tag; + using std::random_access_iterator_tag; + using std::iterator_traits; + + //-------------------------------------------------- + // copy_n (not part of the C++ standard) + + template + pair<_InputIterator, _OutputIterator> + __copy_n(_InputIterator __first, _Size __count, + _OutputIterator __result, + input_iterator_tag) + { + for ( ; __count > 0; --__count) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIterator, _OutputIterator>(__first, __result); + } + + template + inline pair<_RAIterator, _OutputIterator> + __copy_n(_RAIterator __first, _Size __count, + _OutputIterator __result, + random_access_iterator_tag) + { + _RAIterator __last = __first + __count; + return pair<_RAIterator, _OutputIterator>(__last, + std::copy(__first, __last, __result)); + } + + /** + * @brief Copies the range [first,first+count) into [result,result+count). + * @param first An input iterator. + * @param count The number of elements to copy. + * @param result An output iterator. + * @return A std::pair composed of first+count and result+count. + * + * This is an SGI extension. + * This inline function will boil down to a call to @c memmove whenever + * possible. Failing that, if random access iterators are passed, then the + * loop count will be known (and therefore a candidate for compiler + * optimizations such as unrolling). + * @ingroup SGIextensions + */ + template + inline pair<_InputIterator, _OutputIterator> + copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + + return __copy_n(__first, __count, __result, + std::__iterator_category(__first)); + } + + template + int + __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) { + return !(__first1 == __last1); + } + else { + return -1; + } + } + + inline int + __lexicographical_compare_3way(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) + { + const ptrdiff_t __len1 = __last1 - __first1; + const ptrdiff_t __len2 = __last2 - __first2; + const int __result = std::memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result + : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); + } + + inline int + __lexicographical_compare_3way(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) + { +#if CHAR_MAX == SCHAR_MAX + return __lexicographical_compare_3way( + (const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else + return __lexicographical_compare_3way((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif + } + + /** + * @brief @c memcmp on steroids. + * @param first1 An input iterator. + * @param last1 An input iterator. + * @param first2 An input iterator. + * @param last2 An input iterator. + * @return An int, as with @c memcmp. + * + * The return value will be less than zero if the first range is + * "lexigraphically less than" the second, greater than zero if the second + * range is "lexigraphically less than" the first, and zero otherwise. + * This is an SGI extension. + * @ingroup SGIextensions + */ + template + int + lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); + } + + // count and count_if: this version, whose return type is void, was present + // in the HP STL, and is retained as an extension for backward compatibility. + + template + void + count(_InputIterator __first, _InputIterator __last, + const _Tp& __value, + _Size& __n) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + } + + template + void + count_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, + _Size& __n) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + } + + // random_sample and random_sample_n (extensions, not part of the standard). + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + _Distance __remaining = std::distance(__first, __last); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if ((std::rand() % __remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryFunctionConcept< + _RandomNumberGenerator, _Distance, _Distance>) + __glibcxx_requires_valid_range(__first, __last); + + _Distance __remaining = std::distance(__first, __last); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if (__rand(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; + } + + template + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, + const _Distance __n) + { + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = std::rand() % (__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; + } + + template + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, + _RandomNumberGenerator& __rand, + const _Distance __n) + { + // concept requirements + __glibcxx_function_requires(_UnaryFunctionConcept< + _RandomNumberGenerator, _Distance, _Distance>) + + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); + + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, + _RandomNumberGenerator& __rand) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); + + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__is_heap(__first, __last - __first); + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__is_heap(__first, __comp, __last - __first); + } + + // is_sorted, a predicated testing whether a range is sorted in + // nondescending order. This is an extension, not part of the C++ + // standard. + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + bool + is_sorted(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + bool + is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__comp(*__next, *__first)) + return false; + } + + return true; + } +} // namespace __gnu_cxx + +#endif /* _EXT_ALGORITHM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/bitmap_allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/bitmap_allocator.h new file mode 100644 index 00000000000..9a0d1620984 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/bitmap_allocator.h @@ -0,0 +1,859 @@ +// Bitmapped Allocator. -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + + +#if !defined _BITMAP_ALLOCATOR_H +#define _BITMAP_ALLOCATOR_H 1 + +#include +//For std::size_t, and ptrdiff_t. +#include +//For std::pair. +#include +//std::find_if, and std::lower_bound. +#include +//For the free list of exponentially growing memory blocks. At max, +//size of the vector should be not more than the number of bits in an +//integer or an unsigned integer. +#include +//For greater_equal, and less_equal. +#include +//For operator new. +#include +//For __gthread_mutex_t, __gthread_mutex_lock and __gthread_mutex_unlock. +#include +//For __gnu_cxx::new_allocator for std::vector. + +#include +#define NDEBUG + +//#define CHECK_FOR_ERRORS +//#define __CPU_HAS_BACKWARD_BRANCH_PREDICTION + +namespace __gnu_cxx +{ + namespace { +#if defined __GTHREADS + bool const __threads_enabled = __gthread_active_p(); +#endif + + } + +#if defined __GTHREADS + class _Mutex { + __gthread_mutex_t _M_mut; + //Prevent Copying and assignment. + _Mutex (_Mutex const&); + _Mutex& operator= (_Mutex const&); + public: + _Mutex () + { + if (__threads_enabled) + { +#if !defined __GTHREAD_MUTEX_INIT + __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mut); +#else + __gthread_mutex_t __mtemp = __GTHREAD_MUTEX_INIT; + _M_mut = __mtemp; +#endif + } + } + ~_Mutex () + { + //Gthreads does not define a Mutex Destruction Function. + } + __gthread_mutex_t *_M_get() { return &_M_mut; } + }; + + class _Lock { + _Mutex* _M_pmt; + bool _M_locked; + //Prevent Copying and assignment. + _Lock (_Lock const&); + _Lock& operator= (_Lock const&); + public: + _Lock(_Mutex* __mptr) + : _M_pmt(__mptr), _M_locked(false) + { this->_M_lock(); } + void _M_lock() + { + if (__threads_enabled) + { + _M_locked = true; + __gthread_mutex_lock(_M_pmt->_M_get()); + } + } + void _M_unlock() + { + if (__threads_enabled) + { + if (__builtin_expect(_M_locked, true)) + { + __gthread_mutex_unlock(_M_pmt->_M_get()); + _M_locked = false; + } + } + } + ~_Lock() { this->_M_unlock(); } + }; +#endif + + + + namespace __aux_balloc { + static const unsigned int _Bits_Per_Byte = 8; + static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + + template + inline size_t __balloc_num_blocks (_Addr_Pair_t __ap) + { + return (__ap.second - __ap.first) + 1; + } + + template + inline size_t __balloc_num_bit_maps (_Addr_Pair_t __ap) + { + return __balloc_num_blocks(__ap) / _Bits_Per_Block; + } + + //T should be a pointer type. + template + class _Inclusive_between : public std::unary_function, bool> { + typedef _Tp pointer; + pointer _M_ptr_value; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + public: + _Inclusive_between (pointer __ptr) : _M_ptr_value(__ptr) { } + bool operator () (_Block_pair __bp) const throw () + { + if (std::less_equal ()(_M_ptr_value, __bp.second) && + std::greater_equal ()(_M_ptr_value, __bp.first)) + return true; + else + return false; + } + }; + + //Used to pass a Functor to functions by reference. + template + class _Functor_Ref : + public std::unary_function { + _Functor& _M_fref; + + public: + typedef typename _Functor::argument_type argument_type; + typedef typename _Functor::result_type result_type; + + _Functor_Ref (_Functor& __fref) : _M_fref(__fref) { } + result_type operator() (argument_type __arg) { return _M_fref (__arg); } + }; + + + //T should be a pointer type, and A is the Allocator for the vector. + template + class _Ffit_finder + : public std::unary_function, bool> { + typedef typename std::vector, _Alloc> _BPVector; + typedef typename _BPVector::difference_type _Counter_type; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + unsigned int *_M_pbitmap; + unsigned int _M_data_offset; + + public: + _Ffit_finder () + : _M_pbitmap (0), _M_data_offset (0) + { } + + bool operator() (_Block_pair __bp) throw() + { + //Set the _rover to the last unsigned integer, which is the + //bitmap to the first free block. Thus, the bitmaps are in exact + //reverse order of the actual memory layout. So, we count down + //the bimaps, which is the same as moving up the memory. + + //If the used count stored at the start of the Bit Map headers + //is equal to the number of Objects that the current Block can + //store, then there is definitely no space for another single + //object, so just return false. + _Counter_type __diff = __gnu_cxx::__aux_balloc::__balloc_num_bit_maps (__bp); + + assert (*(reinterpret_cast(__bp.first) - (__diff + 1)) <= + __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)); + + if (*(reinterpret_cast(__bp.first) - (__diff + 1)) == + __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)) + return false; + + unsigned int *__rover = reinterpret_cast(__bp.first) - 1; + for (_Counter_type __i = 0; __i < __diff; ++__i) + { + _M_data_offset = __i; + if (*__rover) + { + _M_pbitmap = __rover; + return true; + } + --__rover; + } + return false; + } + + unsigned int *_M_get () { return _M_pbitmap; } + unsigned int _M_offset () { return _M_data_offset * _Bits_Per_Block; } + }; + + //T should be a pointer type. + template + class _Bit_map_counter { + + typedef typename std::vector, _Alloc> _BPVector; + typedef typename _BPVector::size_type _Index_type; + typedef _Tp pointer; + + _BPVector& _M_vbp; + unsigned int *_M_curr_bmap; + unsigned int *_M_last_bmap_in_block; + _Index_type _M_curr_index; + + public: + //Use the 2nd parameter with care. Make sure that such an entry + //exists in the vector before passing that particular index to + //this ctor. + _Bit_map_counter (_BPVector& Rvbp, int __index = -1) + : _M_vbp(Rvbp) + { + this->_M_reset(__index); + } + + void _M_reset (int __index = -1) throw() + { + if (__index == -1) + { + _M_curr_bmap = 0; + _M_curr_index = (_Index_type)-1; + return; + } + + _M_curr_index = __index; + _M_curr_bmap = reinterpret_cast(_M_vbp[_M_curr_index].first) - 1; + + assert (__index <= (int)_M_vbp.size() - 1); + + _M_last_bmap_in_block = _M_curr_bmap - + ((_M_vbp[_M_curr_index].second - _M_vbp[_M_curr_index].first + 1) / _Bits_Per_Block - 1); + } + + //Dangerous Function! Use with extreme care. Pass to this + //function ONLY those values that are known to be correct, + //otherwise this will mess up big time. + void _M_set_internal_bit_map (unsigned int *__new_internal_marker) throw() + { + _M_curr_bmap = __new_internal_marker; + } + + bool _M_finished () const throw() + { + return (_M_curr_bmap == 0); + } + + _Bit_map_counter& operator++ () throw() + { + if (_M_curr_bmap == _M_last_bmap_in_block) + { + if (++_M_curr_index == _M_vbp.size()) + { + _M_curr_bmap = 0; + } + else + { + this->_M_reset (_M_curr_index); + } + } + else + { + --_M_curr_bmap; + } + return *this; + } + + unsigned int *_M_get () + { + return _M_curr_bmap; + } + + pointer _M_base () { return _M_vbp[_M_curr_index].first; } + unsigned int _M_offset () + { + return _Bits_Per_Block * ((reinterpret_cast(this->_M_base()) - _M_curr_bmap) - 1); + } + + unsigned int _M_where () { return _M_curr_index; } + }; + } + + //Generic Version of the bsf instruction. + typedef unsigned int _Bit_map_type; + static inline unsigned int _Bit_scan_forward (register _Bit_map_type __num) + { + return static_cast(__builtin_ctz(__num)); + } + + struct _OOM_handler { + static std::new_handler _S_old_handler; + static bool _S_handled_oom; + typedef void (*_FL_clear_proc)(void); + static _FL_clear_proc _S_oom_fcp; + + _OOM_handler (_FL_clear_proc __fcp) + { + _S_oom_fcp = __fcp; + _S_old_handler = std::set_new_handler (_S_handle_oom_proc); + _S_handled_oom = false; + } + + static void _S_handle_oom_proc() + { + _S_oom_fcp(); + std::set_new_handler (_S_old_handler); + _S_handled_oom = true; + } + + ~_OOM_handler () + { + if (!_S_handled_oom) + std::set_new_handler (_S_old_handler); + } + }; + + std::new_handler _OOM_handler::_S_old_handler; + bool _OOM_handler::_S_handled_oom = false; + _OOM_handler::_FL_clear_proc _OOM_handler::_S_oom_fcp = 0; + + + class _BA_free_list_store { + struct _LT_pointer_compare { + template + bool operator() (_Tp* __pt, _Tp const& __crt) const throw() + { + return *__pt < __crt; + } + }; + +#if defined __GTHREADS + static _Mutex _S_bfl_mutex; +#endif + static std::vector _S_free_list; + typedef std::vector::iterator _FLIter; + + static void _S_validate_free_list(unsigned int *__addr) throw() + { + const unsigned int __max_size = 64; + if (_S_free_list.size() >= __max_size) + { + //Ok, the threshold value has been reached. + //We determine which block to remove from the list of free + //blocks. + if (*__addr >= *_S_free_list.back()) + { + //Ok, the new block is greater than or equal to the last + //block in the list of free blocks. We just free the new + //block. + operator delete((void*)__addr); + return; + } + else + { + //Deallocate the last block in the list of free lists, and + //insert the new one in it's correct position. + operator delete((void*)_S_free_list.back()); + _S_free_list.pop_back(); + } + } + + //Just add the block to the list of free lists + //unconditionally. + _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), + *__addr, _LT_pointer_compare ()); + //We may insert the new free list before _temp; + _S_free_list.insert(__temp, __addr); + } + + static bool _S_should_i_give(unsigned int __block_size, unsigned int __required_size) throw() + { + const unsigned int __max_wastage_percentage = 36; + if (__block_size >= __required_size && + (((__block_size - __required_size) * 100 / __block_size) < __max_wastage_percentage)) + return true; + else + return false; + } + + public: + typedef _BA_free_list_store _BFL_type; + + static inline void _S_insert_free_list(unsigned int *__addr) throw() + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + //Call _S_validate_free_list to decide what should be done with this + //particular free list. + _S_validate_free_list(--__addr); + } + + static unsigned int *_S_get_free_list(unsigned int __sz) throw (std::bad_alloc) + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), + __sz, _LT_pointer_compare()); + if (__temp == _S_free_list.end() || !_S_should_i_give (**__temp, __sz)) + { + //We hold the lock because the OOM_Handler is a stateless + //entity. + _OOM_handler __set_handler(_BFL_type::_S_clear); + unsigned int *__ret_val = reinterpret_cast + (operator new (__sz + sizeof(unsigned int))); + *__ret_val = __sz; + return ++__ret_val; + } + else + { + unsigned int* __ret_val = *__temp; + _S_free_list.erase (__temp); + return ++__ret_val; + } + } + + //This function just clears the internal Free List, and gives back + //all the memory to the OS. + static void _S_clear() + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + _FLIter __iter = _S_free_list.begin(); + while (__iter != _S_free_list.end()) + { + operator delete((void*)*__iter); + ++__iter; + } + _S_free_list.clear(); + } + + }; + +#if defined __GTHREADS + _Mutex _BA_free_list_store::_S_bfl_mutex; +#endif + std::vector _BA_free_list_store::_S_free_list; + + template class bitmap_allocator; + // specialize for void: + template <> class bitmap_allocator { + public: + typedef void* pointer; + typedef const void* const_pointer; + // reference-to-void members are impossible. + typedef void value_type; + template struct rebind { typedef bitmap_allocator<_Tp1> other; }; + }; + + template class bitmap_allocator : private _BA_free_list_store { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + template struct rebind { typedef bitmap_allocator<_Tp1> other; }; + + private: + static const unsigned int _Bits_Per_Byte = 8; + static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + + static inline void _S_bit_allocate(unsigned int *__pbmap, unsigned int __pos) throw() + { + unsigned int __mask = 1 << __pos; + __mask = ~__mask; + *__pbmap &= __mask; + } + + static inline void _S_bit_free(unsigned int *__pbmap, unsigned int __pos) throw() + { + unsigned int __mask = 1 << __pos; + *__pbmap |= __mask; + } + + static inline void *_S_memory_get(size_t __sz) throw (std::bad_alloc) + { + return operator new(__sz); + } + + static inline void _S_memory_put(void *__vptr) throw () + { + operator delete(__vptr); + } + + typedef typename std::pair _Block_pair; + typedef typename __gnu_cxx::new_allocator<_Block_pair> _BPVec_allocator_type; + typedef typename std::vector<_Block_pair, _BPVec_allocator_type> _BPVector; + + +#if defined CHECK_FOR_ERRORS + //Complexity: O(lg(N)). Where, N is the number of block of size + //sizeof(value_type). + static void _S_check_for_free_blocks() throw() + { + typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); + assert(__bpi == _S_mem_blocks.end()); + } +#endif + + + //Complexity: O(1), but internally depends upon the complexity of + //the function _BA_free_list_store::_S_get_free_list. The part + //where the bitmap headers are written is of worst case complexity: + //O(X),where X is the number of blocks of size sizeof(value_type) + //within the newly acquired block. Having a tight bound. + static void _S_refill_pool() throw (std::bad_alloc) + { +#if defined CHECK_FOR_ERRORS + _S_check_for_free_blocks(); +#endif + + const unsigned int __num_bit_maps = _S_block_size / _Bits_Per_Block; + const unsigned int __size_to_allocate = sizeof(unsigned int) + + _S_block_size * sizeof(value_type) + __num_bit_maps*sizeof(unsigned int); + + unsigned int *__temp = + reinterpret_cast(_BA_free_list_store::_S_get_free_list(__size_to_allocate)); + *__temp = 0; + ++__temp; + + //The Header information goes at the Beginning of the Block. + _Block_pair __bp = std::make_pair(reinterpret_cast(__temp + __num_bit_maps), + reinterpret_cast(__temp + __num_bit_maps) + + _S_block_size - 1); + + //Fill the Vector with this information. + _S_mem_blocks.push_back(__bp); + + unsigned int __bit_mask = 0; //0 Indicates all Allocated. + __bit_mask = ~__bit_mask; //1 Indicates all Free. + + for (unsigned int __i = 0; __i < __num_bit_maps; ++__i) + __temp[__i] = __bit_mask; + + //On some implementations, operator new might throw bad_alloc, or + //malloc might fail if the size passed is too large, therefore, we + //limit the size passed to malloc or operator new. + _S_block_size *= 2; + } + + static _BPVector _S_mem_blocks; + static unsigned int _S_block_size; + static __gnu_cxx::__aux_balloc::_Bit_map_counter _S_last_request; + static typename _BPVector::size_type _S_last_dealloc_index; +#if defined __GTHREADS + static _Mutex _S_mut; +#endif + + //Complexity: Worst case complexity is O(N), but that is hardly ever + //hit. if and when this particular case is encountered, the next few + //cases are guaranteed to have a worst case complexity of O(1)! + //That's why this function performs very well on the average. you + //can consider this function to be having a complexity refrred to + //commonly as: Amortized Constant time. + static pointer _S_allocate_single_object() + { +#if defined __GTHREADS + _Lock __bit_lock(&_S_mut); +#endif + + //The algorithm is something like this: The last_requst variable + //points to the last accessed Bit Map. When such a condition + //occurs, we try to find a free block in the current bitmap, or + //succeeding bitmaps until the last bitmap is reached. If no free + //block turns up, we resort to First Fit method. + + //WARNING: Do not re-order the condition in the while statement + //below, because it relies on C++'s short-circuit + //evaluation. The return from _S_last_request->_M_get() will NOT + //be dereferenceable if _S_last_request->_M_finished() returns + //true. This would inevitibly lead to a NULL pointer dereference + //if tinkered with. + while (_S_last_request._M_finished() == false && (*(_S_last_request._M_get()) == 0)) + { + _S_last_request.operator++(); + } + + if (__builtin_expect(_S_last_request._M_finished() == true, false)) + { + //Fall Back to First Fit algorithm. + typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); + + if (__bpi != _S_mem_blocks.end()) + { + //Search was successful. Ok, now mark the first bit from + //the right as 0, meaning Allocated. This bit is obtained + //by calling _M_get() on __fff. + unsigned int __nz_bit = _Bit_scan_forward(*__fff._M_get()); + _S_bit_allocate(__fff._M_get(), __nz_bit); + + _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); + + //Now, get the address of the bit we marked as allocated. + pointer __ret_val = __bpi->first + __fff._M_offset() + __nz_bit; + unsigned int *__puse_count = reinterpret_cast(__bpi->first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(*__bpi) + 1); + ++(*__puse_count); + return __ret_val; + } + else + { + //Search was unsuccessful. We Add more memory to the pool + //by calling _S_refill_pool(). + _S_refill_pool(); + + //_M_Reset the _S_last_request structure to the first free + //block's bit map. + _S_last_request._M_reset(_S_mem_blocks.size() - 1); + + //Now, mark that bit as allocated. + } + } + //_S_last_request holds a pointer to a valid bit map, that points + //to a free block in memory. + unsigned int __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); + _S_bit_allocate(_S_last_request._M_get(), __nz_bit); + + pointer __ret_val = _S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit; + + unsigned int *__puse_count = reinterpret_cast + (_S_mem_blocks[_S_last_request._M_where()].first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[_S_last_request._M_where()]) + 1); + ++(*__puse_count); + return __ret_val; + } + + //Complexity: O(lg(N)), but the worst case is hit quite often! I + //need to do something about this. I'll be able to work on it, only + //when I have some solid figures from a few real apps. + static void _S_deallocate_single_object(pointer __p) throw() + { +#if defined __GTHREADS + _Lock __bit_lock(&_S_mut); +#endif + + typedef typename _BPVector::iterator _Iterator; + typedef typename _BPVector::difference_type _Difference_type; + + _Difference_type __diff; + int __displacement; + + assert(_S_last_dealloc_index >= 0); + + if (__gnu_cxx::__aux_balloc::_Inclusive_between(__p)(_S_mem_blocks[_S_last_dealloc_index])) + { + assert(_S_last_dealloc_index <= _S_mem_blocks.size() - 1); + + //Initial Assumption was correct! + __diff = _S_last_dealloc_index; + __displacement = __p - _S_mem_blocks[__diff].first; + } + else + { + _Iterator _iter = (std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Inclusive_between(__p))); + assert(_iter != _S_mem_blocks.end()); + + __diff = _iter - _S_mem_blocks.begin(); + __displacement = __p - _S_mem_blocks[__diff].first; + _S_last_dealloc_index = __diff; + } + + //Get the position of the iterator that has been found. + const unsigned int __rotate = __displacement % _Bits_Per_Block; + unsigned int *__bit_mapC = reinterpret_cast(_S_mem_blocks[__diff].first) - 1; + __bit_mapC -= (__displacement / _Bits_Per_Block); + + _S_bit_free(__bit_mapC, __rotate); + unsigned int *__puse_count = reinterpret_cast + (_S_mem_blocks[__diff].first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[__diff]) + 1); + + assert(*__puse_count != 0); + + --(*__puse_count); + + if (__builtin_expect(*__puse_count == 0, false)) + { + _S_block_size /= 2; + + //We may safely remove this block. + _Block_pair __bp = _S_mem_blocks[__diff]; + _S_insert_free_list(__puse_count); + _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); + + //We reset the _S_last_request variable to reflect the erased + //block. We do this to protect future requests after the last + //block has been removed from a particular memory Chunk, + //which in turn has been returned to the free list, and + //hence had been erased from the vector, so the size of the + //vector gets reduced by 1. + if ((_Difference_type)_S_last_request._M_where() >= __diff--) + { + _S_last_request._M_reset(__diff); + // assert(__diff >= 0); + } + + //If the Index into the vector of the region of memory that + //might hold the next address that will be passed to + //deallocated may have been invalidated due to the above + //erase procedure being called on the vector, hence we try + //to restore this invariant too. + if (_S_last_dealloc_index >= _S_mem_blocks.size()) + { + _S_last_dealloc_index =(__diff != -1 ? __diff : 0); + assert(_S_last_dealloc_index >= 0); + } + } + } + + public: + bitmap_allocator() throw() + { } + + bitmap_allocator(const bitmap_allocator&) { } + + template bitmap_allocator(const bitmap_allocator<_Tp1>&) throw() + { } + + ~bitmap_allocator() throw() + { } + + //Complexity: O(1), but internally the complexity depends upon the + //complexity of the function(s) _S_allocate_single_object and + //_S_memory_get. + pointer allocate(size_type __n) + { + if (__builtin_expect(__n == 1, true)) + return _S_allocate_single_object(); + else + return reinterpret_cast(_S_memory_get(__n * sizeof(value_type))); + } + + //Complexity: Worst case complexity is O(N) where N is the number of + //blocks of size sizeof(value_type) within the free lists that the + //allocator holds. However, this worst case is hit only when the + //user supplies a bogus argument to hint. If the hint argument is + //sensible, then the complexity drops to O(lg(N)), and in extreme + //cases, even drops to as low as O(1). So, if the user supplied + //argument is good, then this function performs very well. + pointer allocate(size_type __n, typename bitmap_allocator::const_pointer) + { + return allocate(__n); + } + + void deallocate(pointer __p, size_type __n) throw() + { + if (__builtin_expect(__n == 1, true)) + _S_deallocate_single_object(__p); + else + _S_memory_put(__p); + } + + pointer address(reference r) const { return &r; } + const_pointer address(const_reference r) const { return &r; } + + size_type max_size(void) const throw() { return (size_type()-1)/sizeof(value_type); } + + void construct (pointer p, const_reference __data) + { + ::new(p) value_type(__data); + } + + void destroy (pointer p) + { + p->~value_type(); + } + + }; + + template + typename bitmap_allocator<_Tp>::_BPVector bitmap_allocator<_Tp>::_S_mem_blocks; + + template + unsigned int bitmap_allocator<_Tp>::_S_block_size = bitmap_allocator<_Tp>::_Bits_Per_Block; + + template + typename __gnu_cxx::bitmap_allocator<_Tp>::_BPVector::size_type + bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; + + template + __gnu_cxx::__aux_balloc::_Bit_map_counter + ::pointer, typename bitmap_allocator<_Tp>::_BPVec_allocator_type> + bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); + +#if defined __GTHREADS + template + __gnu_cxx::_Mutex + bitmap_allocator<_Tp>::_S_mut; +#endif + + template + bool operator== (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() + { + return true; + } + + template + bool operator!= (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() + { + return false; + } +} + + +#endif //_BITMAP_ALLOCATOR_H diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/debug_allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/debug_allocator.h new file mode 100644 index 00000000000..7ea6fb42f98 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/debug_allocator.h @@ -0,0 +1,121 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/debug_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ + +#ifndef _DEBUG_ALLOCATOR_H +#define _DEBUG_ALLOCATOR_H 1 + +#include + +namespace __gnu_cxx +{ + /** + * @brief A meta-allocator with debugging bits, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * (See @link Allocators allocators info @endlink for more.) + */ + template + class debug_allocator + { + public: + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::value_type value_type; + + private: + // _M_extra is the number of objects that correspond to the + // extra space where debug information is stored. + size_type _M_extra; + + _Alloc _M_allocator; + + public: + debug_allocator() + { + const size_t __obj_size = sizeof(value_type); + _M_extra = (sizeof(size_type) + __obj_size - 1) / __obj_size; + } + + pointer + allocate(size_type __n) + { + pointer __res = _M_allocator.allocate(__n + _M_extra); + size_type* __ps = reinterpret_cast(__res); + *__ps = __n; + return __res + _M_extra; + } + + pointer + allocate(size_type __n, const void* __hint) + { + pointer __res = _M_allocator.allocate(__n + _M_extra, __hint); + size_type* __ps = reinterpret_cast(__res); + *__ps = __n; + return __res + _M_extra; + } + + void + deallocate(pointer __p, size_type __n) + { + if (!__p) + abort(); + pointer __real_p = __p - _M_extra; + if (*reinterpret_cast(__real_p) != __n) + abort(); + _M_allocator.deallocate(__real_p, __n + _M_extra); + } + }; +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/enc_filebuf.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/enc_filebuf.h new file mode 100644 index 00000000000..39f4ef724d1 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/enc_filebuf.h @@ -0,0 +1,68 @@ +// filebuf with __enc_traits state type -*- C++ -*- + +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +namespace __gnu_cxx +{ + // Custom traits type with __enc_traits for the state type, and the + // associated fpos<__enc_traits> for the position type, all other + // bits equivalent to the required char_traits instantiations. + template + struct enc_char_traits: public std::char_traits<_CharT> + { + typedef std::__enc_traits state_type; + typedef typename std::fpos pos_type; + }; + + template + class enc_filebuf + : public std::basic_filebuf<_CharT, enc_char_traits<_CharT> > + { + public: + typedef enc_char_traits<_CharT> traits_type; + typedef typename traits_type::state_type state_type; + typedef typename traits_type::pos_type pos_type; + + enc_filebuf(state_type& __state) + : std::basic_filebuf<_CharT, enc_char_traits<_CharT> >() + { + this->_M_state_beg = __state; + this->_M_state_beg._M_init(); + } + + private: + // concept requirements: + // Set state type to something useful. + // Something more than copyconstructible is needed here, so + // require default and copy constructible + assignment operator. + __glibcxx_class_requires(state_type, _SGIAssignableConcept) + }; +} // namespace __gnu_cxx diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/functional b/reactos/tools/ppc-build/core-headers/g++-v3/ext/functional new file mode 100644 index 00000000000..1a378173177 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/functional @@ -0,0 +1,395 @@ +// Functional extensions -*- C++ -*- + +// Copyright (C) 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/functional + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _EXT_FUNCTIONAL +#define _EXT_FUNCTIONAL 1 + +#pragma GCC system_header + +#include + +namespace __gnu_cxx +{ +using std::unary_function; +using std::binary_function; +using std::mem_fun1_t; +using std::const_mem_fun1_t; +using std::mem_fun1_ref_t; +using std::const_mem_fun1_ref_t; + +/** The @c identity_element functions are not part of the C++ standard; SGI + * provided them as an extension. Its argument is an operation, and its + * return value is the identity element for that operation. It is overloaded + * for addition and multiplication, and you can overload it for your own + * nefarious operations. + * + * @addtogroup SGIextensions + * @{ +*/ +/// An \link SGIextensions SGI extension \endlink. +template inline _Tp identity_element(std::plus<_Tp>) { + return _Tp(0); +} +/// An \link SGIextensions SGI extension \endlink. +template inline _Tp identity_element(std::multiplies<_Tp>) { + return _Tp(1); +} +/** @} */ + +/** As an extension to the binders, SGI provided composition functors and + * wrapper functions to aid in their creation. The @c unary_compose + * functor is constructed from two functions/functors, @c f and @c g. + * Calling @c operator() with a single argument @c x returns @c f(g(x)). + * The function @c compose1 takes the two functions and constructs a + * @c unary_compose variable for you. + * + * @c binary_compose is constructed from three functors, @c f, @c g1, + * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function + * @compose2 takes f, g1, and g2, and constructs the @c binary_compose + * instance for you. For example, if @c f returns an int, then + * \code + * int answer = (compose2(f,g1,g2))(x); + * \endcode + * is equivalent to + * \code + * int temp1 = g1(x); + * int temp2 = g2(x); + * int answer = f(temp1,temp2); + * \endcode + * But the first form is more compact, and can be passed around as a + * functor to other algorithms. + * + * @addtogroup SGIextensions + * @{ +*/ +/// An \link SGIextensions SGI extension \endlink. +template +class unary_compose + : public unary_function +{ +protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; +public: + unary_compose(const _Operation1& __x, const _Operation2& __y) + : _M_fn1(__x), _M_fn2(__y) {} + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_fn1(_M_fn2(__x)); + } +}; + +/// An \link SGIextensions SGI extension \endlink. +template +inline unary_compose<_Operation1,_Operation2> +compose1(const _Operation1& __fn1, const _Operation2& __fn2) +{ + return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); +} + +/// An \link SGIextensions SGI extension \endlink. +template +class binary_compose + : public unary_function { +protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + _Operation3 _M_fn3; +public: + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_fn1(_M_fn2(__x), _M_fn3(__x)); + } +}; + +/// An \link SGIextensions SGI extension \endlink. +template +inline binary_compose<_Operation1, _Operation2, _Operation3> +compose2(const _Operation1& __fn1, const _Operation2& __fn2, + const _Operation3& __fn3) +{ + return binary_compose<_Operation1,_Operation2,_Operation3> + (__fn1, __fn2, __fn3); +} +/** @} */ + +/** As an extension, SGI provided a functor called @c identity. When a + * functor is required but no operations are desired, this can be used as a + * pass-through. Its @c operator() returns its argument unchanged. + * + * @addtogroup SGIextensions +*/ +template struct identity : public std::_Identity<_Tp> {}; + +/** @c select1st and @c select2nd are extensions provided by SGI. Their + * @c operator()s + * take a @c std::pair as an argument, and return either the first member + * or the second member, respectively. They can be used (especially with + * the composition functors) to "strip" data from a sequence before + * performing the remainder of an algorithm. + * + * @addtogroup SGIextensions + * @{ +*/ +/// An \link SGIextensions SGI extension \endlink. +template struct select1st : public std::_Select1st<_Pair> {}; +/// An \link SGIextensions SGI extension \endlink. +template struct select2nd : public std::_Select2nd<_Pair> {}; +/** @} */ + +// extension documented next +template +struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { + _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } +}; + +template +struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { + _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } +}; + +/** The @c operator() of the @c project1st functor takes two arbitrary + * arguments and returns the first one, while @c project2nd returns the + * second one. They are extensions provided by SGI. + * + * @addtogroup SGIextensions + * @{ +*/ + +/// An \link SGIextensions SGI extension \endlink. +template +struct project1st : public _Project1st<_Arg1, _Arg2> {}; + +/// An \link SGIextensions SGI extension \endlink. +template +struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; +/** @} */ + +// extension documented next +template +struct _Constant_void_fun { + typedef _Result result_type; + result_type _M_val; + + _Constant_void_fun(const result_type& __v) : _M_val(__v) {} + const result_type& operator()() const { return _M_val; } +}; + +template +struct _Constant_unary_fun { + typedef _Argument argument_type; + typedef _Result result_type; + result_type _M_val; + + _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} + const result_type& operator()(const _Argument&) const { return _M_val; } +}; + +template +struct _Constant_binary_fun { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + _Result _M_val; + + _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} + const result_type& operator()(const _Arg1&, const _Arg2&) const { + return _M_val; + } +}; + +/** These three functors are each constructed from a single arbitrary + * variable/value. Later, their @c operator()s completely ignore any + * arguments passed, and return the stored value. + * - @c constant_void_fun's @c operator() takes no arguments + * - @c constant_unary_fun's @c operator() takes one argument (ignored) + * - @c constant_binary_fun's @c operator() takes two arguments (ignored) + * + * The helper creator functions @c constant0, @c constant1, and + * @c constant2 each take a "result" argument and construct variables of + * the appropriate functor type. + * + * @addtogroup SGIextensions + * @{ +*/ +/// An \link SGIextensions SGI extension \endlink. +template +struct constant_void_fun : public _Constant_void_fun<_Result> { + constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} +}; + +/// An \link SGIextensions SGI extension \endlink. +template +struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> +{ + constant_unary_fun(const _Result& __v) + : _Constant_unary_fun<_Result, _Argument>(__v) {} +}; + +/// An \link SGIextensions SGI extension \endlink. +template +struct constant_binary_fun + : public _Constant_binary_fun<_Result, _Arg1, _Arg2> +{ + constant_binary_fun(const _Result& __v) + : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} +}; + +/// An \link SGIextensions SGI extension \endlink. +template +inline constant_void_fun<_Result> constant0(const _Result& __val) +{ + return constant_void_fun<_Result>(__val); +} + +/// An \link SGIextensions SGI extension \endlink. +template +inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) +{ + return constant_unary_fun<_Result,_Result>(__val); +} + +/// An \link SGIextensions SGI extension \endlink. +template +inline constant_binary_fun<_Result,_Result,_Result> +constant2(const _Result& __val) +{ + return constant_binary_fun<_Result,_Result,_Result>(__val); +} +/** @} */ + +/** The @c subtractive_rng class is documented on + * SGI's site. + * Note that this code assumes that @c int is 32 bits. + * + * @ingroup SGIextensions +*/ +class subtractive_rng : public unary_function { +private: + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_index2; +public: + /// Returns a number less than the argument. + unsigned int operator()(unsigned int __limit) { + _M_index1 = (_M_index1 + 1) % 55; + _M_index2 = (_M_index2 + 1) % 55; + _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; + return _M_table[_M_index1] % __limit; + } + + void _M_initialize(unsigned int __seed) + { + unsigned int __k = 1; + _M_table[54] = __seed; + size_t __i; + for (__i = 0; __i < 54; __i++) { + size_t __ii = (21 * (__i + 1) % 55) - 1; + _M_table[__ii] = __k; + __k = __seed - __k; + __seed = _M_table[__ii]; + } + for (int __loop = 0; __loop < 4; __loop++) { + for (__i = 0; __i < 55; __i++) + _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; + } + _M_index1 = 0; + _M_index2 = 31; + } + + /// Ctor allowing you to initialize the seed. + subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } + /// Default ctor; initializes its state with some number you don't see. + subtractive_rng() { _M_initialize(161803398u); } +}; + +// Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, +// provided for backward compatibility, they are no longer part of +// the C++ standard. + +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } +} // namespace __gnu_cxx + +#endif + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_fun.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_fun.h new file mode 100644 index 00000000000..27453a6b006 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_fun.h @@ -0,0 +1,122 @@ +// 'struct hash' from SGI -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_fun.h + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _HASH_FUN_H +#define _HASH_FUN_H 1 + +#include + +namespace __gnu_cxx +{ + using std::size_t; + + template struct hash { }; + + inline size_t + __stl_hash_string(const char* __s) + { + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5*__h + *__s; + return size_t(__h); + } + + template<> struct hash + { + size_t operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> struct hash + { + size_t operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> struct hash + { size_t operator()(char __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(unsigned char __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(unsigned char __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(short __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(unsigned short __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(int __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(unsigned int __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(long __x) const { return __x; } }; + + template<> struct hash + { size_t operator()(unsigned long __x) const { return __x; } }; +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_map b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_map new file mode 100644 index 00000000000..5032c7b3f21 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_map @@ -0,0 +1,447 @@ +// Hashing map implementation -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_map + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _HASH_MAP +#define _HASH_MAP 1 + +#include +#include + +namespace __gnu_cxx +{ + using std::equal_to; + using std::allocator; + using std::pair; + using std::_Select1st; + + // Forward declaration of equality operator; needed for friend + // declaration. + template, + class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > + class hash_map; + + template + inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, + const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template +class hash_map +{ +private: + typedef hashtable,_Key,_HashFcn, + _Select1st >,_EqualKey,_Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_map(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } + + template + friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, + const hash_map<_K1, _T1, _HF, _EqK, _Al>&); + + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } + +public: + pair insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } + pair insert_noresize(const value_type& __obj) + { return _M_ht.insert_unique_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } + + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; + } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + return __hm1._M_ht == __hm2._M_ht; +} + +template +inline bool +operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { + return !(__hm1 == __hm2); +} + +template +inline void +swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + __hm1.swap(__hm2); +} + +// Forward declaration of equality operator; needed for friend declaration. + +template , + class _EqualKey = equal_to<_Key>, + class _Alloc = allocator<_Tp> > +class hash_multimap; + +template +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); + +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template +class hash_multimap +{ + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Key, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) + +private: + typedef hashtable, _Key, _HashFcn, + _Select1st >, _EqualKey, _Alloc> + _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multimap(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } + + template + friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, + const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); + + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } + +public: + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) +{ + return __hm1._M_ht == __hm2._M_ht; +} + +template +inline bool +operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { + return !(__hm1 == __hm2); +} + +template +inline void +swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + __hm1.swap(__hm2); +} + +} // namespace __gnu_cxx + +namespace std +{ +// Specialization of insert_iterator so that it will work for hash_map +// and hash_multimap. + +template +class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { +protected: + typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +template +class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { +protected: + typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_set b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_set new file mode 100644 index 00000000000..fee64fcbdb0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hash_set @@ -0,0 +1,439 @@ +// Hashing set implementation -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_set + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _HASH_SET +#define _HASH_SET 1 + +#include +#include + +namespace __gnu_cxx +{ + using std::equal_to; + using std::allocator; + using std::pair; + using std::_Identity; + + // Forward declaration of equality operator; needed for friend + // declaration. + template , + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > + class hash_set; + + template + inline bool + operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); + +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template +class hash_set +{ + // concept requirements + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) + +private: + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_set() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_set(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } + + template + friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, + const hash_set<_Val, _HF, _EqK, _Al>&); + + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } + +public: + pair insert(const value_type& __obj) + { + pair __p = _M_ht.insert_unique(__obj); + return pair(__p.first, __p.second); + } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } + pair insert_noresize(const value_type& __obj) + { + pair __p = + _M_ht.insert_unique_noresize(__obj); + return pair(__p.first, __p.second); + } + + iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + return __hs1._M_ht == __hs2._M_ht; +} + +template +inline bool +operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { + return !(__hs1 == __hs2); +} + +template +inline void +swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + __hs1.swap(__hs2); +} + + +template , + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > +class hash_multiset; + +template +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); + + +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template +class hash_multiset +{ + // concept requirements + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) + +private: + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + +public: + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + +public: + hash_multiset() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multiset(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} + + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } + + template + friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, + const hash_multiset<_Val, _HF, _EqK, _Al>&); + + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } + +public: + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + pair equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +public: + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + return __hs1._M_ht == __hs2._M_ht; +} + +template +inline bool +operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + return !(__hs1 == __hs2); +} + +template +inline void +swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + __hs1.swap(__hs2); +} + +} // namespace __gnu_cxx + +namespace std +{ +// Specialization of insert_iterator so that it will work for hash_set +// and hash_multiset. + +template +class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { +protected: + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Container; + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +template +class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { +protected: + typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->insert(__value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/hashtable.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hashtable.h new file mode 100644 index 00000000000..f81a8580b15 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/hashtable.h @@ -0,0 +1,994 @@ +// Hashtable implementation used by containers -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hashtable.h + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _HASHTABLE_H +#define _HASHTABLE_H 1 + +// Hashtable class, used to implement the hashed associative containers +// hash_set, hash_map, hash_multiset, and hash_multimap. + +#include +#include +#include +#include +#include + +namespace __gnu_cxx +{ +using std::size_t; +using std::ptrdiff_t; +using std::forward_iterator_tag; +using std::input_iterator_tag; +using std::_Construct; +using std::_Destroy; +using std::distance; +using std::vector; +using std::pair; +using std::__iterator_category; + +template +struct _Hashtable_node +{ + _Hashtable_node* _M_next; + _Val _M_val; +}; + +template > +class hashtable; + +template +struct _Hashtable_iterator; + +template +struct _Hashtable_const_iterator; + +template +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_iterator() {} + reference operator*() const { return _M_cur->_M_val; } + pointer operator->() const { return &(operator*()); } + iterator& operator++(); + iterator operator++(int); + bool operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + + +template +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_const_iterator() {} + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} + reference operator*() const { return _M_cur->_M_val; } + pointer operator->() const { return &(operator*()); } + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + +// Note: assumes long is at least 32 bits. +enum { _S_num_primes = 28 }; + +static const unsigned long __stl_prime_list[_S_num_primes] = +{ + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul +}; + +inline unsigned long __stl_next_prime(unsigned long __n) +{ + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; + const unsigned long* pos = std::lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; +} + +// Forward declaration of operator==. + +template +class hashtable; + +template +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); + + +// Hashtables handle allocators a bit differently than other +// containers do. If we're using standard-conforming allocators, then +// a hashtable unconditionally has a member variable to hold its +// allocator, even if it so happens that all instances of the +// allocator type are identical. This is because, for hashtables, +// this extra storage is negligible. Additionally, a base class +// wouldn't serve any other purposes; it wouldn't, for example, +// simplify the exception-handling code. + +template +class hashtable { +public: + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher hash_funct() const { return _M_hash; } + key_equal key_eq() const { return _M_equals; } + +private: + typedef _Hashtable_node<_Val> _Node; + +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } +private: + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; + + _Node_Alloc _M_node_allocator; + _Node* _M_get_node() { return _M_node_allocator.allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } + +private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + +public: + typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey, + _Alloc> + const_iterator; + + friend struct + _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; + friend struct + _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; + +public: + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(__ext), + _M_buckets(__a), + _M_num_elements(0) + { + _M_initialize_buckets(__n); + } + + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(_ExtractKey()), + _M_buckets(__a), + _M_num_elements(0) + { + _M_initialize_buckets(__n); + } + + hashtable(const hashtable& __ht) + : _M_node_allocator(__ht.get_allocator()), + _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), + _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), + _M_num_elements(0) + { + _M_copy_from(__ht); + } + + hashtable& operator= (const hashtable& __ht) + { + if (&__ht != this) { + clear(); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); + } + return *this; + } + + ~hashtable() { clear(); } + + size_type size() const { return _M_num_elements; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return size() == 0; } + + void swap(hashtable& __ht) + { + std::swap(_M_hash, __ht._M_hash); + std::swap(_M_equals, __ht._M_equals); + std::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + std::swap(_M_num_elements, __ht._M_num_elements); + } + + iterator begin() + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); + return end(); + } + + iterator end() { return iterator(0, this); } + + const_iterator begin() const + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); + return end(); + } + + const_iterator end() const { return const_iterator(0, this); } + + template + friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); +public: + + size_type bucket_count() const { return _M_buckets.size(); } + + size_type max_bucket_count() const + { return __stl_prime_list[(int)_S_num_primes - 1]; } + + size_type elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) + __result += 1; + return __result; + } + + pair insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } + + iterator insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } + + pair insert_unique_noresize(const value_type& __obj); + iterator insert_equal_noresize(const value_type& __obj); + + template + void insert_unique(_InputIterator __f, _InputIterator __l) + { + insert_unique(__f, __l, __iterator_category(__f)); + } + + template + void insert_equal(_InputIterator __f, _InputIterator __l) + { + insert_equal(__f, __l, __iterator_category(__f)); + } + + template + void insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template + void insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template + void insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + + reference find_or_insert(const value_type& __obj); + + iterator find(const key_type& __key) + { + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + {} + return iterator(__first, this); + } + + const_iterator find(const key_type& __key) const + { + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + {} + return const_iterator(__first, this); + } + + size_type count(const key_type& __key) const + { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; + } + + pair + equal_range(const key_type& __key); + + pair + equal_range(const key_type& __key) const; + + size_type erase(const key_type& __key); + void erase(const iterator& __it); + void erase(iterator __first, iterator __last); + + void erase(const const_iterator& __it); + void erase(const_iterator __first, const_iterator __last); + + void resize(size_type __num_elements_hint); + void clear(); + +private: + size_type _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } + + void _M_initialize_buckets(size_type __n) + { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; + } + + size_type _M_bkt_num_key(const key_type& __key) const + { + return _M_bkt_num_key(__key, _M_buckets.size()); + } + + size_type _M_bkt_num(const value_type& __obj) const + { + return _M_bkt_num_key(_M_get_key(__obj)); + } + + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const + { + return _M_hash(__key) % __n; + } + + size_type _M_bkt_num(const value_type& __obj, size_t __n) const + { + return _M_bkt_num_key(_M_get_key(__obj), __n); + } + + _Node* _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + try { + _Construct(&__n->_M_val, __obj); + return __n; + } + catch(...) + { + _M_put_node(__n); + __throw_exception_again; + } + } + + void _M_delete_node(_Node* __n) + { + _Destroy(&__n->_M_val); + _M_put_node(__n); + } + + void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + void _M_erase_bucket(const size_type __n, _Node* __last); + + void _M_copy_from(const hashtable& __ht); + +}; + +template +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template +inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + iterator __tmp = *this; + ++*this; + return __tmp; +} + +template +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template +inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + const_iterator __tmp = *this; + ++*this; + return __tmp; +} + +template +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) +{ + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + // Check same length of lists + for ( ; __cur1 && __cur2; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + {} + if (__cur1 || __cur2) + return false; + // Now check one's elements are in the other + for (__cur1 = __ht1._M_buckets[__n] ; __cur1; __cur1 = __cur1->_M_next) + { + bool _found__cur1 = false; + for (_Node* __cur2 = __ht2._M_buckets[__n]; + __cur2; __cur2 = __cur2->_M_next) + { + if (__cur1->_M_val == __cur2->_M_val) + { + _found__cur1 = true; + break; + } + } + if (!_found__cur1) + return false; + } + } + return true; +} + +template +inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { + return !(__ht1 == __ht2); +} + +template +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); +} + + +template +pair::iterator, bool> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_unique_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair(iterator(__tmp, this), true); +} + +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_equal_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); +} + +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) +{ + resize(_M_num_elements + 1); + + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; +} + +template +pair::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) +{ + typedef pair _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); + } + return _Pii(end(), end()); +} + +template +pair::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const +{ + typedef pair _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n] ; + __first; + __first = __first->_M_next) { + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (const _Node* __cur = __first->_M_next; + __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); + } + } + return _Pii(end(), end()); +} + +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key) +{ + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) { + if (_M_equals(_M_get_key(__next->_M_val), __key)) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; + } + } + return __erased; +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) +{ + _Node* __p = __it._M_cur; + if (__p) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else { + _Node* __next = __cur->_M_next; + while (__next) { + if (__next == __p) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; + break; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + } + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::erase(iterator __first, iterator __last) +{ + size_type __f_bucket = __first._M_cur ? + _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + size_type __l_bucket = __last._M_cur ? + _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); + + if (__first._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else { + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); + } +} + +template +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, + const_iterator __last) +{ + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast(__last._M_ht))); +} + +template +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) +{ + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast(__it._M_ht))); +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::resize(size_type __num_elements_hint) +{ + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) { + _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + try { + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { + _Node* __first = _M_buckets[__bucket]; + while (__first) { + size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; + } + } + _M_buckets.swap(__tmp); + } + catch(...) { + for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { + while (__tmp[__bucket]) { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; + } + } + __throw_exception_again; + } + } + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; + } +} + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() +{ + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; +} + + +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_copy_from(const hashtable& __ht) +{ + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + try { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) { + _Node* __local_copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __local_copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + __local_copy->_M_next = _M_new_node(__next->_M_val); + __local_copy = __local_copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + catch(...) + { + clear(); + __throw_exception_again; + } +} +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/iterator b/reactos/tools/ppc-build/core-headers/g++-v3/ext/iterator new file mode 100644 index 00000000000..094313c76e4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/iterator @@ -0,0 +1,113 @@ +// HP/SGI iterator extensions -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/iterator + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _EXT_ITERATOR +#define _EXT_ITERATOR 1 + +#pragma GCC system_header + +#include +#include + +namespace __gnu_cxx +{ + // There are two signatures for distance. In addition to the one + // taking two iterators and returning a result, there is another + // taking two iterators and a reference-to-result variable, and + // returning nothing. The latter seems to be an SGI extension. + // -- pedwards + template + inline void + __distance(_InputIterator __first, _InputIterator __last, + _Distance& __n, std::input_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + while (__first != __last) { ++__first; ++__n; } + } + + template + inline void + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Distance& __n, std::random_access_iterator_tag) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __n += __last - __first; + } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline void + distance(_InputIterator __first, _InputIterator __last, + _Distance& __n) + { + // concept requirements -- taken care of in __distance + __distance(__first, __last, __n, std::__iterator_category(__first)); + } +} // namespace __gnu_cxx + +#endif + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/malloc_allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/malloc_allocator.h new file mode 100644 index 00000000000..938380c36f6 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/malloc_allocator.h @@ -0,0 +1,118 @@ +// Allocator that wraps "C" malloc -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _MALLOC_ALLOCATOR_H +#define _MALLOC_ALLOCATOR_H 1 + +#include + +namespace __gnu_cxx +{ + /** + * @brief An allocator that uses malloc + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls malloc + * - all deallocation calls free + * + * (See @link Allocators allocators info @endlink for more.) + */ + template + class malloc_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef malloc_allocator<_Tp1> other; }; + + malloc_allocator() throw() { } + + malloc_allocator(const malloc_allocator&) throw() { } + + template + malloc_allocator(const malloc_allocator<_Tp1>&) throw() { } + + ~malloc_allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { + pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); + if (!__ret) + throw std::bad_alloc(); + return __ret; + } + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { free(static_cast(__p)); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) value_type(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template + inline bool + operator==(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) + { return false; } +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/memory b/reactos/tools/ppc-build/core-headers/g++-v3/ext/memory new file mode 100644 index 00000000000..1d93f90ac7a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/memory @@ -0,0 +1,171 @@ +// Memory extensions -*- C++ -*- + +// Copyright (C) 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/memory + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _EXT_MEMORY +#define _EXT_MEMORY 1 + +#pragma GCC system_header + +#include +#include + +namespace __gnu_cxx +{ + using std::ptrdiff_t; + using std::pair; + using std::__iterator_category; + using std::_Temporary_buffer; + + template + pair<_InputIter, _ForwardIter> + __uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result, std::input_iterator_tag) + { + _ForwardIter __cur = __result; + try + { + for ( ; __count > 0 ; --__count, ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } + catch(...) + { + std::_Destroy(__result, __cur); + __throw_exception_again; + } + } + + template + inline pair<_RandomAccessIter, _ForwardIter> + __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, + _ForwardIter __result, + std::random_access_iterator_tag) + { + _RandomAccessIter __last = __first + __count; + return pair<_RandomAccessIter, _ForwardIter>( + __last, + std::uninitialized_copy(__first, __last, __result)); + } + + template + inline pair<_InputIter, _ForwardIter> + __uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) + { + return __uninitialized_copy_n(__first, __count, __result, + __iterator_category(__first)); + } + + /** + * @brief Copies the range [first,last) into result. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return result + (first - last) + * @ingroup SGIextensions + * + * Like copy(), but does not require an initialized output range. + */ + template + inline pair<_InputIter, _ForwardIter> + uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) + { + return __uninitialized_copy_n(__first, __count, __result, + __iterator_category(__first)); + } + + + /** + * This class provides similar behavior and semantics of the standard + * functions get_temporary_buffer() and return_temporary_buffer(), but + * encapsulated in a type vaguely resembling a standard container. + * + * By default, a temporary_buffer stores space for objects of + * whatever type the Iter iterator points to. It is constructed from a + * typical [first,last) range, and provides the begin(), end(), size() + * functions, as well as requested_size(). For non-trivial types, copies + * of *first will be used to initialize the storage. + * + * @c malloc is used to obtain underlying storage. + * + * Like get_temporary_buffer(), not all the requested memory may be + * available. Ideally, the created buffer will be large enough to hold a + * copy of [first,last), but if size() is less than requested_size(), + * then this didn't happen. + * + * @ingroup SGIextensions + */ + template ::value_type > + struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> + { + /// Requests storage large enough to hold a copy of [first,last). + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } + + /// Destroys objects and frees storage. + ~temporary_buffer() { } + }; +} // namespace __gnu_cxx + +#endif + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/mt_allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/mt_allocator.h new file mode 100644 index 00000000000..f0ee2ebd26d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/mt_allocator.h @@ -0,0 +1,718 @@ +// MT-optimized allocator -*- C++ -*- + +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/mt_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ + +#ifndef _MT_ALLOCATOR_H +#define _MT_ALLOCATOR_H 1 + +#include +#include +#include +#include +#include + +namespace __gnu_cxx +{ + /** + * This is a fixed size (power of 2) allocator which - when + * compiled with thread support - will maintain one freelist per + * size per thread plus a "global" one. Steps are taken to limit + * the per thread freelist sizes (by returning excess back to + * "global"). + * + * Further details: + * http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html + */ + template + class __mt_alloc + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef __mt_alloc<_Tp1> other; }; + + __mt_alloc() throw() + { + // XXX + } + + __mt_alloc(const __mt_alloc&) throw() + { + // XXX + } + + template + __mt_alloc(const __mt_alloc<_Tp1>& obj) throw() + { + // XXX + } + + ~__mt_alloc() throw() { } + + pointer + address(reference __x) const + { return &__x; } + + const_pointer + address(const_reference __x) const + { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + + // Variables used to configure the behavior of the allocator, + // assigned and explained in detail below. + struct _Tune + { + // Alignment needed. + // NB: In any case must be >= sizeof(_Block_record), that + // is 4 on 32 bit machines and 8 on 64 bit machines. + size_t _M_align; + + // Allocation requests (after round-up to power of 2) below + // this value will be handled by the allocator. A raw new/ + // call will be used for requests larger than this value. + size_t _M_max_bytes; + + // Size in bytes of the smallest bin. + // NB: Must be a power of 2 and >= _M_align. + size_t _M_min_bin; + + // In order to avoid fragmenting and minimize the number of + // new() calls we always request new memory using this + // value. Based on previous discussions on the libstdc++ + // mailing list we have choosen the value below. + // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html + size_t _M_chunk_size; + + // The maximum number of supported threads. Our Linux 2.4.18 + // reports 4070 in /proc/sys/kernel/threads-max + size_t _M_max_threads; + + // Each time a deallocation occurs in a threaded application + // we make sure that there are no more than + // _M_freelist_headroom % of used memory on the freelist. If + // the number of additional records is more than + // _M_freelist_headroom % of the freelist, we move these + // records back to the global pool. + size_t _M_freelist_headroom; + + // Set to true forces all allocations to use new(). + bool _M_force_new; + + explicit + _Tune() + : _M_align(8), _M_max_bytes(128), _M_min_bin(8), + _M_chunk_size(4096 - 4 * sizeof(void*)), + _M_max_threads(4096), _M_freelist_headroom(10), + _M_force_new(getenv("GLIBCXX_FORCE_NEW") ? true : false) + { } + + explicit + _Tune(size_t __align, size_t __maxb, size_t __minbin, + size_t __chunk, size_t __maxthreads, size_t __headroom, + bool __force) + : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), + _M_chunk_size(__chunk), _M_max_threads(__maxthreads), + _M_freelist_headroom(__headroom), _M_force_new(__force) + { } + }; + + private: + // We need to create the initial lists and set up some variables + // before we can answer to the first request for memory. +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + static bool _S_init; + + static void + _S_initialize(); + + // Configuration options. + static _Tune _S_options; + + static const _Tune + _S_get_options() + { return _S_options; } + + static void + _S_set_options(_Tune __t) + { + if (!_S_init) + _S_options = __t; + } + + // Using short int as type for the binmap implies we are never + // caching blocks larger than 65535 with this allocator + typedef unsigned short int _Binmap_type; + static _Binmap_type* _S_binmap; + + // Each requesting thread is assigned an id ranging from 1 to + // _S_max_threads. Thread id 0 is used as a global memory pool. + // In order to get constant performance on the thread assignment + // routine, we keep a list of free ids. When a thread first + // requests memory we remove the first record in this list and + // stores the address in a __gthread_key. When initializing the + // __gthread_key we specify a destructor. When this destructor + // (i.e. the thread dies) is called, we return the thread id to + // the front of this list. +#ifdef __GTHREADS + struct _Thread_record + { + // Points to next free thread id record. NULL if last record in list. + _Thread_record* volatile _M_next; + + // Thread id ranging from 1 to _S_max_threads. + size_t _M_id; + }; + + static _Thread_record* volatile _S_thread_freelist_first; + static __gthread_mutex_t _S_thread_freelist_mutex; + static __gthread_key_t _S_thread_key; + + static void + _S_destroy_thread_key(void* __freelist_pos); +#endif + + static size_t + _S_get_thread_id(); + + union _Block_record + { + // Points to the block_record of the next free block. + _Block_record* volatile _M_next; + +#ifdef __GTHREADS + // The thread id of the thread which has requested this block. + size_t _M_thread_id; +#endif + }; + + struct _Bin_record + { + // An "array" of pointers to the first free block for each + // thread id. Memory to this "array" is allocated in _S_initialize() + // for _S_max_threads + global pool 0. + _Block_record** volatile _M_first; + +#ifdef __GTHREADS + // An "array" of counters used to keep track of the amount of + // blocks that are on the freelist/used for each thread id. + // Memory to these "arrays" is allocated in _S_initialize() for + // _S_max_threads + global pool 0. + size_t* volatile _M_free; + size_t* volatile _M_used; + + // Each bin has its own mutex which is used to ensure data + // integrity while changing "ownership" on a block. The mutex + // is initialized in _S_initialize(). + __gthread_mutex_t* _M_mutex; +#endif + }; + + // An "array" of bin_records each of which represents a specific + // power of 2 size. Memory to this "array" is allocated in + // _S_initialize(). + static _Bin_record* volatile _S_bin; + + // Actual value calculated in _S_initialize(). + static size_t _S_bin_size; + }; + + template + typename __mt_alloc<_Tp>::pointer + __mt_alloc<_Tp>:: + allocate(size_type __n, const void*) + { + // Although the test in __gthread_once() would suffice, we wrap + // test of the once condition in our own unlocked check. This + // saves one function call to pthread_once() (which itself only + // tests for the once value unlocked anyway and immediately + // returns if set) + if (!_S_init) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + __gthread_once(&_S_once, _S_initialize); +#endif + if (!_S_init) + _S_initialize(); + } + + // Requests larger than _M_max_bytes are handled by new/delete + // directly. + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > _S_options._M_max_bytes || _S_options._M_force_new) + { + void* __ret = ::operator new(__bytes); + return static_cast<_Tp*>(__ret); + } + + // Round up to power of 2 and figure out which bin to use. + const size_t __which = _S_binmap[__bytes]; + const size_t __thread_id = _S_get_thread_id(); + + // Find out if we have blocks on our freelist. If so, go ahead + // and use them directly without having to lock anything. + const _Bin_record& __bin = _S_bin[__which]; + _Block_record* __block = NULL; + if (__bin._M_first[__thread_id] == NULL) + { + // NB: For alignment reasons, we can't use the first _M_align + // bytes, even when sizeof(_Block_record) < _M_align. + const size_t __bin_size = ((_S_options._M_min_bin << __which) + + _S_options._M_align); + size_t __block_count = _S_options._M_chunk_size / __bin_size; + + // Are we using threads? + // - Yes, check if there are free blocks on the global + // list. If so, grab up to __block_count blocks in one + // lock and change ownership. If the global list is + // empty, we allocate a new chunk and add those blocks + // directly to our own freelist (with us as owner). + // - No, all operations are made directly to global pool 0 + // no need to lock or change ownership but check for free + // blocks on global list (and if not add new ones) and + // get the first one. +#ifdef __GTHREADS + if (__gthread_active_p()) + { + __gthread_mutex_lock(__bin._M_mutex); + if (__bin._M_first[0] == NULL) + { + // No need to hold the lock when we are adding a + // whole chunk to our own list. + __gthread_mutex_unlock(__bin._M_mutex); + + void* __v = ::operator new(_S_options._M_chunk_size); + __bin._M_first[__thread_id] = static_cast<_Block_record*>(__v); + __bin._M_free[__thread_id] = __block_count; + + --__block_count; + __block = __bin._M_first[__thread_id]; + while (__block_count-- > 0) + { + char* __c = reinterpret_cast(__block) + __bin_size; + __block->_M_next = reinterpret_cast<_Block_record*>(__c); + __block = __block->_M_next; + } + __block->_M_next = NULL; + } + else + { + // Is the number of required blocks greater than or + // equal to the number that can be provided by the + // global free list? + __bin._M_first[__thread_id] = __bin._M_first[0]; + if (__block_count >= __bin._M_free[0]) + { + __bin._M_free[__thread_id] = __bin._M_free[0]; + __bin._M_free[0] = 0; + __bin._M_first[0] = NULL; + } + else + { + __bin._M_free[__thread_id] = __block_count; + __bin._M_free[0] -= __block_count; + --__block_count; + __block = __bin._M_first[0]; + while (__block_count-- > 0) + __block = __block->_M_next; + __bin._M_first[0] = __block->_M_next; + __block->_M_next = NULL; + } + __gthread_mutex_unlock(__bin._M_mutex); + } + } + else +#endif + { + void* __v = ::operator new(_S_options._M_chunk_size); + __bin._M_first[0] = static_cast<_Block_record*>(__v); + + --__block_count; + __block = __bin._M_first[0]; + while (__block_count-- > 0) + { + char* __c = reinterpret_cast(__block) + __bin_size; + __block->_M_next = reinterpret_cast<_Block_record*>(__c); + __block = __block->_M_next; + } + __block->_M_next = NULL; + } + } + + __block = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next; +#ifdef __GTHREADS + if (__gthread_active_p()) + { + __block->_M_thread_id = __thread_id; + --__bin._M_free[__thread_id]; + ++__bin._M_used[__thread_id]; + } +#endif + + char* __c = reinterpret_cast(__block) + _S_options._M_align; + return static_cast<_Tp*>(static_cast(__c)); + } + + template + void + __mt_alloc<_Tp>:: + deallocate(pointer __p, size_type __n) + { + // Requests larger than _M_max_bytes are handled by operators + // new/delete directly. + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > _S_options._M_max_bytes || _S_options._M_force_new) + { + ::operator delete(__p); + return; + } + + // Round up to power of 2 and figure out which bin to use. + const size_t __which = _S_binmap[__bytes]; + const _Bin_record& __bin = _S_bin[__which]; + + char* __c = reinterpret_cast(__p) - _S_options._M_align; + _Block_record* __block = reinterpret_cast<_Block_record*>(__c); + +#ifdef __GTHREADS + if (__gthread_active_p()) + { + // Calculate the number of records to remove from our freelist: + // in order to avoid too much contention we wait until the + // number of records is "high enough". + const size_t __thread_id = _S_get_thread_id(); + + long __remove = ((__bin._M_free[__thread_id] + * _S_options._M_freelist_headroom) + - __bin._M_used[__thread_id]); + if (__remove > static_cast(100 * (_S_bin_size - __which) + * _S_options._M_freelist_headroom) + && __remove > static_cast(__bin._M_free[__thread_id])) + { + _Block_record* __tmp = __bin._M_first[__thread_id]; + _Block_record* __first = __tmp; + __remove /= _S_options._M_freelist_headroom; + const long __removed = __remove; + --__remove; + while (__remove-- > 0) + __tmp = __tmp->_M_next; + __bin._M_first[__thread_id] = __tmp->_M_next; + __bin._M_free[__thread_id] -= __removed; + + __gthread_mutex_lock(__bin._M_mutex); + __tmp->_M_next = __bin._M_first[0]; + __bin._M_first[0] = __first; + __bin._M_free[0] += __removed; + __gthread_mutex_unlock(__bin._M_mutex); + } + + // Return this block to our list and update counters and + // owner id as needed. + --__bin._M_used[__block->_M_thread_id]; + + __block->_M_next = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block; + + ++__bin._M_free[__thread_id]; + } + else +#endif + { + // Single threaded application - return to global pool. + __block->_M_next = __bin._M_first[0]; + __bin._M_first[0] = __block; + } + } + + template + void + __mt_alloc<_Tp>:: + _S_initialize() + { + // This method is called on the first allocation (when _S_init is still + // false) to create the bins. + + // Ensure that the static initialization of _S_options has + // happened. This depends on (a) _M_align == 0 being an invalid + // value that is only present at startup, and (b) the real + // static initialization that happens later not actually + // changing anything. + if (_S_options._M_align == 0) + new (&_S_options) _Tune; + + // _M_force_new must not change after the first allocate(), + // which in turn calls this method, so if it's false, it's false + // forever and we don't need to return here ever again. + if (_S_options._M_force_new) + { + _S_init = true; + return; + } + + // Calculate the number of bins required based on _M_max_bytes. + // _S_bin_size is statically-initialized to one. + size_t __bin_size = _S_options._M_min_bin; + while (_S_options._M_max_bytes > __bin_size) + { + __bin_size <<= 1; + ++_S_bin_size; + } + + // Setup the bin map for quick lookup of the relevant bin. + const size_t __j = (_S_options._M_max_bytes + 1) * sizeof(_Binmap_type); + _S_binmap = static_cast<_Binmap_type*>(::operator new(__j)); + + _Binmap_type* __bp = _S_binmap; + _Binmap_type __bin_max = _S_options._M_min_bin; + _Binmap_type __bint = 0; + for (_Binmap_type __ct = 0; __ct <= _S_options._M_max_bytes; ++__ct) + { + if (__ct > __bin_max) + { + __bin_max <<= 1; + ++__bint; + } + *__bp++ = __bint; + } + + // Initialize _S_bin and its members. + void* __v = ::operator new(sizeof(_Bin_record) * _S_bin_size); + _S_bin = static_cast<_Bin_record*>(__v); + + // If __gthread_active_p() create and initialize the list of + // free thread ids. Single threaded applications use thread id 0 + // directly and have no need for this. +#ifdef __GTHREADS + if (__gthread_active_p()) + { + const size_t __k = sizeof(_Thread_record) * _S_options._M_max_threads; + __v = ::operator new(__k); + _S_thread_freelist_first = static_cast<_Thread_record*>(__v); + + // NOTE! The first assignable thread id is 1 since the + // global pool uses id 0 + size_t __i; + for (__i = 1; __i < _S_options._M_max_threads; ++__i) + { + _Thread_record& __tr = _S_thread_freelist_first[__i - 1]; + __tr._M_next = &_S_thread_freelist_first[__i]; + __tr._M_id = __i; + } + + // Set last record. + _S_thread_freelist_first[__i - 1]._M_next = NULL; + _S_thread_freelist_first[__i - 1]._M_id = __i; + + // Make sure this is initialized. +#ifndef __GTHREAD_MUTEX_INIT + __GTHREAD_MUTEX_INIT_FUNCTION(&_S_thread_freelist_mutex); +#endif + // Initialize per thread key to hold pointer to + // _S_thread_freelist. + __gthread_key_create(&_S_thread_key, _S_destroy_thread_key); + + const size_t __max_threads = _S_options._M_max_threads + 1; + for (size_t __n = 0; __n < _S_bin_size; ++__n) + { + _Bin_record& __bin = _S_bin[__n]; + __v = ::operator new(sizeof(_Block_record*) * __max_threads); + __bin._M_first = static_cast<_Block_record**>(__v); + + __v = ::operator new(sizeof(size_t) * __max_threads); + __bin._M_free = static_cast(__v); + + __v = ::operator new(sizeof(size_t) * __max_threads); + __bin._M_used = static_cast(__v); + + __v = ::operator new(sizeof(__gthread_mutex_t)); + __bin._M_mutex = static_cast<__gthread_mutex_t*>(__v); + +#ifdef __GTHREAD_MUTEX_INIT + { + // Do not copy a POSIX/gthr mutex once in use. + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + *__bin._M_mutex = __tmp; + } +#else + { __GTHREAD_MUTEX_INIT_FUNCTION(__bin._M_mutex); } +#endif + + for (size_t __threadn = 0; __threadn < __max_threads; + ++__threadn) + { + __bin._M_first[__threadn] = NULL; + __bin._M_free[__threadn] = 0; + __bin._M_used[__threadn] = 0; + } + } + } + else +#endif + for (size_t __n = 0; __n < _S_bin_size; ++__n) + { + _Bin_record& __bin = _S_bin[__n]; + __v = ::operator new(sizeof(_Block_record*)); + __bin._M_first = static_cast<_Block_record**>(__v); + __bin._M_first[0] = NULL; + } + + _S_init = true; + } + + template + size_t + __mt_alloc<_Tp>:: + _S_get_thread_id() + { +#ifdef __GTHREADS + // If we have thread support and it's active we check the thread + // key value and return its id or if it's not set we take the + // first record from _S_thread_freelist and sets the key and + // returns it's id. + if (__gthread_active_p()) + { + _Thread_record* __freelist_pos = + static_cast<_Thread_record*>(__gthread_getspecific(_S_thread_key)); + if (__freelist_pos == NULL) + { + // Since _S_options._M_max_threads must be larger than + // the theoretical max number of threads of the OS the + // list can never be empty. + __gthread_mutex_lock(&_S_thread_freelist_mutex); + __freelist_pos = _S_thread_freelist_first; + _S_thread_freelist_first = _S_thread_freelist_first->_M_next; + __gthread_mutex_unlock(&_S_thread_freelist_mutex); + + __gthread_setspecific(_S_thread_key, + static_cast(__freelist_pos)); + } + return __freelist_pos->_M_id; + } +#endif + // Otherwise (no thread support or inactive) all requests are + // served from the global pool 0. + return 0; + } + +#ifdef __GTHREADS + template + void + __mt_alloc<_Tp>:: + _S_destroy_thread_key(void* __freelist_pos) + { + // Return this thread id record to front of thread_freelist. + __gthread_mutex_lock(&_S_thread_freelist_mutex); + _Thread_record* __tr = static_cast<_Thread_record*>(__freelist_pos); + __tr->_M_next = _S_thread_freelist_first; + _S_thread_freelist_first = __tr; + __gthread_mutex_unlock(&_S_thread_freelist_mutex); + } +#endif + + template + inline bool + operator==(const __mt_alloc<_Tp>&, const __mt_alloc<_Tp>&) + { return true; } + + template + inline bool + operator!=(const __mt_alloc<_Tp>&, const __mt_alloc<_Tp>&) + { return false; } + + template + bool __mt_alloc<_Tp>::_S_init = false; + + template + typename __mt_alloc<_Tp>::_Tune __mt_alloc<_Tp>::_S_options; + + template + typename __mt_alloc<_Tp>::_Binmap_type* __mt_alloc<_Tp>::_S_binmap; + + template + typename __mt_alloc<_Tp>::_Bin_record* volatile __mt_alloc<_Tp>::_S_bin; + + template + size_t __mt_alloc<_Tp>::_S_bin_size = 1; + + // Actual initialization in _S_initialize(). +#ifdef __GTHREADS + template + __gthread_once_t __mt_alloc<_Tp>::_S_once = __GTHREAD_ONCE_INIT; + + template + typename __mt_alloc<_Tp>::_Thread_record* + volatile __mt_alloc<_Tp>::_S_thread_freelist_first = NULL; + + template + __gthread_key_t __mt_alloc<_Tp>::_S_thread_key; + + template + __gthread_mutex_t +#ifdef __GTHREAD_MUTEX_INIT + __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT; +#else + __mt_alloc<_Tp>::_S_thread_freelist_mutex; +#endif +#endif +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/new_allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/new_allocator.h new file mode 100644 index 00000000000..1b0b4f61079 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/new_allocator.h @@ -0,0 +1,113 @@ +// Allocator that wraps operator new -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _NEW_ALLOCATOR_H +#define _NEW_ALLOCATOR_H 1 + +#include + +namespace __gnu_cxx +{ + /** + * @brief An allocator that uses global new, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * (See @link Allocators allocators info @endlink for more.) + */ + template + class new_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef new_allocator<_Tp1> other; }; + + new_allocator() throw() { } + + new_allocator(const new_allocator&) throw() { } + + template + new_allocator(const new_allocator<_Tp1>&) throw() { } + + ~new_allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template + inline bool + operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return false; } +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/numeric b/reactos/tools/ppc-build/core-headers/g++-v3/ext/numeric new file mode 100644 index 00000000000..40edf07fe3d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/numeric @@ -0,0 +1,148 @@ +// Numeric extensions -*- C++ -*- + +// Copyright (C) 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/numeric + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _EXT_NUMERIC +#define _EXT_NUMERIC 1 + +#pragma GCC system_header + +#include +#include + +#include // For identity_element + +namespace __gnu_cxx +{ + // Returns __x ** __n, where __n >= 0. _Note that "multiplication" + // is required to be associative, but not necessarily commutative. + template + _Tp + __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) + { + if (__n == 0) + return identity_element(__monoid_op); + else { + while ((__n & 1) == 0) { + __n >>= 1; + __x = __monoid_op(__x, __x); + } + + _Tp __result = __x; + __n >>= 1; + while (__n != 0) { + __x = __monoid_op(__x, __x); + if ((__n & 1) != 0) + __result = __monoid_op(__result, __x); + __n >>= 1; + } + return __result; + } + } + + template + inline _Tp + __power(_Tp __x, _Integer __n) + { return __power(__x, __n, std::multiplies<_Tp>()); } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + // Alias for the internal name __power. Note that power is an extension, + // not part of the C++ standard. + template + inline _Tp + power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) + { return __power(__x, __n, __monoid_op); } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template + inline _Tp + power(_Tp __x, _Integer __n) + { return __power(__x, __n); } + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + // iota is not part of the C++ standard. It is an extension. + template + void + iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) + { + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename std::iterator_traits<_ForwardIter>::value_type>) + + while (__first != __last) + *__first++ = __value++; + } +} // namespace __gnu_cxx + +#endif + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/pod_char_traits.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/pod_char_traits.h new file mode 100644 index 00000000000..c69025e005d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/pod_char_traits.h @@ -0,0 +1,158 @@ +// POD character, std::char_traits specialization -*- C++ -*- + +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Gabriel Dos Reis +// Benjamin Kosnik + +#ifndef _POD_CHAR_TRAITS_H +#define _POD_CHAR_TRAITS_H 1 + +#include + +namespace __gnu_cxx +{ + template + struct character + { + typedef V value_type; + typedef I int_type; + typedef S state_type; + value_type value; + }; + + template + inline bool + operator==(const character& lhs, const character& rhs) + { return lhs.value == rhs.value; } + + template + inline bool + operator<(const character& lhs, const character& rhs) + { return lhs.value < rhs.value; } +} // namespace __gnu_cxx + +namespace std +{ + // Provide std::char_traits specialization. + template + struct char_traits<__gnu_cxx::character > + { + typedef __gnu_cxx::character char_type; + + // NB: This type should be bigger than char_type, so as to + // properly hold EOF values in addition to the full range of + // char_type values. + // Also, assumes + // int_type(value_type) is valid. + // int_type(-1) is possible. + typedef typename char_type::int_type int_type; + typedef typename char_type::state_type state_type; + typedef fpos pos_type; + typedef streamoff off_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (__p->value) + ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) + return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + for (char_type* __p = __s; __p < __s + __n; ++__p) + assign(*__p, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __c) + { + char_type __r = { __c }; + return __r; + } + + static int_type + to_int_type(const char_type& __c) + { return int_type(__c.value); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast(-1); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + }; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/pool_allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/pool_allocator.h new file mode 100644 index 00000000000..0f087a03c1e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/pool_allocator.h @@ -0,0 +1,255 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/pool_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ +#ifndef _POOL_ALLOCATOR_H +#define _POOL_ALLOCATOR_H 1 + +#include +#include +#include +#include +#include +#include + +namespace __gnu_cxx +{ + /** + * @if maint + * Uses various allocators to fulfill underlying requests (and makes as + * few requests as possible when in default high-speed pool mode). + * + * Important implementation properties: + * 0. If globally mandated, then allocate objects from new + * 1. If the clients request an object of size > _S_max_bytes, the resulting + * object will be obtained directly from new + * 2. In all other cases, we allocate an object of size exactly + * _S_round_up(requested_size). Thus the client has enough size + * information that we can return the object to the proper free list + * without permanently losing part of the object. + * + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + class __pool_alloc_base + { + protected: + + enum { _S_align = 8 }; + enum { _S_max_bytes = 128 }; + enum { _S_free_list_size = _S_max_bytes / _S_align }; + + union _Obj + { + union _Obj* _M_free_list_link; + char _M_client_data[1]; // The client sees this. + }; + + static _Obj* volatile _S_free_list[_S_free_list_size]; + + // Chunk allocation state. + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; + + size_t + _M_round_up(size_t __bytes) + { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); } + + _Obj* volatile* + _M_get_free_list(size_t __bytes); + + mutex_type& + _M_get_mutex(); + + // Returns an object of size __n, and optionally adds to size __n + // free list. + void* + _M_refill(size_t __n); + + // Allocates a chunk for nobjs of size size. nobjs may be reduced + // if it is inconvenient to allocate the requested number. + char* + _M_allocate_chunk(size_t __n, int& __nobjs); + }; + + + template + class __pool_alloc : private __pool_alloc_base + { + private: + static _Atomic_word _S_force_new; + + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef __pool_alloc<_Tp1> other; }; + + __pool_alloc() throw() { } + + __pool_alloc(const __pool_alloc&) throw() { } + + template + __pool_alloc(const __pool_alloc<_Tp1>&) throw() { } + + ~__pool_alloc() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + }; + + template + inline bool + operator==(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) + { return true; } + + template + inline bool + operator!=(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) + { return false; } + + template + _Atomic_word + __pool_alloc<_Tp>::_S_force_new; + + template + _Tp* + __pool_alloc<_Tp>::allocate(size_type __n, const void*) + { + pointer __ret = 0; + if (__n) + { + if (__n <= max_size()) + { + // If there is a race through here, assume answer from getenv + // will resolve in same direction. Inspired by techniques + // to efficiently support threading found in basic_string.h. + if (_S_force_new == 0) + { + if (getenv("GLIBCXX_FORCE_NEW")) + __atomic_add(&_S_force_new, 1); + else + __atomic_add(&_S_force_new, -1); + } + + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1) + __ret = static_cast<_Tp*>(::operator new(__bytes)); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + + lock sentry(_M_get_mutex()); + _Obj* __restrict__ __result = *__free_list; + if (__builtin_expect(__result == 0, 0)) + __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); + else + { + *__free_list = __result->_M_free_list_link; + __ret = reinterpret_cast<_Tp*>(__result); + } + if (__builtin_expect(__ret == 0, 0)) + std::__throw_bad_alloc(); + } + } + else + std::__throw_bad_alloc(); + } + return __ret; + } + + template + void + __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) + { + if (__n) + { + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > static_cast(_S_max_bytes) || _S_force_new == 1) + ::operator delete(__p); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + _Obj* __q = reinterpret_cast<_Obj*>(__p); + + lock sentry(_M_get_mutex()); + __q ->_M_free_list_link = *__free_list; + *__free_list = __q; + } + } + } +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/rb_tree b/reactos/tools/ppc-build/core-headers/g++-v3/ext/rb_tree new file mode 100644 index 00000000000..2c38b39706e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/rb_tree @@ -0,0 +1,97 @@ +// rb_tree extension -*- C++ -*- + +// Copyright (C) 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/rb_tree + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _RB_TREE +#define _RB_TREE 1 + +#pragma GCC system_header + +#include + +namespace __gnu_cxx +{ + using std::_Rb_tree; + using std::allocator; + + // Class rb_tree is not part of the C++ standard. It is provided for + // compatibility with the HP STL. + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template > + struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> + { + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) { } + + ~rb_tree() { } + }; +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/rope b/reactos/tools/ppc-build/core-headers/g++-v3/ext/rope new file mode 100644 index 00000000000..b4bf2c9650c --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/rope @@ -0,0 +1,2494 @@ +// SGI's rope class -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/rope + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _ROPE +#define _ROPE 1 + +#include +#include +#include +#include +#include +#include +#include +#include + +# ifdef __GC +# define __GC_CONST const +# else +# include +# define __GC_CONST // constant except for deallocation +# endif + +#include // For uninitialized_copy_n + +namespace __gnu_cxx +{ +using std::size_t; +using std::ptrdiff_t; +using std::allocator; +using std::iterator; +using std::reverse_iterator; +using std::_Destroy; + +// The _S_eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. + +// The end-of-C-string character. +// This is what the draft standard says it should be. +template +inline _CharT _S_eos(_CharT*) { return _CharT(); } + +// Test for basic character types. +// For basic character types leaves having a trailing eos. +template +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template +class char_producer { + public: + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. +}; + +// Sequence buffers: +// +// Sequence must provide an append operation that appends an +// array to the sequence. Sequence buffers are useful only if +// appending an entire array is cheaper than appending element by element. +// This is true for many string representations. +// This should perhaps inherit from ostream +// and be implemented correspondingly, so that they can be used +// for formatted. For the sake of portability, we don't do this yet. +// +// For now, sequence buffers behave as output iterators. But they also +// behave a little like basic_ostringstream and a +// little like containers. + +template +class sequence_buffer : public iterator +{ + public: + typedef typename _Sequence::value_type value_type; + protected: + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; + public: + void flush() { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} + sequence_buffer(const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + sequence_buffer(sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + void push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } else { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + void append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) { + size_t __i = _M_buf_count; + for (size_t __j = 0; __j < __len; __i++, __j++) { + _M_buffer[__i] = __s[__j]; + } + _M_buf_count += __len; + } else if (0 == _M_buf_count) { + _M_prefix->append(__s, __s + __len); + } else { + flush(); + append(__s, __len); + } + } + sequence_buffer& write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + sequence_buffer& put(value_type __x) + { + push_back(__x); + return *this; + } + sequence_buffer& operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer operator++(int) { return *this; } +}; + +// The following should be treated as private, at least for now. +template +class _Rope_char_consumer { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; +}; + +// First a lot of forward declarations. The standard seems to require +// much stricter "declaration before use" than many of the implementations +// that preceded it. +template > class rope; +template struct _Rope_RopeConcatenation; +template struct _Rope_RopeLeaf; +template struct _Rope_RopeFunction; +template struct _Rope_RopeSubstring; +template class _Rope_iterator; +template class _Rope_const_iterator; +template class _Rope_char_ref_proxy; +template class _Rope_char_ptr_proxy; + +template +bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + +template +_Rope_const_iterator<_CharT,_Alloc> operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_const_iterator<_CharT,_Alloc> operator+ + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_const_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + +template +bool operator== + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template +bool operator< + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template +ptrdiff_t operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template +_Rope_iterator<_CharT,_Alloc> operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_iterator<_CharT,_Alloc> operator+ + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template +_Rope_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); + +template +bool operator== + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template +bool operator< + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template +ptrdiff_t operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + +template +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + +template +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + _CharT __right); + +// Some helpers, so we can use power on ropes. +// See below for why this isn't local to the implementation. + +// This uses a nonstandard refcount convention. +// The result has refcount 0. +template +struct _Rope_Concat_fn + : public std::binary_function, rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, + const rope<_CharT,_Alloc>& __y) { + return __x + __y; + } +}; + +template +inline +rope<_CharT,_Alloc> +identity_element(_Rope_Concat_fn<_CharT, _Alloc>) +{ + return rope<_CharT,_Alloc>(); +} + + + // Class _Refcount_Base provides a type, _RC_t, a data member, + // _M_ref_count, and member functions _M_incr and _M_decr, which perform + // atomic preincrement/predecrement. The constructor initializes + // _M_ref_count. + struct _Refcount_Base + { + // The type _RC_t + typedef size_t _RC_t; + + // The data member _M_ref_count + volatile _RC_t _M_ref_count; + + // Constructor + __gthread_mutex_t _M_ref_count_lock; + + _Refcount_Base(_RC_t __n) : _M_ref_count(__n), _M_ref_count_lock() + { +#ifdef __GTHREAD_MUTEX_INIT + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_ref_count_lock = __tmp; +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) + __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); +#else +#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. +#endif + } + + void + _M_incr() + { + __gthread_mutex_lock(&_M_ref_count_lock); + ++_M_ref_count; + __gthread_mutex_unlock(&_M_ref_count_lock); + } + + _RC_t + _M_decr() + { + __gthread_mutex_lock(&_M_ref_count_lock); + volatile _RC_t __tmp = --_M_ref_count; + __gthread_mutex_unlock(&_M_ref_count_lock); + return __tmp; + } + }; + +// +// What follows should really be local to rope. Unfortunately, +// that doesn't work, since it makes it impossible to define generic +// equality on rope iterators. According to the draft standard, the +// template parameters for such an equality operator cannot be inferred +// from the occurrence of a member class as a parameter. +// (SGI compilers in fact allow this, but the __result wouldn't be +// portable.) +// Similarly, some of the static member functions are member functions +// only to avoid polluting the global namespace, and to circumvent +// restrictions on type inference for template functions. +// + +// +// The internal data structure for representing a rope. This is +// private to the implementation. A rope is really just a pointer +// to one of these. +// +// A few basic functions for manipulating this data structure +// are members of _RopeRep. Most of the more complex algorithms +// are implemented as rope members. +// +// Some of the static member functions of _RopeRep have identically +// named functions in rope that simply invoke the _RopeRep versions. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ + __ROPE_DEFINE_ALLOC(__C,_C) \ + typedef _Rope_RopeLeaf<_CharT,__a> __L; \ + __ROPE_DEFINE_ALLOC(__L,_L) \ + typedef _Rope_RopeFunction<_CharT,__a> __F; \ + __ROPE_DEFINE_ALLOC(__F,_F) \ + typedef _Rope_RopeSubstring<_CharT,__a> __S; \ + __ROPE_DEFINE_ALLOC(__S,_S) + +// Internal rope nodes potentially store a copy of the allocator +// instance used to allocate them. This is mostly redundant. +// But the alternative would be to pass allocator instances around +// in some form to nearly all internal functions, since any pointer +// assignment may result in a zero reference count and thus require +// deallocation. + +#define __STATIC_IF_SGI_ALLOC /* not static */ + +template +struct _Rope_rep_base +: public _Alloc +{ + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast(this); } + + _Rope_rep_base(size_t __size, const allocator_type&) + : _M_size(__size) {} + + size_t _M_size; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc::template rebind<_Tp>::other __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc().allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc().deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC +}; + +namespace _Rope_constants +{ + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; +} + +template +struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> +# ifndef __GC + , _Refcount_Base +# endif +{ + public: + _Rope_constants::_Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + __gthread_mutex_t _M_c_string_lock; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + using _Rope_rep_base<_CharT,_Alloc>::get_allocator; + _Rope_RopeRep(_Rope_constants::_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _Rope_rep_base<_CharT,_Alloc>(__size, __a), +# ifndef __GC + _Refcount_Base(1), +# endif + _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) +#ifdef __GTHREAD_MUTEX_INIT + { + // Do not copy a POSIX/gthr mutex once in use. However, bits are bits. + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_c_string_lock = __tmp; + } +#else + { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); } +#endif +# ifdef __GC + void _M_incr () {} +# endif + static void _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. +# ifndef __GC + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void _M_unref_nonnil() + { + if (0 == _M_decr()) _M_free_tree(); + } + void _M_ref_nonnil() + { + _M_incr(); + } + static void _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) { + __t->_M_unref_nonnil(); + } + } + static void _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) __t->_M_incr(); + } + static void _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_ref_count) __t->_M_free_tree(); + } +# else /* __GC */ + void _M_unref_nonnil() {} + void _M_ref_nonnil() {} + static void _S_unref(_Rope_RopeRep*) {} + static void _S_ref(_Rope_RopeRep*) {} + static void _S_free_if_unref(_Rope_RopeRep*) {} +# endif +protected: + _Rope_RopeRep& + operator=(const _Rope_RopeRep&); + + _Rope_RopeRep(const _Rope_RopeRep&); +}; + +template +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ + // The data fields of leaves are allocated with some + // extra space, to accommodate future growth and for basic + // character types, to hold a trailing eos character. + enum { _S_alloc_granularity = 8 }; + static size_t _S_rounded_up_size(size_t __n) { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) { + __size_with_eos = __n + 1; + } else { + __size_with_eos = __n; + } +# ifdef __GC + return __size_with_eos; +# else + // Allow slop for in-place expansion. + return (__size_with_eos + _S_alloc_granularity-1) + &~ (_S_alloc_granularity-1); +# endif + } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_leaf, 0, true, __size, __a), _M_data(__d) + { + if (_S_is_basic_char_type((_CharT *)0)) { + // already eos terminated. + this->_M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +# ifndef __GC + ~_Rope_RopeLeaf() throw() { + if (_M_data != this->_M_c_string) { + this->_M_free_c_string(); + } + __STL_FREE_STRING(_M_data, this->_M_size, this->get_allocator()); + } +# endif +protected: + _Rope_RopeLeaf& + operator=(const _Rope_RopeLeaf&); + + _Rope_RopeLeaf(const _Rope_RopeLeaf&); +}; + +template +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { + public: + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + + : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_concat, + std::max(__l->_M_depth, __r->_M_depth) + 1, + false, + __l->_M_size + __r->_M_size, __a), + _M_left(__l), _M_right(__r) + {} +# ifndef __GC + ~_Rope_RopeConcatenation() throw() { + this->_M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +# endif +protected: + _Rope_RopeConcatenation& + operator=(const _Rope_RopeConcatenation&); + + _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); +}; + +template +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { + public: + char_producer<_CharT>* _M_fn; +# ifndef __GC + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. +# else + // In the GC case, we either register the rope for + // finalization, or not. Thus the field is unnecessary; + // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void _S_fn_finalization_proc(void * __tree, void *) { + delete ((_Rope_RopeFunction *)__tree) -> _M_fn; + } +# endif + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_function, + 0, true, __size, __a) + , _M_fn(__f) +# ifndef __GC + , _M_delete_when_done(__d) +# endif + { +# ifdef __GC + if (__d) { + GC_REGISTER_FINALIZER( + this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); + } +# endif + } +# ifndef __GC + ~_Rope_RopeFunction() throw() { + this->_M_free_c_string(); + if (_M_delete_when_done) { + delete _M_fn; + } + } +# endif +protected: + _Rope_RopeFunction& + operator=(const _Rope_RopeFunction&); + + _Rope_RopeFunction(const _Rope_RopeFunction&); +}; +// Substring results are usually represented using just +// concatenation nodes. But in the case of very long flat ropes +// or ropes with a functional representation that isn't practical. +// In that case, we represent the __result as a special case of +// RopeFunction, whose char_producer points back to the rope itself. +// In all cases except repeated substring operations and +// deallocation, we treat the __result as a RopeFunction. +template +struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, + public char_producer<_CharT> { + public: + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case _Rope_constants::_S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + break; + } + } + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a), + char_producer<_CharT>(), + _M_base(__b), + _M_start(__s) + { +# ifndef __GC + _M_base->_M_ref_nonnil(); +# endif + this->_M_tag = _Rope_constants::_S_substringfn; + } + virtual ~_Rope_RopeSubstring() throw() + { +# ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +# endif + } +}; + + +// Self-destructing pointers to Rope_rep. +// These are not conventional smart pointers. Their +// only purpose in life is to ensure that unref is called +// on the pointer either at normal exit or if an exception +// is raised. It is the caller's responsibility to +// adjust reference counts when these pointers are initialized +// or assigned to. (This convention significantly reduces +// the number of potentially expensive reference count +// updates.) +#ifndef __GC + template + struct _Rope_self_destruct_ptr { + _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } +#ifdef __EXCEPTIONS + _Rope_self_destruct_ptr() : _M_ptr(0) {}; +#else + _Rope_self_destruct_ptr() {}; +#endif + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {} + _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; } + _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; } + operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; } + _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x) + { _M_ptr = __x; return *this; } + }; +#endif + +// Dereferencing a nonconst iterator has to return something +// that behaves almost like a reference. It's not possible to +// return an actual reference since assignment requires extra +// work. And we would get into the same problems as with the +// CD2 version of basic_string. +template +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. + public: + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) + : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) {} + + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) + : _M_pos(__x._M_pos), _M_current(__x._M_current), _M_current_valid(false), + _M_root(__x._M_root) {} + + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c) + : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) {} + inline operator _CharT () const; + _Rope_char_ref_proxy& operator= (_CharT __c); + _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const; + _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) { + return operator=((_CharT)__c); + } +}; + +template +inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; +} + +template +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. + public: + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + } + _Rope_char_ptr_proxy& + operator= (const _Rope_char_ptr_proxy& __x) { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; + } + template + friend bool operator== (const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __x, + const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __y); + _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const { + return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos); + } +}; + + +// Rope iterators: +// Unlike in the C version, we cache only part of the stack +// for rope iterators, since they must be efficiently copyable. +// When we run out of cache, we have to reconstruct the iterator +// value. +// Pointers from iterators are not included in reference counts. +// Iterators are assumed to be thread private. Ropes can +// be shared. + +template +class _Rope_iterator_base + : public iterator +{ + friend class rope<_CharT,_Alloc>; + public: + typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // Borland doesn't want this to be protected. + protected: + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. + // What follows is the path cache. We go out of our + // way to make this compact. + // Path_end contains the bottom section of the path from + // the root to the current leaf. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() {} + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) {} + void _M_incr(size_t __n); + void _M_decr(size_t __n); + public: + size_t index() const { return _M_current_pos; } + _Rope_iterator_base(const _Rope_iterator_base& __x) { + if (0 != __x._M_buf_ptr) { + *this = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } +}; + +template class _Rope_iterator; + +template +class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // The one from the base class may not be directly visible. + _Rope_const_iterator(const _RopeRep* __root, size_t __pos): + _Rope_iterator_base<_CharT,_Alloc>( + const_cast<_RopeRep*>(__root), __pos) + // Only nonconst iterators modify root ref count + {} + public: + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; + + public: + _Rope_const_iterator() {}; + _Rope_const_iterator(const _Rope_const_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { } + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) : + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {} + _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) { + if (0 != __x._M_buf_ptr) { + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + this->_M_current_pos = __x._M_current_pos; + this->_M_root = __x._M_root; + this->_M_buf_ptr = 0; + } + return(*this); + } + reference operator*() { + if (0 == this->_M_buf_ptr) _S_setcache(*this); + return *this->_M_buf_ptr; + } + _Rope_const_iterator& operator++() { + __GC_CONST _CharT* __next; + if (0 != this->_M_buf_ptr + && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) { + this->_M_buf_ptr = __next; + ++this->_M_current_pos; + } else { + this->_M_incr(1); + } + return *this; + } + _Rope_const_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_incr(__n); + } else { + this->_M_decr(-__n); + } + return *this; + } + _Rope_const_iterator& operator--() { + this->_M_decr(1); + return *this; + } + _Rope_const_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_decr(__n); + } else { + this->_M_incr(-__n); + } + return *this; + } + _Rope_const_iterator operator++(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? + } + _Rope_const_iterator operator--(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); + } + template + friend _Rope_const_iterator<_CharT2,_Alloc2> operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT2,_Alloc2>& __x); + reference operator[](size_t __n) { + return rope<_CharT,_Alloc>::_S_fetch(this->_M_root, + this->_M_current_pos + __n); + } + + template + friend bool operator== + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template + friend bool operator< + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template + friend ptrdiff_t operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); +}; + +template +class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + typedef typename _Rope_iterator_base<_CharT,_Alloc>::_RopeRep _RopeRep; + rope<_CharT,_Alloc>* _M_root_rope; + // root is treated as a cached version of this, + // and is used to detect changes to the underlying + // rope. + // Root is included in the reference count. + // This is necessary so that we can detect changes reliably. + // Unfortunately, it requires careful bookkeeping for the + // nonGC case. + _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(this->_M_root); + if (!(__r -> empty()))_S_setcache(*this); } + + void _M_check(); + public: + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; + + public: + rope<_CharT,_Alloc>& container() { return *_M_root_rope; } + _Rope_iterator() { + this->_M_root = 0; // Needed for reference counting. + }; + _Rope_iterator(const _Rope_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(this->_M_root); + } + _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); + ~_Rope_iterator() { + _RopeRep::_S_unref(this->_M_root); + } + _Rope_iterator& operator= (const _Rope_iterator& __x) { + _RopeRep* __old = this->_M_root; + + _RopeRep::_S_ref(__x._M_root); + if (0 != __x._M_buf_ptr) { + _M_root_rope = __x._M_root_rope; + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + this->_M_current_pos = __x._M_current_pos; + this->_M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + this->_M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); + } + reference operator*() { + _M_check(); + if (0 == this->_M_buf_ptr) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, this->_M_current_pos); + } else { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, this->_M_current_pos, *this->_M_buf_ptr); + } + } + _Rope_iterator& operator++() { + this->_M_incr(1); + return *this; + } + _Rope_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_incr(__n); + } else { + this->_M_decr(-__n); + } + return *this; + } + _Rope_iterator& operator--() { + this->_M_decr(1); + return *this; + } + _Rope_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_decr(__n); + } else { + this->_M_incr(-__n); + } + return *this; + } + _Rope_iterator operator++(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + _Rope_iterator operator--(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + reference operator[](ptrdiff_t __n) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, this->_M_current_pos + __n); + } + + template + friend bool operator== + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template + friend bool operator< + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template + friend ptrdiff_t operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template + friend _Rope_iterator<_CharT2,_Alloc2> operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT2,_Alloc2>& __x); +}; + + +template +struct _Rope_base +: public _Alloc +{ + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast(this); } + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // The one in _Base may not be visible due to template rules. + + _Rope_base(_RopeRep* __t, const allocator_type&) + : _M_tree_ptr(__t) {} + _Rope_base(const allocator_type&) {} + + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc::template rebind<_Tp>::other __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc().allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc().deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC + +protected: + _Rope_base& + operator=(const _Rope_base&); + + _Rope_base(const _Rope_base&); +}; + + +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template +class rope : public _Rope_base<_CharT,_Alloc> { + public: + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; + + protected: + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + using _Base::_M_tree_ptr; + using _Base::get_allocator; + typedef __GC_CONST _CharT* _Cstrptr; + + static _CharT _S_empty_c_str[1]; + + static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +# endif + + static bool _S_apply_to_pieces( + // should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void _S_unref(_RopeRep* __t) + { + _RopeRep::_S_unref(__t); + } + static void _S_ref(_RopeRep* __t) + { + _RopeRep::_S_ref(__t); + } +# else /* __GC */ + static void _S_unref(_RopeRep*) {} + static void _S_ref(_RopeRep*) {} +# endif + + +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevant reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +# else + ; +# endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. + + public: + void apply_to_pieces( size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const { + _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); + } + + + protected: + + static size_t _S_rounded_up_size(size_t __n) { + return _RopeLeaf::_S_rounded_up_size(__n); + } + + static size_t _S_allocated_capacity(size_t __n) { + if (_S_is_basic_char_type((_CharT*)0)) { + return _S_rounded_up_size(__n) - 1; + } else { + return _S_rounded_up_size(__n); + } + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { + _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* _S_new_RopeConcatenation( + _RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { + _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { + _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* _S_new_RopeSubstring( + _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { + _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) + { + if (0 == __size) return 0; + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); + + uninitialized_copy_n(__s, __size, __buf); + _S_cond_store_eos(__buf[__size]); + try { + return _S_new_RopeLeaf(__buf, __size, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, __size, __a); + __throw_exception_again; + } + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static _RopeLeaf* _S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_ref_count == 1. +# endif + + private: + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t,__a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[_Rope_constants::_S_max_rope_depth + 1]; + + static bool _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 || + __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 || + __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, + _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); + + public: + bool empty() const { return 0 == this->_M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope& __y) const { + return _S_compare(this->_M_tree_ptr, __y._M_tree_ptr); + } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a),__a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1)); + + std::_Construct(__buf, __c); + try { + this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, 1, __a); + __throw_exception_again; + } + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) {} + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + this->_M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { + _S_ref(this->_M_tree_ptr); + } + + ~rope() throw() + { _S_unref(this->_M_tree_ptr); } + + rope& operator=(const rope& __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = __x._M_tree_ptr; + _S_ref(this->_M_tree_ptr); + _S_unref(__old); + return *this; + } + + void clear() + { + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = 0; + } + + void push_back(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void pop_back() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = + _S_substring(this->_M_tree_ptr, + 0, + this->_M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT back() const + { + return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); + } + + void push_front(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, this->get_allocator()); + try { + this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); + _S_unref(__old); + _S_unref(__left); + } + catch(...) + { + _S_unref(__left); + __throw_exception_again; + } + } + + void pop_front() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT front() const + { + return _S_fetch(this->_M_tree_ptr, 0); + } + + void balance() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); + _S_unref(__old); + } + + void copy(_CharT* __buffer) const { + _Destroy(__buffer, __buffer + size()); + _S_flatten(this->_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + _Destroy(__buffer, __buffer + __len); + _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + _S_dump(this->_M_tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == this->_M_tree_ptr) return; + if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag && + ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == + this->_M_tree_ptr->_M_c_string) { + // Representation shared + return; + } +# ifndef __GC + this->_M_tree_ptr->_M_free_c_string(); +# endif + this->_M_tree_ptr->_M_c_string = 0; + } + + _CharT operator[] (size_type __pos) const { + return _S_fetch(this->_M_tree_ptr, __pos); + } + + _CharT at(size_type __pos) const { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator begin() const { + return(const_iterator(this->_M_tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(this->_M_tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(this->_M_tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(this->_M_tree_ptr, size())); + } + + size_type size() const { + return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return _S_min_len[_Rope_constants::_S_max_rope_depth - 1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } + + typedef reverse_iterator const_reverse_iterator; + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator const_rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator const_rend() const { + return const_reverse_iterator(begin()); + } + + template + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const rope<_CharT2,_Alloc2>& __right); + + template + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const _CharT2* __right); + + template + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, _CharT2 __right); + // The symmetric cases are intentionally omitted, since they're presumed + // to be less common, and we don't handle them as well. + + // The following should really be templatized. + // The first argument should be an input iterator or + // forward iterator with value_type _CharT. + rope& append(const _CharT* __iter, size_t __n) { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(const _CharT* __c_string) { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& append(const _CharT* __s, const _CharT* __e) { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(const_iterator __s, const_iterator __e) { + _Self_destruct_ptr __appendee(_S_substring( + __s._M_root, __s._M_current_pos, __e._M_current_pos)); + _RopeRep* __result = + _S_concat(this->_M_tree_ptr, (_RopeRep*)__appendee); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(_CharT __c) { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append() { return append(_CharT()); } // XXX why? + + rope& append(const rope& __y) { + _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void swap(rope& __b) { + _RopeRep* __tmp = this->_M_tree_ptr; + this->_M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } + + + protected: + // Result is included in refcount. + static _RopeRep* replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) { + if (0 == __old) { _S_ref(__r); return __r; } + _Self_destruct_ptr __left( + _S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right( + _S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + + if (0 == __r) { + __result = _S_concat(__left, __right); + } else { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } + + public: + void insert(size_t __p, const rope& __r) { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void insert(size_t __p, size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void insert(size_t __p, const _CharT* __i, size_t __n) { + _Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, + __p, size())); + _Self_destruct_ptr __left_result( + _S_concat_char_iter(__left, __i, __n)); + // _S_ destr_concat_char_iter should be safe here. + // But as it stands it's probably not a win, since __left + // is likely to have additional references. + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void insert(size_t __p, const _CharT* __c_string) { + insert(__p, __c_string, _S_char_ptr_len(__c_string)); + } + + void insert(size_t __p, _CharT __c) { + insert(__p, &__c, 1); + } + + void insert(size_t __p) { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void insert(size_t __p, const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const iterator& __i, + const iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void replace(size_t __p, size_t __n, const rope& __r) { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, _CharT __c) { + rope __r(__c); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, const _CharT* __c_string) { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void replace(size_t __p, _CharT __c) { + iterator __i(this, __p); + *__i = __c; + } + + void replace(size_t __p, const rope& __r) { + replace(__p, 1, __r); + } + + void replace(size_t __p, const _CharT* __i, size_t __i_len) { + replace(__p, 1, __i, __i_len); + } + + void replace(size_t __p, const _CharT* __c_string) { + replace(__p, 1, __c_string); + } + + void replace(size_t __p, const _CharT* __i, const _CharT* __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const iterator& __i, + const iterator& __j) { + replace(__p, 1, __i, __j); + } + + // Erase, (position, size) variant. + void erase(size_t __p, size_t __n) { + _RopeRep* __result = replace(this->_M_tree_ptr, __p, __p + __n, 0); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + // Erase, single character + void erase(size_t __p) { + erase(__p, __p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& __p, const rope& __r) + { insert(__p.index(), __r); return __p; } + iterator insert(const iterator& __p, size_t __n, _CharT __c) + { insert(__p.index(), __n, __c); return __p; } + iterator insert(const iterator& __p, _CharT __c) + { insert(__p.index(), __c); return __p; } + iterator insert(const iterator& __p ) + { insert(__p.index()); return __p; } + iterator insert(const iterator& __p, const _CharT* c_string) + { insert(__p.index(), c_string); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, size_t __n) + { insert(__p.index(), __i, __n); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + + // Replace, range variants. + void replace(const iterator& __p, const iterator& __q, + const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + void replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + void replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + void replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + void replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, const_iterator __i, + const_iterator __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator erase(const iterator& __p, const iterator& __q) { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + iterator erase(const iterator& __p) { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope substr(size_t __start, size_t __len = 1) const { + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, + __start, + __start + __len)); + } + + rope substr(iterator __start, iterator __end) const { + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, + __start.index(), + __end.index())); + } + + rope substr(iterator __start) const { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, __pos, __pos + 1)); + } + + rope substr(const_iterator __start, const_iterator __end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, __start.index(), __end.index())); + } + + rope<_CharT,_Alloc> substr(const_iterator __start) { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + size_type find(const _CharT* __s, size_type __pos = 0) const { + size_type __result_pos; + const_iterator __result = + std::search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } + + typedef reverse_iterator reverse_iterator; + + reverse_iterator mutable_rbegin() { + return reverse_iterator(mutable_end()); + } + + reverse_iterator mutable_rend() { + return reverse_iterator(mutable_begin()); + } + + reference mutable_reference_at(size_type __pos) { + return reference(this, __pos); + } + +# ifdef __STD_STUFF + reference operator[] (size_type __pos) { + return _char_ref_proxy(this, __pos); + } + + reference at(size_type __pos) { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + void resize(size_type __n, _CharT __c) {} + void resize(size_type __n) {} + void reserve(size_type __res_arg = 0) {} + size_type capacity() const { + return max_size(); + } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const { + return copy(__pos, __n, __buffer); + } + + iterator end() { return mutable_end(); } + + iterator begin() { return mutable_begin(); } + + reverse_iterator rend() { return mutable_rend(); } + + reverse_iterator rbegin() { return mutable_rbegin(); } + +# else + + const_iterator end() { return const_end(); } + + const_iterator begin() { return const_begin(); } + + const_reverse_iterator rend() { return const_rend(); } + + const_reverse_iterator rbegin() { return const_rbegin(); } + +# endif + +}; + +template +const typename rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); +} + +template +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +template +inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos - __n); +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template +inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); +} + +template +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +template +inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos - __n); +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); + // Inlining this should make it possible to keep __left and + // __right in registers. +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + __left.append(__right); + return __left; +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, __right, __rlen)); +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; +} + +template +bool +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; +} + +template +bool +operator== (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) == 0; +} + +template +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); +} + +template +inline bool +operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +inline bool +operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template +inline bool +operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template +inline bool +operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template +inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template +std::basic_ostream<_CharT, _Traits>& operator<< + (std::basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r); + +typedef rope crope; +typedef rope wrope; + +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +template +inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { + __x.swap(__y); +} + +// Hash functions should probably be revisited later: +template<> struct hash +{ + size_t operator()(const crope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + + +template<> struct hash +{ + size_t operator()(const wrope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + +} // namespace __gnu_cxx + +# include + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/ropeimpl.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/ropeimpl.h new file mode 100644 index 00000000000..29dc550a037 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/ropeimpl.h @@ -0,0 +1,1539 @@ +// SGI's rope class implementation -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ropeimpl.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#include +#include +#include + +#include // For copy_n and lexicographical_compare_3way +#include // For uninitialized_copy_n +#include // For power + +namespace __gnu_cxx +{ + using std::size_t; + using std::printf; + using std::basic_ostream; + using std::__throw_length_error; + using std::_Destroy; + using std::uninitialized_fill_n; + +// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf +// if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. +// Results in a valid buf_ptr if the iterator can be legitimately +// dereferenced. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( + _Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) { + case _Rope_constants::_S_leaf: + __x._M_buf_start = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data; + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; + break; + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + { + size_t __len = _S_iterator_buf_len; + size_t __buf_start_pos = __leaf_pos; + size_t __leaf_end = __leaf_pos + __leaf->_M_size; + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)__leaf)->_M_fn; + + if (__buf_start_pos + __len <= __pos) { + __buf_start_pos = __pos - __len/4; + if (__buf_start_pos + __len > __leaf_end) { + __buf_start_pos = __leaf_end - __len; + } + } + if (__buf_start_pos + __len > __leaf_end) { + __len = __leaf_end - __buf_start_pos; + } + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); + __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); + __x._M_buf_start = __x._M_tmp_buf; + __x._M_buf_end = __x._M_tmp_buf + __len; + } + break; + default: + break; + } +} + +// Set path and buffer inside a rope iterator. We assume that +// pos and root are already set. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __path[_Rope_constants::_S_max_rope_depth + 1]; + const _RopeRep* __curr_rope; + int __curr_depth = -1; /* index into path */ + size_t __curr_start_pos = 0; + size_t __pos = __x._M_current_pos; + unsigned char __dirns = 0; // Bit vector marking right turns in the path + + if (__pos >= __x._M_root->_M_size) { + __x._M_buf_ptr = 0; + return; + } + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) { + /* Treat the root as a leaf. */ + __x._M_buf_start = __curr_rope->_M_c_string; + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; + __x._M_path_end[0] = __curr_rope; + __x._M_leaf_index = 0; + __x._M_leaf_pos = 0; + return; + } + for(;;) { + ++__curr_depth; + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) { + case _Rope_constants::_S_leaf: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; + goto done; + case _Rope_constants::_S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c = + (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + __dirns <<= 1; + if (__pos >= __curr_start_pos + __left_len) { + __dirns |= 1; + __curr_rope = __c->_M_right; + __curr_start_pos += __left_len; + } else { + __curr_rope = __left; + } + } + break; + } + } + done: + // Copy last section of path into _M_path_end. + { + int __i = -1; + int __j = __curr_depth + 1 - _S_path_cache_len; + + if (__j < 0) __j = 0; + while (__j <= __curr_depth) { + __x._M_path_end[++__i] = __path[__j++]; + } + __x._M_leaf_index = __i; + } + __x._M_path_directions = __dirns; + _S_setbuf(__x); +} + +// Specialized version of the above. Assumes that +// the path cache is valid for the previous position. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c; + + if (__x._M_current_pos - __node_start_pos < __len) { + /* More stuff in this leaf, we just didn't cache it. */ + _S_setbuf(__x); + return; + } + // node_start_pos is starting position of last_node. + while (--__current_index >= 0) { + if (!(__dirns & 1) /* Path turned left */) + break; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; + // Otherwise we were in the right child. Thus we should pop + // the concatenation node. + __node_start_pos -= __c->_M_left->_M_size; + __dirns >>= 1; + } + if (__current_index < 0) { + // We underflowed the cache. Punt. + _S_setcache(__x); + return; + } + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; + // current_node is a concatenation node. We are positioned on the first + // character in its right child. + // node_start_pos is starting position of current_node. + __node_start_pos += __c->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (_Rope_constants::_S_concat == __current_node->_M_tag) { + ++__current_index; + if (_S_path_cache_len == __current_index) { + int __i; + for (__i = 0; __i < _S_path_cache_len-1; __i++) { + __x._M_path_end[__i] = __x._M_path_end[__i+1]; + } + --__current_index; + } + __current_node = + ((_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node)->_M_left; + __x._M_path_end[__current_index] = __current_node; + __dirns <<= 1; + // node_start_pos is unchanged. + } + __x._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); +} + +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) { + _M_current_pos += __n; + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) { + _M_buf_ptr += __n; + } else if (__chars_left == __n) { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); + } else { + _M_buf_ptr = 0; + } + } +} + +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) { + _M_buf_ptr -= __n; + } else { + _M_buf_ptr = 0; + } + } + _M_current_pos -= __n; +} + +template +void _Rope_iterator<_CharT,_Alloc>::_M_check() { + if (_M_root_rope->_M_tree_ptr != this->_M_root) { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(this->_M_root); + this->_M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(this->_M_root); + this->_M_buf_ptr = 0; + } +} + +template +inline +_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( + const _Rope_iterator<_CharT,_Alloc>& __x) +: _Rope_iterator_base<_CharT,_Alloc>(__x) +{ } + +template +inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator( + rope<_CharT,_Alloc>& __r, size_t __pos) +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) +{ + _RopeRep::_S_ref(this->_M_root); +} + +template +inline size_t +rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) +{ + const _CharT* __p = __s; + + while (!_S_is0(*__p)) { ++__p; } + return (__p - __s); +} + + +#ifndef __GC + +template +inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() +{ + _CharT* __cstr = _M_c_string; + if (0 != __cstr) { + size_t __size = this->_M_size + 1; + _Destroy(__cstr, __cstr + __size); + this->_Data_deallocate(__cstr, __size); + } +} + + +template + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n, + allocator_type __a) +{ + if (!_S_is_basic_char_type((_CharT*)0)) { + _Destroy(__s, __s + __n); + } +// This has to be a static member, so this gets a bit messy + __a.deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +} + + +// There are several reasons for not doing this with virtual destructors +// and a class specific delete operator: +// - A class specific delete operator can't easily get access to +// allocator instances if we need them. +// - Any virtual function would need a 4 or byte vtable pointer; +// this only requires a one byte tag per object. +template +void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() +{ + switch(_M_tag) { + case _Rope_constants::_S_leaf: + { + _Rope_RopeLeaf<_CharT,_Alloc>* __l + = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; + } + case _Rope_constants::_S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT,_Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; + } + case _Rope_constants::_S_function: + { + _Rope_RopeFunction<_CharT,_Alloc>* __f + = (_Rope_RopeFunction<_CharT,_Alloc>*)this; + __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); + break; + } + case _Rope_constants::_S_substringfn: + { + _Rope_RopeSubstring<_CharT,_Alloc>* __ss = + (_Rope_RopeSubstring<_CharT,_Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT,_Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); + break; + } + } +} +#else + +template + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t, allocator_type) +{} + +#endif + + +// Concatenate a C string onto a leaf rope by copying the rope data. +// Used for short ropes. +template +typename rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) +{ + size_t __old_len = __r->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; + + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); + uninitialized_copy_n(__iter, __len, __new_data + __old_len); + _S_cond_store_eos(__new_data[__old_len + __len]); + try { + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator()); + __throw_exception_again; + } + return __result; +} + +#ifndef __GC +// As above, but it's OK to clobber original if refcount is 1 +template +typename rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) +{ + if (__r->_M_ref_count > 1) + return _S_leaf_concat_char_iter(__r, __iter, __len); + size_t __old_len = __r->_M_size; + if (_S_allocated_capacity(__old_len) >= __old_len + __len) { + // The space has been partially initialized for the standard + // character types. But that doesn't matter for those types. + uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) { + _S_cond_store_eos(__r->_M_data[__old_len + __len]); + } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + __r->_M_size = __old_len + __len; + __r->_M_ref_count = 2; + return __r; + } else { + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + return __result; + } +} +#endif + +// Assumes left and right are not 0. +// Does not increment (nor decrement on exception) child reference counts. +// Result has ref count 1. +template +typename rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) +{ + _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, + __left->get_allocator()); + size_t __depth = __result->_M_depth; + + if (__depth > 20 && (__result->_M_size < 1000 || + __depth > _Rope_constants::_S_max_rope_depth)) + { + _RopeRep* __balanced; + + try + { + __balanced = _S_balance(__result); + __result->_M_unref_nonnil(); + } + catch(...) + { + _C_deallocate(__result,1); + __throw_exception_again; + } + // In case of exception, we need to deallocate + // otherwise dangling result node. But caller + // still owns its children. Thus unref is + // inappropriate. + return __balanced; + } + else + return __result; +} + +template +typename +rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter + (_RopeRep* __r, const _CharT*__s, size_t __slen) +{ + _RopeRep* __result; + if (0 == __slen) { + _S_ref(__r); + return __r; + } + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (_Rope_constants::_S_leaf == __r->_M_tag && + __r->_M_size + __slen <= _S_copy_max) { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; + } + if (_Rope_constants::_S_concat == __r->_M_tag + && _Rope_constants::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); + try { + __result = _S_tree_concat(__left, __nright); + } + catch(...) + { + _S_unref(__left); + _S_unref(__nright); + __throw_exception_again; + } + return __result; + } + } + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + try { + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); + } + catch(...) + { + _S_unref(__r); + _S_unref(__nright); + __throw_exception_again; + } + return __result; +} + +#ifndef __GC +template +typename rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_destr_concat_char_iter( + _RopeRep* __r, const _CharT* __s, size_t __slen) +{ + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_ref_count; + size_t __orig_size = __r->_M_size; + if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) { + __r->_M_ref_count = 2; // One more than before + return __r; + } + if (__orig_size + __slen <= _S_copy_max && + _Rope_constants::_S_leaf == __r->_M_tag) { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; + } + if (_Rope_constants::_S_concat == __r->_M_tag) { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); + if (_Rope_constants::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) + __new_right->_M_ref_count = 1; + else + __right->_M_unref_nonnil(); + __r->_M_ref_count = 2; // One more than before. + ((_RopeConcatenation*)__r)->_M_right = __new_right; + __r->_M_size = __orig_size + __slen; + if (0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + return __r; + } + } + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); + try { + __result = _S_tree_concat(__r, __right); + } + catch(...) + { + _S_unref(__r); + _S_unref(__right); + __throw_exception_again; + } + return __result; +} +#endif /* !__GC */ + +template +typename rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) +{ + if (0 == __left) { + _S_ref(__right); + return __right; + } + if (0 == __right) { + __left->_M_ref_nonnil(); + return __left; + } + if (_Rope_constants::_S_leaf == __right->_M_tag) { + if (_Rope_constants::_S_leaf == __left->_M_tag) { + if (__right->_M_size + __left->_M_size <= _S_copy_max) { + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + } + } else if (_Rope_constants::_S_concat == __left->_M_tag + && _Rope_constants::_S_leaf == + ((_RopeConcatenation*)__left)->_M_right->_M_tag) { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + __right->_M_size <= _S_copy_max) { + _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + __leftleft->_M_ref_nonnil(); + try { + return(_S_tree_concat(__leftleft, __rest)); + } + catch(...) + { + _S_unref(__leftleft); + _S_unref(__rest); + __throw_exception_again; + } + } + } + } + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); + try { + return(_S_tree_concat(__left, __right)); + } + catch(...) + { + _S_unref(__left); + _S_unref(__right); + __throw_exception_again; + } +} + +template +typename rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, + size_t __start, size_t __endp1) +{ + if (0 == __base) return 0; + size_t __len = __base->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; + + if (__endp1 >= __len) { + if (0 == __start) { + __base->_M_ref_nonnil(); + return __base; + } else { + __adj_endp1 = __len; + } + } else { + __adj_endp1 = __endp1; + } + switch(__base->_M_tag) { + case _Rope_constants::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__base; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + size_t __left_len = __left->_M_size; + _RopeRep* __result; + + if (__adj_endp1 <= __left_len) { + return _S_substring(__left, __start, __endp1); + } else if (__start >= __left_len) { + return _S_substring(__right, __start - __left_len, + __adj_endp1 - __left_len); + } + _Self_destruct_ptr __left_result( + _S_substring(__left, __start, __left_len)); + _Self_destruct_ptr __right_result( + _S_substring(__right, 0, __endp1 - __left_len)); + __result = _S_concat(__left_result, __right_result); + return __result; + } + case _Rope_constants::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__base; + _RopeLeaf* __result; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) goto lazy; +# ifdef __GC + const _CharT* __section = __l->_M_data + __start; + __result = _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + __result->_M_c_string = 0; // Not eos terminated. +# else + // We should sometimes create substring node instead. + __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR( + __l->_M_data + __start, __result_len, + __base->get_allocator()); +# endif + return __result; + } + case _Rope_constants::_S_substringfn: + // Avoid introducing multiple layers of substring nodes. + { + _RopeSubstring* __old = (_RopeSubstring*)__base; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) { + _RopeSubstring* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** + } + case _Rope_constants::_S_function: + { + _RopeFunction* __f = (_RopeFunction*)__base; + _CharT* __section; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + + if (__result_len > __lazy_threshold) goto lazy; + __section = (_CharT*) + _Data_allocate(_S_rounded_up_size(__result_len)); + try { + (*(__f->_M_fn))(__start, __result_len, __section); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING( + __section, __result_len, __base->get_allocator()); + __throw_exception_again; + } + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + } + } + lazy: + { + // Create substring node. + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, + __base->get_allocator()); + } +} + +template +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT* _M_buf_ptr; + public: + + _Rope_flatten_char_consumer(_CharT* __buffer) { + _M_buf_ptr = __buffer; + }; + ~_Rope_flatten_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; + return true; + } +}; + +template +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT _M_pattern; + public: + size_t _M_count; // Number of nonmatching characters + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + ~_Rope_find_char_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + size_t __i; + for (__i = 0; __i < __n; __i++) { + if (__leaf[__i] == _M_pattern) { + _M_count += __i; return false; + } + } + _M_count += __n; return true; + } +}; + + template + // Here _CharT is both the stream and rope character type. +class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { + private: + typedef basic_ostream<_CharT,_Traits> _Insert_ostream; + _Insert_ostream& _M_o; + public: + _Rope_insert_char_consumer(_Insert_ostream& __writer) + : _M_o(__writer) {}; + ~_Rope_insert_char_consumer() { }; + // Caller is presumed to own the ostream + bool operator() (const _CharT* __leaf, size_t __n); + // Returns true to continue traversal. +}; + +template +bool _Rope_insert_char_consumer<_CharT, _Traits>::operator() + (const _CharT* __leaf, size_t __n) +{ + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); + return true; +} + +template +bool rope<_CharT, _Alloc>::_S_apply_to_pieces( + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end) +{ + if (0 == __r) return true; + switch(__r->_M_tag) { + case _Rope_constants::_S_concat: + { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) { + size_t __left_end = std::min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) + return false; + } + if (__end > __left_len) { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = std::max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) { + return false; + } + } + } + return true; + case _Rope_constants::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); + } + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)_Alloc().allocate(__len * sizeof(_CharT)); + try { + (*(__f->_M_fn))(__begin, __len, __buffer); + __result = __c(__buffer, __len); + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); + } + catch(...) + { + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); + __throw_exception_again; + } + return __result; + } + default: + return false; + } +} + + template + inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) +{ + char __f = __o.fill(); + size_t __i; + + for (__i = 0; __i < __n; __i++) __o.put(__f); +} + + +template inline bool _Rope_is_simple(_CharT*) { return false; } +inline bool _Rope_is_simple(char*) { return true; } +inline bool _Rope_is_simple(wchar_t*) { return true; } + +template +basic_ostream<_CharT, _Traits>& operator<< (basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r) +{ + size_t __w = __o.width(); + bool __left = bool(__o.flags() & std::ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); + _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); + bool __is_simple = _Rope_is_simple((_CharT*)0); + + if (__rope_len < __w) { + __pad_len = __w - __rope_len; + } else { + __pad_len = 0; + } + if (!__is_simple) __o.width(__w/__rope_len); + try { + if (__is_simple && !__left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); + } + __r.apply_to_pieces(0, __r.size(), __c); + if (__is_simple && __left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); + } + if (!__is_simple) + __o.width(__w); + } + catch(...) + { + if (!__is_simple) + __o.width(__w); + __throw_exception_again; + } + return __o; +} + +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer) +{ + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); +} + +template +size_t +rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const +{ + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, this->_M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; +} + +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) +{ + if (0 == __r) return __buffer; + switch(__r->_M_tag) { + case _Rope_constants::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + _CharT* __rest = _S_flatten(__left, __buffer); + return _S_flatten(__right, __rest); + } + case _Rope_constants::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; + } + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + // We don't yet do anything with substring nodes. + // This needs to be fixed before ropefiles will work well. + { + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; + } + default: + return 0; + } +} + + +// This needs work for _CharT != char +template +void +rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) +{ + for (int __i = 0; __i < __indent; __i++) putchar(' '); + if (0 == __r) { + printf("NULL\n"); return; + } + if (_Rope_constants::_S_concat == __r->_M_tag) { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + +# ifdef __GC + printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", + __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); +# else + printf("Concatenation %p (rc = %ld, depth = %d, " + "len = %ld, %s balanced)\n", + __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); +# endif + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); + return; + } else { + char* __kind; + + switch (__r->_M_tag) { + case _Rope_constants::_S_leaf: + __kind = "Leaf"; + break; + case _Rope_constants::_S_function: + __kind = "Function"; + break; + case _Rope_constants::_S_substringfn: + __kind = "Function representing substring"; + break; + default: + __kind = "(corrupted kind field!)"; + } +# ifdef __GC + printf("%s %p (depth = %d, len = %ld) ", + __kind, __r, __r->_M_depth, __r->_M_size); +# else + printf("%s %p (rc = %ld, depth = %d, len = %ld) ", + __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size); +# endif + if (_S_is_one_byte_char_type((_CharT*)0)) { + const int __max_len = 40; + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); + _CharT __buffer[__max_len + 1]; + bool __too_big = __r->_M_size > __prefix->_M_size; + + _S_flatten(__prefix, __buffer); + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", + (char*)__buffer, __too_big? "...\n" : "\n"); + } else { + printf("\n"); + } + } +} + +template +const unsigned long +rope<_CharT,_Alloc>::_S_min_len[_Rope_constants::_S_max_rope_depth + 1] = { +/* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, +/* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, +/* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, +/* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, +/* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, +/* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, +/* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, +/* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, +/* 39 */165580141, /* 40 */267914296, /* 41 */433494437, +/* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, +/* 45 */2971215073u }; +// These are Fibonacci numbers < 2**32. + +template +typename rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) +{ + _RopeRep* __forest[_Rope_constants::_S_max_rope_depth + 1]; + _RopeRep* __result = 0; + int __i; + // Invariant: + // The concatenation of forest in descending order is equal to __r. + // __forest[__i]._M_size >= _S_min_len[__i] + // __forest[__i]._M_depth = __i + // References from forest are included in refcount. + + for (__i = 0; __i <= _Rope_constants::_S_max_rope_depth; ++__i) + __forest[__i] = 0; + try { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= _Rope_constants::_S_max_rope_depth; ++__i) + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__result); +# endif + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); +# if !defined(__GC) && defined(__EXCEPTIONS) + __forest[__i] = 0; +# endif + } + } + catch(...) + { + for(__i = 0; __i <= _Rope_constants::_S_max_rope_depth; __i++) + _S_unref(__forest[__i]); + __throw_exception_again; + } + + if (__result->_M_depth > _Rope_constants::_S_max_rope_depth) + __throw_length_error(__N("rope::_S_balance")); + return(__result); +} + + +template +void +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + if (__r->_M_is_balanced) { + _S_add_leaf_to_forest(__r, __forest); + return; + } + + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + + _S_add_to_forest(__c->_M_left, __forest); + _S_add_to_forest(__c->_M_right, __forest); + } +} + + +template +void +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; + + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + } + { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + for (;; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__insertee); +# endif + __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + if (__i == _Rope_constants::_S_max_rope_depth || + __insertee->_M_size < _S_min_len[__i+1]) { + __forest[__i] = __insertee; + // refcount is OK since __insertee is now dead. + return; + } + } +} + +template +_CharT +rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) +{ + __GC_CONST _CharT* __cstr = __r->_M_c_string; + + if (0 != __cstr) return __cstr[__i]; + for(;;) { + switch(__r->_M_tag) { + case _Rope_constants::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; + } else { + __r = __left; + } + } + break; + case _Rope_constants::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __l->_M_data[__i]; + } + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + _CharT __result; + + (*(__f->_M_fn))(__i, 1, &__result); + return __result; + } + } + } +} + +# ifndef __GC +// Return a uniquely referenced character slot for the given +// position, or 0 if that's not possible. +template +_CharT* +rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) +{ + _RopeRep* __clrstack[_Rope_constants::_S_max_rope_depth]; + size_t __csptr = 0; + + for(;;) { + if (__r->_M_ref_count > 1) return 0; + switch(__r->_M_tag) { + case _Rope_constants::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; + } else { + __r = __left; + } + } + break; + case _Rope_constants::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) + __clrstack[__csptr++] = __l; + while (__csptr > 0) { + -- __csptr; + _RopeRep* __d = __clrstack[__csptr]; + __d->_M_free_c_string(); + __d->_M_c_string = 0; + } + return __l->_M_data + __i; + } + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + return 0; + } + } +} +# endif /* __GC */ + +// The following could be implemented trivially using +// lexicographical_compare_3way. +// We do a little more work to avoid dealing with rope iterators for +// flat strings. +template +int +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, + const _RopeRep* __right) +{ + size_t __left_len; + size_t __right_len; + + if (0 == __right) return 0 != __left; + if (0 == __left) return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (_Rope_constants::_S_leaf == __left->_M_tag) { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (_Rope_constants::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way( + __l->_M_data, __l->_M_data + __left_len, + __r->_M_data, __r->_M_data + __right_len); + } else { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way( + __l->_M_data, __l->_M_data + __left_len, + __rstart, __rend); + } + } else { + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (_Rope_constants::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way( + __lstart, __lend, + __r->_M_data, __r->_M_data + __right_len); + } else { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way( + __lstart, __lend, + __rstart, __rend); + } + } +} + +// Assignment to reference proxies. +template +_Rope_char_ref_proxy<_CharT, _Alloc>& +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) { + _RopeRep* __old = _M_root->_M_tree_ptr; +# ifndef __GC + // First check for the case in which everything is uniquely + // referenced. In that case we can do this destructively. + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) { + *__ptr = __c; + return *this; + } +# endif + _Self_destruct_ptr __left( + _My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right( + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size)); + _Self_destruct_ptr __result_left( + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1)); + + _RopeRep* __result = + _My_rope::_S_concat(__result_left, __right); +# ifndef __GC + _RopeRep::_S_unref(__old); +# endif + _M_root->_M_tree_ptr = __result; + return *this; +} + +template +inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const +{ + if (_M_current_valid) { + return _M_current; + } else { + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); + } +} +template +_Rope_char_ptr_proxy<_CharT, _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); +} + +template +rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, + const allocator_type& __a) +: _Base(__a) +{ + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT,_Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) { + __remainder = 0; + } else { + __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest)); + uninitialized_fill_n(__rest_buffer, __rest, __c); + _S_cond_store_eos(__rest_buffer[__rest]); + try { + __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a); + __throw_exception_again; + } + } + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) { + _CharT* __base_buffer = + this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); + try { + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a); + __throw_exception_again; + } + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) { + __result = __base_rope; + } else { + __result = power(__base_rope, __exponent, + _Rope_Concat_fn<_CharT,_Alloc>()); + } + if (0 != __remainder) { + __result += __remainder_rope; + } + } else { + __result = __remainder_rope; + } + this->_M_tree_ptr = __result._M_tree_ptr; + this->_M_tree_ptr->_M_ref_nonnil(); +} + +template + _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; + +template +const _CharT* rope<_CharT,_Alloc>::c_str() const { + if (0 == this->_M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, + // but probably fast. + return _S_empty_c_str; + } + __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock); + __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string; + if (0 == __result) + { + size_t __s = size(); + __result = this->_Data_allocate(__s + 1); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_c_string = __result; + } + __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock); + return(__result); +} + +template +const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { + if (0 == this->_M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string; + if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag + && 0 != __old_c_string) { + return(__old_c_string); + } + size_t __s = size(); + _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_unref_nonnil(); + this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s, this->get_allocator()); + return(__result); +} + +// Algorithm specializations. More should be added. + +template // was templated on CharT and Alloc +void // VC++ workaround +_Rope_rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) +{ + typedef typename _Rope_iterator::value_type _CharT; + typedef typename _Rope_iterator::_allocator_type _Alloc; + + rope<_CharT,_Alloc>& __r(__first.container()); + rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index()); + rope<_CharT,_Alloc> __suffix = + __r.substr(__last.index(), __r.size() - __last.index()); + rope<_CharT,_Alloc> __part1 = + __r.substr(__middle.index(), __last.index() - __middle.index()); + rope<_CharT,_Alloc> __part2 = + __r.substr(__first.index(), __middle.index() - __first.index()); + __r = __prefix; + __r += __part1; + __r += __part2; + __r += __suffix; +} + +#if !defined(__GNUC__) +// Appears to confuse g++ +inline void rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); +} +#endif + +# if 0 +// Probably not useful for several reasons: +// - for SGIs 7.1 compiler and probably some others, +// this forces lots of rope instantiations, creating a +// code bloat and compile time problem. (Fixed in 7.2.) +// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive +// for unicode strings. Unsigned short may be a better character +// type. +inline void rotate( + _Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); +} +# endif + +} // namespace __gnu_cxx + +// Local Variables: +// mode:C++ +// End: diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/slist b/reactos/tools/ppc-build/core-headers/g++-v3/ext/slist new file mode 100644 index 00000000000..4b585203018 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/slist @@ -0,0 +1,906 @@ +// Singly-linked list implementation -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/slist + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _SLIST +#define _SLIST 1 + +#include +#include +#include +#include +#include + +namespace __gnu_cxx +{ +using std::size_t; +using std::ptrdiff_t; +using std::_Construct; +using std::_Destroy; +using std::allocator; + +struct _Slist_node_base +{ + _Slist_node_base* _M_next; +}; + +inline _Slist_node_base* +__slist_make_link(_Slist_node_base* __prev_node, + _Slist_node_base* __new_node) +{ + __new_node->_M_next = __prev_node->_M_next; + __prev_node->_M_next = __new_node; + return __new_node; +} + +inline _Slist_node_base* +__slist_previous(_Slist_node_base* __head, + const _Slist_node_base* __node) +{ + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; +} + +inline const _Slist_node_base* +__slist_previous(const _Slist_node_base* __head, + const _Slist_node_base* __node) +{ + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; +} + +inline void __slist_splice_after(_Slist_node_base* __pos, + _Slist_node_base* __before_first, + _Slist_node_base* __before_last) +{ + if (__pos != __before_first && __pos != __before_last) { + _Slist_node_base* __first = __before_first->_M_next; + _Slist_node_base* __after = __pos->_M_next; + __before_first->_M_next = __before_last->_M_next; + __pos->_M_next = __first; + __before_last->_M_next = __after; + } +} + +inline void +__slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head) +{ + _Slist_node_base* __before_last = __slist_previous(__head, 0); + if (__before_last != __head) { + _Slist_node_base* __after = __pos->_M_next; + __pos->_M_next = __head->_M_next; + __head->_M_next = 0; + __before_last->_M_next = __after; + } +} + +inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node) +{ + _Slist_node_base* __result = __node; + __node = __node->_M_next; + __result->_M_next = 0; + while(__node) { + _Slist_node_base* __next = __node->_M_next; + __node->_M_next = __result; + __result = __node; + __node = __next; + } + return __result; +} + +inline size_t __slist_size(_Slist_node_base* __node) +{ + size_t __result = 0; + for ( ; __node != 0; __node = __node->_M_next) + ++__result; + return __result; +} + +template +struct _Slist_node : public _Slist_node_base +{ + _Tp _M_data; +}; + +struct _Slist_iterator_base +{ + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Slist_node_base* _M_node; + + _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {} + void _M_incr() { _M_node = _M_node->_M_next; } + + bool operator==(const _Slist_iterator_base& __x) const { + return _M_node == __x._M_node; + } + bool operator!=(const _Slist_iterator_base& __x) const { + return _M_node != __x._M_node; + } +}; + +template +struct _Slist_iterator : public _Slist_iterator_base +{ + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; + + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _Node; + + _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {} + _Slist_iterator() : _Slist_iterator_base(0) {} + _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {} + + reference operator*() const { return ((_Node*) _M_node)->_M_data; } + pointer operator->() const { return &(operator*()); } + + _Self& operator++() + { + _M_incr(); + return *this; + } + _Self operator++(int) + { + _Self __tmp = *this; + _M_incr(); + return __tmp; + } +}; + +template +struct _Slist_base + : public _Alloc::template rebind<_Slist_node<_Tp> >::other +{ + typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc; + typedef _Alloc allocator_type; + allocator_type get_allocator() const { + return *static_cast(this); + } + + _Slist_base(const allocator_type& __a) + : _Node_alloc(__a) { this->_M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&this->_M_head, 0); } + +protected: + _Slist_node_base _M_head; + + _Slist_node<_Tp>* _M_get_node() { return _Node_alloc::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Node_alloc::deallocate(__p, 1); } + +protected: + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + _Destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); +}; + +template +_Slist_node_base* +_Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + _Destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; +} + +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template > +class slist : private _Slist_base<_Tp,_Alloc> +{ + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + +private: + typedef _Slist_base<_Tp,_Alloc> _Base; +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +private: + typedef _Slist_node<_Tp> _Node; + typedef _Slist_node_base _Node_base; + typedef _Slist_iterator_base _Iterator_base; + + _Node* _M_create_node(const value_type& __x) { + _Node* __node = this->_M_get_node(); + try { + _Construct(&__node->_M_data, __x); + __node->_M_next = 0; + } + catch(...) + { + this->_M_put_node(__node); + __throw_exception_again; + } + return __node; + } + + _Node* _M_create_node() { + _Node* __node = this->_M_get_node(); + try { + _Construct(&__node->_M_data); + __node->_M_next = 0; + } + catch(...) + { + this->_M_put_node(__node); + __throw_exception_again; + } + return __node; + } + +public: + explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + slist(size_type __n, const value_type& __x, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_fill(&this->_M_head, __n, __x); } + + explicit slist(size_type __n) : _Base(allocator_type()) + { _M_insert_after_fill(&this->_M_head, __n, value_type()); } + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&this->_M_head, __first, __last); } + + slist(const slist& __x) : _Base(__x.get_allocator()) + { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); } + + slist& operator= (const slist& __x); + + ~slist() {} + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val) + { _M_fill_assign(__n, __val); } + + void _M_fill_assign(size_type __n, const _Tp& __val); + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +public: + + iterator begin() { return iterator((_Node*)this->_M_head._M_next); } + const_iterator begin() const + { return const_iterator((_Node*)this->_M_head._M_next);} + + iterator end() { return iterator(0); } + const_iterator end() const { return const_iterator(0); } + + // Experimental new feature: before_begin() returns a + // non-dereferenceable iterator that, when incremented, yields + // begin(). This iterator may be used as the argument to + // insert_after, erase_after, etc. Note that even for an empty + // slist, before_begin() is not the same iterator as end(). It + // is always necessary to increment before_begin() at least once to + // obtain end(). + iterator before_begin() { return iterator((_Node*) &this->_M_head); } + const_iterator before_begin() const + { return const_iterator((_Node*) &this->_M_head); } + + size_type size() const { return __slist_size(this->_M_head._M_next); } + + size_type max_size() const { return size_type(-1); } + + bool empty() const { return this->_M_head._M_next == 0; } + + void swap(slist& __x) + { std::swap(this->_M_head._M_next, __x._M_head._M_next); } + +public: + + reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; } + const_reference front() const + { return ((_Node*) this->_M_head._M_next)->_M_data; } + void push_front(const value_type& __x) { + __slist_make_link(&this->_M_head, _M_create_node(__x)); + } + void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); } + void pop_front() { + _Node* __node = (_Node*) this->_M_head._M_next; + this->_M_head._M_next = __node->_M_next; + _Destroy(&__node->_M_data); + this->_M_put_node(__node); + } + + iterator previous(const_iterator __pos) { + return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node)); + } + const_iterator previous(const_iterator __pos) const { + return const_iterator((_Node*) __slist_previous(&this->_M_head, + __pos._M_node)); + } + +private: + _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { + return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); + } + + _Node* _M_insert_after(_Node_base* __pos) { + return (_Node*) (__slist_make_link(__pos, _M_create_node())); + } + + void _M_insert_after_fill(_Node_base* __pos, + size_type __n, const value_type& __x) { + for (size_type __i = 0; __i < __n; ++__i) + __pos = __slist_make_link(__pos, _M_create_node(__x)); + } + + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last) { + typedef typename _Is_integer<_InIterator>::_Integral _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) { + _M_insert_after_fill(__pos, __n, __x); + } + + template + void _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last, + __false_type) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + +public: + + iterator insert_after(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__pos._M_node, __x)); + } + + iterator insert_after(iterator __pos) { + return insert_after(__pos, value_type()); + } + + void insert_after(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__pos._M_node, __n, __x); + } + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert_after(iterator __pos, _InIterator __first, _InIterator __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + + iterator insert(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + __x)); + } + + iterator insert(iterator __pos) { + return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + value_type())); + } + + void insert(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), + __n, __x); + } + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert(iterator __pos, _InIterator __first, _InIterator __last) { + _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + __first, __last); + } + +public: + iterator erase_after(iterator __pos) { + return iterator((_Node*) this->_M_erase_after(__pos._M_node)); + } + iterator erase_after(iterator __before_first, iterator __last) { + return iterator((_Node*) this->_M_erase_after(__before_first._M_node, + __last._M_node)); + } + + iterator erase(iterator __pos) { + return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, + __pos._M_node)); + } + iterator erase(iterator __first, iterator __last) { + return (_Node*) this->_M_erase_after( + __slist_previous(&this->_M_head, __first._M_node), __last._M_node); + } + + void resize(size_type new_size, const _Tp& __x); + void resize(size_type new_size) { resize(new_size, _Tp()); } + void clear() { this->_M_erase_after(&this->_M_head, 0); } + +public: + // Moves the range [__before_first + 1, __before_last + 1) to *this, + // inserting it immediately after __pos. This is constant time. + void splice_after(iterator __pos, + iterator __before_first, iterator __before_last) + { + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, + __before_last._M_node); + } + + // Moves the element that follows __prev to *this, inserting it immediately + // after __pos. This is constant time. + void splice_after(iterator __pos, iterator __prev) + { + __slist_splice_after(__pos._M_node, + __prev._M_node, __prev._M_node->_M_next); + } + + + // Removes all of the elements from the list __x to *this, inserting + // them immediately after __pos. __x must not be *this. Complexity: + // linear in __x.size(). + void splice_after(iterator __pos, slist& __x) + { + __slist_splice_after(__pos._M_node, &__x._M_head); + } + + // Linear in distance(begin(), __pos), and linear in __x.size(). + void splice(iterator __pos, slist& __x) { + if (__x._M_head._M_next) + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + &__x._M_head, __slist_previous(&__x._M_head, 0)); + } + + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void splice(iterator __pos, slist& __x, iterator __i) { + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_node); + } + + // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), + // and in distance(__first, __last). + void splice(iterator __pos, slist& __x, iterator __first, iterator __last) + { + if (__first != __last) + __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __first._M_node), + __slist_previous(__first._M_node, __last._M_node)); + } + +public: + void reverse() { + if (this->_M_head._M_next) + this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); + } + + void remove(const _Tp& __val); + void unique(); + void merge(slist& __x); + void sort(); + + template + void remove_if(_Predicate __pred); + + template + void unique(_BinaryPredicate __pred); + + template + void merge(slist&, _StrictWeakOrdering); + + template + void sort(_StrictWeakOrdering __comp); +}; + +template +slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) +{ + if (&__x != this) { + _Node_base* __p1 = &this->_M_head; + _Node* __n1 = (_Node*) this->_M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; + } + if (__n2 == 0) + this->_M_erase_after(__p1, 0); + else + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); + } + return *this; +} + +template +void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + for ( ; __node != 0 && __n > 0 ; --__n) { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + this->_M_erase_after(__prev, 0); +} + +template template +void +slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) +{ + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_M_head._M_next; + while (__node != 0 && __first != __last) { + __node->_M_data = *__first; + __prev = __node; + __node = (_Node*) __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + this->_M_erase_after(__prev, 0); +} + +template +inline bool +operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = _SL1.end(); + const_iterator __end2 = _SL2.end(); + + const_iterator __i1 = _SL1.begin(); + const_iterator __i2 = _SL2.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; +} + + +template +inline bool +operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + return std::lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); +} + +template +inline bool +operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL1 == _SL2); +} + +template +inline bool +operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return _SL2 < _SL1; +} + +template +inline bool +operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL2 < _SL1); +} + +template +inline bool +operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + return !(_SL1 < _SL2); +} + +template +inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { + __x.swap(__y); +} + + +template +void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) +{ + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next != 0 && __len > 0) { + --__len; + __cur = __cur->_M_next; + } + if (__cur->_M_next) + this->_M_erase_after(__cur, 0); + else + _M_insert_after_fill(__cur, __len, __x); +} + +template +void slist<_Tp,_Alloc>::remove(const _Tp& __val) +{ + _Node_base* __cur = &this->_M_head; + while (__cur && __cur->_M_next) { + if (((_Node*) __cur->_M_next)->_M_data == __val) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template +void slist<_Tp,_Alloc>::unique() +{ + _Node_base* __cur = this->_M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (((_Node*)__cur)->_M_data == + ((_Node*)(__cur->_M_next))->_M_data) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } +} + +template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) +{ + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (((_Node*) __x._M_head._M_next)->_M_data < + ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template +void slist<_Tp,_Alloc>::sort() +{ + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); + } +} + +template +template +void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) +{ + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next) { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template template +void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) +{ + _Node* __cur = (_Node*) this->_M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + this->_M_erase_after(__cur); + else + __cur = (_Node*) __cur->_M_next; + } + } +} + +template template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, + _StrictWeakOrdering __comp) +{ + _Node_base* __n1 = &this->_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template template +void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) +{ + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); + } +} + +} // namespace __gnu_cxx + +namespace std +{ +// Specialization of insert_iterator so that insertions will be constant +// time rather than linear time. + +template +class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> > { +protected: + typedef __gnu_cxx::slist<_Tp, _Alloc> _Container; + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x) { + if (__i == __x.begin()) + iter = __x.before_begin(); + else + iter = __x.previous(__i); + } + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + iter = container->insert_after(iter, __value); + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_filebuf.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_filebuf.h new file mode 100644 index 00000000000..cc229728fa8 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_filebuf.h @@ -0,0 +1,162 @@ +// File descriptor layer for filebuf -*- C++ -*- + +// Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/stdio_filebuf.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _STDIO_FILEBUF_H +#define _STDIO_FILEBUF_H 1 + +#pragma GCC system_header + +#include + +namespace __gnu_cxx +{ + /** + * @class stdio_filebuf ext/stdio_filebuf.h + * @brief Provides a layer of compatibility for C/POSIX. + * + * This GNU extension provides extensions for working with standard C + * FILE*'s and POSIX file descriptors. It must be instantiated by the + * user with the type of character used in the file stream, e.g., + * stdio_filebuf. + */ + template > + class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + typedef std::size_t size_t; + + public: + /** + * deferred initialization + */ + stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {} + + /** + * @param fd An open file descriptor. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * + * This constructor associates a file stream buffer with an open + * POSIX file descriptor. The file descriptor will be automatically + * closed when the stdio_filebuf is closed/destroyed. + */ + stdio_filebuf(int __fd, std::ios_base::openmode __mode, + size_t __size = static_cast(BUFSIZ)); + + /** + * @param f An open @c FILE*. + * @param mode Same meaning as in a standard filebuf. + * @param size Optimal or preferred size of internal buffer, in chars. + * Defaults to system's @c BUFSIZ. + * + * This constructor associates a file stream buffer with an open + * C @c FILE*. The @c FILE* will not be automatically closed when the + * stdio_filebuf is closed/destroyed. + */ + stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, + size_t __size = static_cast(BUFSIZ)); + + /** + * Closes the external data stream if the file descriptor constructor + * was used. + */ + virtual + ~stdio_filebuf(); + + /** + * @return The underlying file descriptor. + * + * Once associated with an external data stream, this function can be + * used to access the underlying POSIX file descriptor. Note that + * there is no way for the library to track what you do with the + * descriptor, so be careful. + */ + int + fd() { return this->_M_file.fd(); } + + /** + * @return The underlying FILE*. + * + * This function can be used to access the underlying "C" file pointer. + * Note that there is no way for the library to track what you do + * with the file, so be careful. + */ + std::__c_file* + file() { return this->_M_file.file(); } + }; + + template + stdio_filebuf<_CharT, _Traits>::~stdio_filebuf() + { } + + template + stdio_filebuf<_CharT, _Traits>:: + stdio_filebuf(int __fd, std::ios_base::openmode __mode, size_t __size) + { + this->_M_file.sys_open(__fd, __mode); + if (this->is_open()) + { + this->_M_mode = __mode; + this->_M_buf_size = __size; + this->_M_allocate_internal_buffer(); + this->_M_reading = false; + this->_M_writing = false; + this->_M_set_buffer(-1); + } + } + + template + stdio_filebuf<_CharT, _Traits>:: + stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, + size_t __size) + { + this->_M_file.sys_open(__f, __mode); + if (this->is_open()) + { + this->_M_mode = __mode; + this->_M_buf_size = __size; + this->_M_allocate_internal_buffer(); + this->_M_reading = false; + this->_M_writing = false; + this->_M_set_buffer(-1); + } + } +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_sync_filebuf.h b/reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_sync_filebuf.h new file mode 100644 index 00000000000..367d310b4b0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ext/stdio_sync_filebuf.h @@ -0,0 +1,281 @@ +// Iostreams wrapper for stdio FILE* -*- C++ -*- + +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/stdiostream.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _STDIO_SYNC_FILEBUF_H +#define _STDIO_SYNC_FILEBUF_H 1 + +#pragma GCC system_header + +#include +#include +#include + +#ifdef _GLIBCXX_USE_WCHAR_T +#include +#endif + +namespace __gnu_cxx +{ + template > + class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + private: + // Underlying stdio FILE + std::__c_file* const _M_file; + + // Last character gotten. This is used when pbackfail is + // called from basic_streambuf::sungetc() + int_type _M_unget_buf; + + public: + explicit + stdio_sync_filebuf(std::__c_file* __f) + : _M_file(__f), _M_unget_buf(traits_type::eof()) + { } + + /** + * @return The underlying FILE*. + * + * This function can be used to access the underlying "C" file pointer. + * Note that there is no way for the library to track what you do + * with the file, so be careful. + */ + std::__c_file* const + file() { return this->_M_file; } + + protected: + int_type + syncgetc(); + + int_type + syncungetc(int_type __c); + + int_type + syncputc(int_type __c); + + virtual int_type + underflow() + { + int_type __c = this->syncgetc(); + return this->syncungetc(__c); + } + + virtual int_type + uflow() + { + // Store the gotten character in case we need to unget it. + _M_unget_buf = this->syncgetc(); + return _M_unget_buf; + } + + virtual int_type + pbackfail(int_type __c = traits_type::eof()) + { + int_type __ret; + const int_type __eof = traits_type::eof(); + + // Check if the unget or putback was requested + if (traits_type::eq_int_type(__c, __eof)) // unget + { + if (!traits_type::eq_int_type(_M_unget_buf, __eof)) + __ret = this->syncungetc(_M_unget_buf); + else // buffer invalid, fail. + __ret = __eof; + } + else // putback + __ret = this->syncungetc(__c); + + // The buffered character is no longer valid, discard it. + _M_unget_buf = __eof; + return __ret; + } + + virtual std::streamsize + xsgetn(char_type* __s, std::streamsize __n); + + virtual int_type + overflow(int_type __c = traits_type::eof()) + { + int_type __ret; + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + if (std::fflush(_M_file)) + __ret = traits_type::eof(); + else + __ret = traits_type::not_eof(__c); + } + else + __ret = this->syncputc(__c); + return __ret; + } + + virtual std::streamsize + xsputn(const char_type* __s, std::streamsize __n); + + virtual int + sync() + { return std::fflush(_M_file); } + + virtual std::streampos + seekoff(std::streamoff __off, std::ios_base::seekdir __dir, + std::ios_base::openmode = std::ios_base::in | std::ios_base::out) + { + std::streampos __ret(std::streamoff(-1)); + int __whence; + if (__dir == std::ios_base::beg) + __whence = SEEK_SET; + else if (__dir == std::ios_base::cur) + __whence = SEEK_CUR; + else + __whence = SEEK_END; +#ifdef _GLIBCXX_USE_LFS + if (!fseeko64(_M_file, __off, __whence)) + __ret = std::streampos(ftello64(_M_file)); +#else + if (!fseek(_M_file, __off, __whence)) + __ret = std::streampos(std::ftell(_M_file)); +#endif + return __ret; + } + + virtual std::streampos + seekpos(std::streampos __pos, + std::ios_base::openmode __mode = + std::ios_base::in | std::ios_base::out) + { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); } + }; + + template<> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncgetc() + { return std::getc(_M_file); } + + template<> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncungetc(int_type __c) + { return std::ungetc(__c, _M_file); } + + template<> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncputc(int_type __c) + { return std::putc(__c, _M_file); } + + template<> + inline std::streamsize + stdio_sync_filebuf::xsgetn(char* __s, std::streamsize __n) + { + std::streamsize __ret = std::fread(__s, 1, __n, _M_file); + if (__ret > 0) + _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); + else + _M_unget_buf = traits_type::eof(); + return __ret; + } + + template<> + inline std::streamsize + stdio_sync_filebuf::xsputn(const char* __s, std::streamsize __n) + { return std::fwrite(__s, 1, __n, _M_file); } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncgetc() + { return std::getwc(_M_file); } + + template<> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncungetc(int_type __c) + { return std::ungetwc(__c, _M_file); } + + template<> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncputc(int_type __c) + { return std::putwc(__c, _M_file); } + + template<> + inline std::streamsize + stdio_sync_filebuf::xsgetn(wchar_t* __s, std::streamsize __n) + { + std::streamsize __ret = 0; + const int_type __eof = traits_type::eof(); + while (__n--) + { + int_type __c = this->syncgetc(); + if (traits_type::eq_int_type(__c, __eof)) + break; + __s[__ret] = traits_type::to_char_type(__c); + ++__ret; + } + + if (__ret > 0) + _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); + else + _M_unget_buf = traits_type::eof(); + return __ret; + } + + template<> + inline std::streamsize + stdio_sync_filebuf::xsputn(const wchar_t* __s, + std::streamsize __n) + { + std::streamsize __ret = 0; + const int_type __eof = traits_type::eof(); + while (__n--) + { + if (traits_type::eq_int_type(this->syncputc(*__s++), __eof)) + break; + ++__ret; + } + return __ret; + } +#endif + +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class stdio_sync_filebuf; +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class stdio_sync_filebuf; +#endif +#endif +} // namespace __gnu_cxx + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/fstream b/reactos/tools/ppc-build/core-headers/g++-v3/fstream new file mode 100644 index 00000000000..ca0216057cc --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/fstream @@ -0,0 +1,847 @@ +// File based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +/** @file fstream + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_FSTREAM +#define _GLIBCXX_FSTREAM 1 + +#pragma GCC system_header + +#include +#include +#include // For codecvt +#include // For SEEK_SET, SEEK_CUR, SEEK_END, BUFSIZ +#include +#include + +#pragma GCC visibility push(default) + +namespace std +{ + // [27.8.1.1] template class basic_filebuf + /** + * @brief The actual work of input and output (for files). + * + * This class associates both its input and output sequence with an + * external disk file, and maintains a joint file position for both + * sequences. Many of its sematics are described in terms of similar + * behavior in the Standard C Library's @c FILE streams. + */ + // Requirements on traits_type, specific to this class: + // traits_type::pos_type must be fpos + // traits_type::off_type must be streamoff + // traits_type::state_type must be Assignable and DefaultConstructable, + // and traits_type::state_type() must be the initial state for codecvt. + template + class basic_filebuf : public basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + //@{ + /** + * @if maint + * @doctodo + * @endif + */ + typedef basic_streambuf __streambuf_type; + typedef basic_filebuf __filebuf_type; + typedef __basic_file __file_type; + typedef typename traits_type::state_type __state_type; + typedef codecvt __codecvt_type; + //@} + + friend class ios_base; // For sync_with_stdio. + + protected: + // Data Members: + // MT lock inherited from libio or other low-level io library. + /** + * @if maint + * @doctodo + * @endif + */ + __c_lock _M_lock; + + // External buffer. + /** + * @if maint + * @doctodo + * @endif + */ + __file_type _M_file; + + /** + * @if maint + * Place to stash in || out || in | out settings for current filebuf. + * @endif + */ + ios_base::openmode _M_mode; + + // Beginning state type for codecvt. + /** + * @if maint + * @doctodo + * @endif + */ + __state_type _M_state_beg; + + // During output, the state that corresponds to pptr(), + // during input, the state that corresponds to egptr() and + // _M_ext_next. + /** + * @if maint + * @doctodo + * @endif + */ + __state_type _M_state_cur; + + // Not used for output. During input, the state that corresponds + // to eback() and _M_ext_buf. + /** + * @if maint + * @doctodo + * @endif + */ + __state_type _M_state_last; + + /** + * @if maint + * Pointer to the beginning of internal buffer. + * @endif + */ + char_type* _M_buf; + + /** + * @if maint + * Actual size of internal buffer. This number is equal to the size + * of the put area + 1 position, reserved for the overflow char of + * a full area. + * @endif + */ + size_t _M_buf_size; + + // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. + /** + * @if maint + * @doctodo + * @endif + */ + bool _M_buf_allocated; + + /** + * @if maint + * _M_reading == false && _M_writing == false for 'uncommitted' mode; + * _M_reading == true for 'read' mode; + * _M_writing == true for 'write' mode; + * + * NB: _M_reading == true && _M_writing == true is unused. + * @endif + */ + bool _M_reading; + bool _M_writing; + + //@{ + /** + * @if maint + * Necessary bits for putback buffer management. + * + * @note pbacks of over one character are not currently supported. + * @endif + */ + char_type _M_pback; + char_type* _M_pback_cur_save; + char_type* _M_pback_end_save; + bool _M_pback_init; + //@} + + // Cached codecvt facet. + const __codecvt_type* _M_codecvt; + + /** + * @if maint + * Buffer for external characters. Used for input when + * codecvt::always_noconv() == false. When valid, this corresponds + * to eback(). + * @endif + */ + char* _M_ext_buf; + + /** + * @if maint + * Size of buffer held by _M_ext_buf. + * @endif + */ + streamsize _M_ext_buf_size; + + /** + * @if maint + * Pointers into the buffer held by _M_ext_buf that delimit a + * subsequence of bytes that have been read but not yet converted. + * When valid, _M_ext_next corresponds to egptr(). + * @endif + */ + const char* _M_ext_next; + char* _M_ext_end; + + /** + * @if maint + * Initializes pback buffers, and moves normal buffers to safety. + * Assumptions: + * _M_in_cur has already been moved back + * @endif + */ + void + _M_create_pback() + { + if (!_M_pback_init) + { + _M_pback_cur_save = this->gptr(); + _M_pback_end_save = this->egptr(); + this->setg(&_M_pback, &_M_pback, &_M_pback + 1); + _M_pback_init = true; + } + } + + /** + * @if maint + * Deactivates pback buffer contents, and restores normal buffer. + * Assumptions: + * The pback buffer has only moved forward. + * @endif + */ + void + _M_destroy_pback() throw() + { + if (_M_pback_init) + { + // Length _M_in_cur moved in the pback buffer. + _M_pback_cur_save += this->gptr() != this->eback(); + this->setg(this->_M_buf, _M_pback_cur_save, _M_pback_end_save); + _M_pback_init = false; + } + } + + public: + // Constructors/destructor: + /** + * @brief Does not open any files. + * + * The default constructor initializes the parent class using its + * own default ctor. + */ + basic_filebuf(); + + /** + * @brief The destructor closes the file first. + */ + virtual + ~basic_filebuf() + { this->close(); } + + // Members: + /** + * @brief Returns true if the external file is open. + */ + bool + is_open() const throw() { return _M_file.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * @return @c this on success, NULL on failure + * + * If a file is already open, this function immediately fails. + * Otherwise it tries to open the file named @a s using the flags + * given in @a mode. + * + * [Table 92 gives the relation between openmode combinations and the + * equivalent fopen() flags, but the table has not been copied yet.] + */ + __filebuf_type* + open(const char* __s, ios_base::openmode __mode); + + /** + * @brief Closes the currently associated file. + * @return @c this on success, NULL on failure + * + * If no file is currently open, this function immediately fails. + * + * If a "put buffer area" exists, @c overflow(eof) is called to flush + * all the characters. The file is then closed. + * + * If any operations fail, this function also fails. + */ + __filebuf_type* + close() throw(); + + protected: + /** + * @if maint + * @doctodo + * @endif + */ + void + _M_allocate_internal_buffer(); + + /** + * @if maint + * @doctodo + * @endif + */ + void + _M_destroy_internal_buffer() throw(); + + // [27.8.1.4] overridden virtual functions + // [documentation is inherited] + virtual streamsize + showmanyc(); + + // Stroustrup, 1998, p. 628 + // underflow() and uflow() functions are called to get the next + // charater from the real input source when the buffer is empty. + // Buffered input uses underflow() + + // [documentation is inherited] + virtual int_type + underflow(); + + // [documentation is inherited] + virtual int_type + pbackfail(int_type __c = _Traits::eof()); + + // Stroustrup, 1998, p 648 + // The overflow() function is called to transfer characters to the + // real output destination when the buffer is full. A call to + // overflow(c) outputs the contents of the buffer plus the + // character c. + // 27.5.2.4.5 + // Consume some sequence of the characters in the pending sequence. + /** + * @if maint + * @doctodo + * @endif + */ + virtual int_type + overflow(int_type __c = _Traits::eof()); + + // Convert internal byte sequence to external, char-based + // sequence via codecvt. + /** + * @if maint + * @doctodo + * @endif + */ + bool + _M_convert_to_external(char_type*, streamsize); + + /** + * @brief Manipulates the buffer. + * @param s Pointer to a buffer area. + * @param n Size of @a s. + * @return @c this + * + * If no file has been opened, and both @a s and @a n are zero, then + * the stream becomes unbuffered. Otherwise, @c s is used as a + * buffer; see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 + * for more. + */ + virtual __streambuf_type* + setbuf(char_type* __s, streamsize __n); + + // [documentation is inherited] + virtual pos_type + seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // [documentation is inherited] + virtual pos_type + seekpos(pos_type __pos, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // Common code for seekoff and seekpos + /** + * @if maint + * @doctodo + * @endif + */ + pos_type + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); + + // [documentation is inherited] + virtual int + sync(); + + // [documentation is inherited] + virtual void + imbue(const locale& __loc); + + // [documentation is inherited] + virtual streamsize + xsgetn(char_type* __s, streamsize __n); + + // [documentation is inherited] + virtual streamsize + xsputn(const char_type* __s, streamsize __n); + + // Flushes output buffer, then writes unshift sequence. + /** + * @if maint + * @doctodo + * @endif + */ + bool + _M_terminate_output(); + + /** + * @if maint + * This function sets the pointers of the internal buffer, both get + * and put areas. Typically: + * + * __off == egptr() - eback() upon underflow/uflow ('read' mode); + * __off == 0 upon overflow ('write' mode); + * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). + * + * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size + * reflects the actual allocated memory and the last cell is reserved + * for the overflow char of a full put area. + * @endif + */ + void + _M_set_buffer(streamsize __off) + { + const bool __testin = this->_M_mode & ios_base::in; + const bool __testout = this->_M_mode & ios_base::out; + + if (__testin && __off > 0) + this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off); + else + this->setg(this->_M_buf, this->_M_buf, this->_M_buf); + + if (__testout && __off == 0 && this->_M_buf_size > 1 ) + this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1); + else + this->setp(NULL, NULL); + } + }; + + // [27.8.1.5] Template class basic_ifstream + /** + * @brief Controlling input for files. + * + * This class supports reading from named files, using the inherited + * functions from std::basic_istream. To control the associated + * sequence, an instance of std::basic_filebuf is used, which this page + * refers to as @c sb. + */ + template + class basic_ifstream : public basic_istream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf __filebuf_type; + typedef basic_istream __istream_type; + + private: + /** + * @if maint + * @doctodo + * @endif + */ + __filebuf_type _M_filebuf; + + public: + // Constructors/Destructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + basic_ifstream() : __istream_type(), _M_filebuf() + { this->init(&_M_filebuf); } + + /** + * @brief Create an input file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::in is automatically included in @a mode. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + explicit + basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + ~basic_ifstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __filebuf_type* + rdbuf() const + { return const_cast<__filebuf_type*>(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool + is_open() { return _M_filebuf.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode|in). If that function + * fails, @c failbit is set in the stream's error state. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + void + open(const char* __s, ios_base::openmode __mode = ios_base::in) + { + if (!_M_filebuf.open(__s, __mode | ios_base::in)) + this->setstate(ios_base::failbit); + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + close() + { + if (!_M_filebuf.close()) + this->setstate(ios_base::failbit); + } + }; + + + // [27.8.1.8] Template class basic_ofstream + /** + * @brief Controlling output for files. + * + * This class supports reading from named files, using the inherited + * functions from std::basic_ostream. To control the associated + * sequence, an instance of std::basic_filebuf is used, which this page + * refers to as @c sb. + */ + template + class basic_ofstream : public basic_ostream<_CharT,_Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf __filebuf_type; + typedef basic_ostream __ostream_type; + + private: + /** + * @if maint + * @doctodo + * @endif + */ + __filebuf_type _M_filebuf; + + public: + // Constructors: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + basic_ofstream(): __ostream_type(), _M_filebuf() + { this->init(&_M_filebuf); } + + /** + * @brief Create an output file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::out|ios_base::trunc is automatically included in + * @a mode. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + explicit + basic_ofstream(const char* __s, + ios_base::openmode __mode = ios_base::out|ios_base::trunc) + : __ostream_type(), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + ~basic_ofstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __filebuf_type* + rdbuf() const + { return const_cast<__filebuf_type*>(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool + is_open() { return _M_filebuf.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that + * function fails, @c failbit is set in the stream's error state. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + void + open(const char* __s, + ios_base::openmode __mode = ios_base::out | ios_base::trunc) + { + if (!_M_filebuf.open(__s, __mode | ios_base::out)) + this->setstate(ios_base::failbit); + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + close() + { + if (!_M_filebuf.close()) + this->setstate(ios_base::failbit); + } + }; + + + // [27.8.1.11] Template class basic_fstream + /** + * @brief Controlling intput and output for files. + * + * This class supports reading from and writing to named files, using + * the inherited functions from std::basic_iostream. To control the + * associated sequence, an instance of std::basic_filebuf is used, which + * this page refers to as @c sb. + */ + template + class basic_fstream : public basic_iostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_filebuf __filebuf_type; + typedef basic_ios __ios_type; + typedef basic_iostream __iostream_type; + + private: + /** + * @if maint + * @doctodo + * @endif + */ + __filebuf_type _M_filebuf; + + public: + // Constructors/destructor: + /** + * @brief Default constructor. + * + * Initializes @c sb using its default constructor, and passes + * @c &sb to the base class initializer. Does not open any files + * (you haven't given it a filename to open). + */ + basic_fstream() + : __iostream_type(), _M_filebuf() + { this->init(&_M_filebuf); } + + /** + * @brief Create an input/output file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + explicit + basic_fstream(const char* __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __iostream_type(NULL), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } + + /** + * @brief The destructor does nothing. + * + * The file is closed by the filebuf object, not the formatting + * stream. + */ + ~basic_fstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_filebuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __filebuf_type* + rdbuf() const + { return const_cast<__filebuf_type*>(&_M_filebuf); } + + /** + * @brief Wrapper to test for an open file. + * @return @c rdbuf()->is_open() + */ + bool + is_open() { return _M_filebuf.is_open(); } + + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode). If that + * function fails, @c failbit is set in the stream's error state. + * + * Tip: When using std::string to hold the filename, you must use + * .c_str() before passing it to this constructor. + */ + void + open(const char* __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { + if (!_M_filebuf.open(__s, __mode)) + this->setstate(ios_base::failbit); + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + close() + { + if (!_M_filebuf.close()) + this->setstate(ios_base::failbit); + } + }; +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#pragma GCC visibility pop + +#endif /* _GLIBCXX_FSTREAM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/functional b/reactos/tools/ppc-build/core-headers/g++-v3/functional new file mode 100644 index 00000000000..6819f20b6f0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/functional @@ -0,0 +1,58 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file functional + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_FUNCTIONAL +#define _GLIBCXX_FUNCTIONAL 1 + +#pragma GCC system_header + +#include +#include +#include + +#endif /* _GLIBCXX_FUNCTIONAL */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/iomanip b/reactos/tools/ppc-build/core-headers/g++-v3/iomanip new file mode 100644 index 00000000000..0d965c28bf9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/iomanip @@ -0,0 +1,300 @@ +// Standard stream manipulators -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.3 Standard manipulators +// + +/** @file iomanip + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_IOMANIP +#define _GLIBCXX_IOMANIP 1 + +#pragma GCC system_header + +#include +#include +#include + +namespace std +{ + // [27.6.3] standard manipulators + // Also see DR 183. + + struct _Resetiosflags { ios_base::fmtflags _M_mask; }; + + /** + * @brief Manipulator for @c setf. + * @param mask A format flags mask. + * + * Sent to a stream object, this manipulator resets the specified flags, + * via @e stream.setf(0,mask). + */ + inline _Resetiosflags + resetiosflags(ios_base::fmtflags __mask) + { + _Resetiosflags __x; + __x._M_mask = __mask; + return __x; + } + + template + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Resetiosflags __f) + { + __is.setf(ios_base::fmtflags(0), __f._M_mask); + return __is; + } + + template + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Resetiosflags __f) + { + __os.setf(ios_base::fmtflags(0), __f._M_mask); + return __os; + } + + + struct _Setiosflags { ios_base::fmtflags _M_mask; }; + + /** + * @brief Manipulator for @c setf. + * @param mask A format flags mask. + * + * Sent to a stream object, this manipulator sets the format flags + * to @a mask. + */ + inline _Setiosflags + setiosflags(ios_base::fmtflags __mask) + { + _Setiosflags __x; + __x._M_mask = __mask; + return __x; + } + + template + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setiosflags __f) + { + __is.setf(__f._M_mask); + return __is; + } + + template + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setiosflags __f) + { + __os.setf(__f._M_mask); + return __os; + } + + + struct _Setbase { int _M_base; }; + + /** + * @brief Manipulator for @c setf. + * @param base A numeric base. + * + * Sent to a stream object, this manipulator changes the + * @c ios_base::basefield flags to @c oct, @c dec, or @c hex when @a base + * is 8, 10, or 16, accordingly, and to 0 if @a base is any other value. + */ + inline _Setbase + setbase(int __base) + { + _Setbase __x; + __x._M_base = __base; + return __x; + } + + template + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setbase __f) + { + __is.setf(__f._M_base == 8 ? ios_base::oct : + __f._M_base == 10 ? ios_base::dec : + __f._M_base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __is; + } + + template + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setbase __f) + { + __os.setf(__f._M_base == 8 ? ios_base::oct : + __f._M_base == 10 ? ios_base::dec : + __f._M_base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return __os; + } + + + template + struct _Setfill { _CharT _M_c; }; + + /** + * @brief Manipulator for @c fill. + * @param c The new fill character. + * + * Sent to a stream object, this manipulator calls @c fill(c) for that + * object. + */ + template + inline _Setfill<_CharT> + setfill(_CharT __c) + { + _Setfill<_CharT> __x; + __x._M_c = __c; + return __x; + } + + template + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setfill<_CharT> __f) + { + __is.fill(__f._M_c); + return __is; + } + + template + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setfill<_CharT> __f) + { + __os.fill(__f._M_c); + return __os; + } + + + struct _Setprecision { int _M_n; }; + + /** + * @brief Manipulator for @c precision. + * @param n The new precision. + * + * Sent to a stream object, this manipulator calls @c precision(n) for + * that object. + */ + inline _Setprecision + setprecision(int __n) + { + _Setprecision __x; + __x._M_n = __n; + return __x; + } + + template + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setprecision __f) + { + __is.precision(__f._M_n); + return __is; + } + + template + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setprecision __f) + { + __os.precision(__f._M_n); + return __os; + } + + + struct _Setw { int _M_n; }; + + /** + * @brief Manipulator for @c width. + * @param n The new width. + * + * Sent to a stream object, this manipulator calls @c width(n) for + * that object. + */ + inline _Setw + setw(int __n) + { + _Setw __x; + __x._M_n = __n; + return __x; + } + + template + inline basic_istream<_CharT,_Traits>& + operator>>(basic_istream<_CharT,_Traits>& __is, _Setw __f) + { + __is.width(__f._M_n); + return __is; + } + + template + inline basic_ostream<_CharT,_Traits>& + operator<<(basic_ostream<_CharT,_Traits>& __os, _Setw __f) + { + __os.width(__f._M_n); + return __os; + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template ostream& operator<<(ostream&, _Setfill); + extern template ostream& operator<<(ostream&, _Setiosflags); + extern template ostream& operator<<(ostream&, _Resetiosflags); + extern template ostream& operator<<(ostream&, _Setbase); + extern template ostream& operator<<(ostream&, _Setprecision); + extern template ostream& operator<<(ostream&, _Setw); + extern template istream& operator>>(istream&, _Setfill); + extern template istream& operator>>(istream&, _Setiosflags); + extern template istream& operator>>(istream&, _Resetiosflags); + extern template istream& operator>>(istream&, _Setbase); + extern template istream& operator>>(istream&, _Setprecision); + extern template istream& operator>>(istream&, _Setw); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template wostream& operator<<(wostream&, _Setfill); + extern template wostream& operator<<(wostream&, _Setiosflags); + extern template wostream& operator<<(wostream&, _Resetiosflags); + extern template wostream& operator<<(wostream&, _Setbase); + extern template wostream& operator<<(wostream&, _Setprecision); + extern template wostream& operator<<(wostream&, _Setw); + extern template wistream& operator>>(wistream&, _Setfill); + extern template wistream& operator>>(wistream&, _Setiosflags); + extern template wistream& operator>>(wistream&, _Resetiosflags); + extern template wistream& operator>>(wistream&, _Setbase); + extern template wistream& operator>>(wistream&, _Setprecision); + extern template wistream& operator>>(wistream&, _Setw); +#endif +#endif +} // namespace std + +#endif /* _GLIBCXX_IOMANIP */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ios b/reactos/tools/ppc-build/core-headers/g++-v3/ios new file mode 100644 index 00000000000..596458f1ede --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ios @@ -0,0 +1,53 @@ +// Iostreams base classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4 Iostreams base classes +// + +/** @file ios + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_IOS +#define _GLIBCXX_IOS 1 + +#pragma GCC system_header + +#include +#include // For ios_base::failure +#include // For char_traits, streamoff, streamsize, fpos +#include // For SEEK_SET, SEEK_CUR, SEEK_END +#include // For class locale +#include // For ios_base declarations. +#include +#include + +#endif /* _GLIBCXX_IOS */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/iosfwd b/reactos/tools/ppc-build/core-headers/g++-v3/iosfwd new file mode 100644 index 00000000000..050b9e8bab7 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/iosfwd @@ -0,0 +1,168 @@ +// Forwarding declarations -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.2 Forward declarations +// + +/** @file iosfwd + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_IOSFWD +#define _GLIBCXX_IOSFWD 1 + +#pragma GCC system_header + +#include +#include +#include +#include // For isspace, etc. +#include // For string forward declarations. +#include +#include + +namespace std +{ + template > + class basic_ios; + + template > + class basic_streambuf; + + template > + class basic_istream; + + template > + class basic_ostream; + + template > + class basic_iostream; + + template, + typename _Alloc = allocator<_CharT> > + class basic_stringbuf; + + template, + typename _Alloc = allocator<_CharT> > + class basic_istringstream; + + template, + typename _Alloc = allocator<_CharT> > + class basic_ostringstream; + + template, + typename _Alloc = allocator<_CharT> > + class basic_stringstream; + + template > + class basic_filebuf; + + template > + class basic_ifstream; + + template > + class basic_ofstream; + + template > + class basic_fstream; + + template > + class istreambuf_iterator; + + template > + class ostreambuf_iterator; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // Not included. (??? Apparently no LWG number?) + class ios_base; + + /** + * @defgroup s27_2_iosfwd I/O Forward Declarations + * + * Nearly all of the I/O classes are parameterized on the type of + * characters they read and write. (The major exception is ios_base at + * the top of the hierarchy.) This is a change from pre-Standard + * streams, which were not templates. + * + * For ease of use and compatibility, all of the basic_* I/O-related + * classes are given typedef names for both of the builtin character + * widths (wide and narrow). The typedefs are the same as the + * pre-Standard names, for example: + * + * @code + * typedef basic_ifstream ifstream; + * @endcode + * + * Because properly forward-declaring these classes can be difficult, you + * should not do it yourself. Instead, include the <iosfwd> + * header, which contains only declarations of all the I/O classes as + * well as the typedefs. Trying to forward-declare the typedefs + * themselves (e.g., "class ostream;") is not valid ISO C++. + * + * For more specific declarations, see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10 + * + * @{ + */ + typedef basic_ios ios; ///< @isiosfwd + typedef basic_streambuf streambuf; ///< @isiosfwd + typedef basic_istream istream; ///< @isiosfwd + typedef basic_ostream ostream; ///< @isiosfwd + typedef basic_iostream iostream; ///< @isiosfwd + typedef basic_stringbuf stringbuf; ///< @isiosfwd + typedef basic_istringstream istringstream; ///< @isiosfwd + typedef basic_ostringstream ostringstream; ///< @isiosfwd + typedef basic_stringstream stringstream; ///< @isiosfwd + typedef basic_filebuf filebuf; ///< @isiosfwd + typedef basic_ifstream ifstream; ///< @isiosfwd + typedef basic_ofstream ofstream; ///< @isiosfwd + typedef basic_fstream fstream; ///< @isiosfwd + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef basic_ios wios; ///< @isiosfwd + typedef basic_streambuf wstreambuf; ///< @isiosfwd + typedef basic_istream wistream; ///< @isiosfwd + typedef basic_ostream wostream; ///< @isiosfwd + typedef basic_iostream wiostream; ///< @isiosfwd + typedef basic_stringbuf wstringbuf; ///< @isiosfwd + typedef basic_istringstream wistringstream; ///< @isiosfwd + typedef basic_ostringstream wostringstream; ///< @isiosfwd + typedef basic_stringstream wstringstream; ///< @isiosfwd + typedef basic_filebuf wfilebuf; ///< @isiosfwd + typedef basic_ifstream wifstream; ///< @isiosfwd + typedef basic_ofstream wofstream; ///< @isiosfwd + typedef basic_fstream wfstream; ///< @isiosfwd +#endif + /** @} */ +} // namespace std + +#endif /* _GLIBCXX_IOSFWD */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/iostream b/reactos/tools/ppc-build/core-headers/g++-v3/iostream new file mode 100644 index 00000000000..f5049db4a91 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/iostream @@ -0,0 +1,80 @@ +// Standard iostream objects -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.3 Standard iostream objects +// + +/** @file iostream + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_IOSTREAM +#define _GLIBCXX_IOSTREAM 1 + +#pragma GCC system_header + +#include +#include +#include + +namespace std +{ + /** + * @name Standard Stream Objects + * + * The <iostream> header declares the eight standard stream + * objects. For other declarations, see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10 and the + * @link s27_2_iosfwd I/O forward declarations @endlink + * + * They are required by default to cooperate with the global C library's + * @c FILE streams, and to be available during program startup and + * termination. For more information, see the HOWTO linked to above. + */ + //@{ + extern istream cin; ///< Linked to standard input + extern ostream cout; ///< Linked to standard output + extern ostream cerr; ///< Linked to standard error (unbuffered) + extern ostream clog; ///< Linked to standard error (buffered) + +#ifdef _GLIBCXX_USE_WCHAR_T + extern wistream wcin; ///< Linked to standard input + extern wostream wcout; ///< Linked to standard output + extern wostream wcerr; ///< Linked to standard error (unbuffered) + extern wostream wclog; ///< Linked to standard error (buffered) +#endif + //@} + + // For construction of filebuffers for cout, cin, cerr, clog et. al. + static ios_base::Init __ioinit; +} // namespace std + +#endif /* _GLIBCXX_IOSTREAM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/istream b/reactos/tools/ppc-build/core-headers/g++-v3/istream new file mode 100644 index 00000000000..5822ad7d963 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/istream @@ -0,0 +1,778 @@ +// Input streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +/** @file istream + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_ISTREAM +#define _GLIBCXX_ISTREAM 1 + +#pragma GCC system_header + +#include +#include // For numeric_limits + +#pragma GCC visibility push(default) + +namespace std +{ + // [27.6.1.1] Template class basic_istream + /** + * @brief Controlling input. + * + * This is the base class for all input streams. It provides text + * formatting of all builtin types, and communicates with any class + * derived from basic_streambuf to do the actual input. + */ + template + class basic_istream : virtual public basic_ios<_CharT, _Traits> + { + public: + // Types (inherited from basic_ios (27.4.4)): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; + typedef ctype<_CharT> __ctype_type; + + template + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2&); + + template + friend basic_istream<_CharT2, _Traits2>& + operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); + + protected: + // Data Members: + /** + * @if maint + * The number of characters extracted in the previous unformatted + * function; see gcount(). + * @endif + */ + streamsize _M_gcount; + + public: + // [27.6.1.1.1] constructor/destructor + /** + * @brief Base constructor. + * + * This ctor is almost never called by the user directly, rather from + * derived classes' initialization lists, which pass a pointer to + * their own stream buffer. + */ + explicit + basic_istream(__streambuf_type* __sb): _M_gcount(streamsize(0)) + { this->init(__sb); } + + /** + * @brief Base destructor. + * + * This does very little apart from providing a virtual base dtor. + */ + virtual + ~basic_istream() + { _M_gcount = streamsize(0); } + + // [27.6.1.1.2] prefix/suffix + class sentry; + friend class sentry; + + // [27.6.1.2] formatted input + // [27.6.1.2.3] basic_istream::operator>> + //@{ + /** + * @brief Interface for manipulators. + * + * Manuipulators such as @c std::ws and @c std::dec use these + * functions in constructs like "std::cin >> std::ws". For more + * information, see the iomanip header. + */ + inline __istream_type& + operator>>(__istream_type& (*__pf)(__istream_type&)); + + inline __istream_type& + operator>>(__ios_type& (*__pf)(__ios_type&)); + + inline __istream_type& + operator>>(ios_base& (*__pf)(ios_base&)); + //@} + + // [27.6.1.2.2] arithmetic extractors + /** + * @name Arithmetic Extractors + * + * All the @c operator>> functions (aka formatted input + * functions) have some common behavior. Each starts by + * constructing a temporary object of type std::basic_istream::sentry + * with the second argument (noskipws) set to false. This has several + * effects, concluding with the setting of a status flag; see the + * sentry documentation for more. + * + * If the sentry status is good, the function tries to extract + * whatever data is appropriate for the type of the argument. + * + * If an exception is thrown during extraction, ios_base::badbit + * will be turned on in the stream's error state without causing an + * ios_base::failure to be thrown. The original exception will then + * be rethrown. + */ + //@{ + /** + * @brief Basic arithmetic extractors + * @param A variable of builtin type. + * @return @c *this if successful + * + * These functions use the stream's current locale (specifically, the + * @c num_get facet) to parse the input data. + */ + __istream_type& + operator>>(bool& __n); + + __istream_type& + operator>>(short& __n); + + __istream_type& + operator>>(unsigned short& __n); + + __istream_type& + operator>>(int& __n); + + __istream_type& + operator>>(unsigned int& __n); + + __istream_type& + operator>>(long& __n); + + __istream_type& + operator>>(unsigned long& __n); + +#ifdef _GLIBCXX_USE_LONG_LONG + __istream_type& + operator>>(long long& __n); + + __istream_type& + operator>>(unsigned long long& __n); +#endif + + __istream_type& + operator>>(float& __f); + + __istream_type& + operator>>(double& __f); + + __istream_type& + operator>>(long double& __f); + + __istream_type& + operator>>(void*& __p); + + /** + * @brief Extracting into another streambuf. + * @param sb A pointer to a streambuf + * + * This function behaves like one of the basic arithmetic extractors, + * in that it also constructs a sentry object and has the same error + * handling behavior. + * + * If @a sb is NULL, the stream will set failbit in its error state. + * + * Characters are extracted from this stream and inserted into the + * @a sb streambuf until one of the following occurs: + * + * - the input stream reaches end-of-file, + * - insertion into the output buffer fails (in this case, the + * character that would have been inserted is not extracted), or + * - an exception occurs (and in this case is caught) + * + * If the function inserts no characters, failbit is set. + */ + __istream_type& + operator>>(__streambuf_type* __sb); + //@} + + // [27.6.1.3] unformatted input + /** + * @brief Character counting + * @return The number of characters extracted by the previous + * unformatted input function dispatched for this stream. + */ + inline streamsize + gcount() const + { return _M_gcount; } + + /** + * @name Unformatted Input Functions + * + * All the unformatted input functions have some common behavior. + * Each starts by constructing a temporary object of type + * std::basic_istream::sentry with the second argument (noskipws) + * set to true. This has several effects, concluding with the + * setting of a status flag; see the sentry documentation for more. + * + * If the sentry status is good, the function tries to extract + * whatever data is appropriate for the type of the argument. + * + * The number of characters extracted is stored for later retrieval + * by gcount(). + * + * If an exception is thrown during extraction, ios_base::badbit + * will be turned on in the stream's error state without causing an + * ios_base::failure to be thrown. The original exception will then + * be rethrown. + */ + //@{ + /** + * @brief Simple extraction. + * @return A character, or eof(). + * + * Tries to extract a character. If none are available, sets failbit + * and returns traits::eof(). + */ + int_type + get(); + + /** + * @brief Simple extraction. + * @param c The character in which to store data. + * @return *this + * + * Tries to extract a character and store it in @a c. If none are + * available, sets failbit and returns traits::eof(). + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __istream_type& + get(char_type& __c); + + /** + * @brief Simple multiple-character extraction. + * @param s Pointer to an array. + * @param n Maximum number of characters to store in @a s. + * @param delim A "stop" character. + * @return *this + * + * Characters are extracted and stored into @a s until one of the + * following happens: + * + * - @c n-1 characters are stored + * - the input sequence reaches EOF + * - the next character equals @a delim, in which case the character + * is not extracted + * + * If no characters are stored, failbit is set in the stream's error + * state. + * + * In any case, a null character is stored into the next location in + * the array. + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __istream_type& + get(char_type* __s, streamsize __n, char_type __delim); + + /** + * @brief Simple multiple-character extraction. + * @param s Pointer to an array. + * @param n Maximum number of characters to store in @a s. + * @return *this + * + * Returns @c get(s,n,widen('\n')). + */ + inline __istream_type& + get(char_type* __s, streamsize __n) + { return this->get(__s, __n, this->widen('\n')); } + + /** + * @brief Extraction into another streambuf. + * @param sb A streambuf in which to store data. + * @param delim A "stop" character. + * @return *this + * + * Characters are extracted and inserted into @a sb until one of the + * following happens: + * + * - the input sequence reaches EOF + * - insertion into the output buffer fails (in this case, the + * character that would have been inserted is not extracted) + * - the next character equals @a delim (in this case, the character + * is not extracted) + * - an exception occurs (and in this case is caught) + * + * If no characters are stored, failbit is set in the stream's error + * state. + */ + __istream_type& + get(__streambuf_type& __sb, char_type __delim); + + /** + * @brief Extraction into another streambuf. + * @param sb A streambuf in which to store data. + * @return *this + * + * Returns @c get(sb,widen('\n')). + */ + inline __istream_type& + get(__streambuf_type& __sb) + { return this->get(__sb, this->widen('\n')); } + + /** + * @brief String extraction. + * @param s A character array in which to store the data. + * @param n Maximum number of characters to extract. + * @param delim A "stop" character. + * @return *this + * + * Extracts and stores characters into @a s until one of the + * following happens. Note that these criteria are required to be + * tested in the order listed here, to allow an input line to exactly + * fill the @a s array without setting failbit. + * + * -# the input sequence reaches end-of-file, in which case eofbit + * is set in the stream error state + * -# the next character equals @c delim, in which case the character + * is extracted (and therefore counted in @c gcount()) but not stored + * -# @c n-1 characters are stored, in which case failbit is set + * in the stream error state + * + * If no characters are extracted, failbit is set. (An empty line of + * input should therefore not cause failbit to be set.) + * + * In any case, a null character is stored in the next location in + * the array. + */ + __istream_type& + getline(char_type* __s, streamsize __n, char_type __delim); + + /** + * @brief String extraction. + * @param s A character array in which to store the data. + * @param n Maximum number of characters to extract. + * @return *this + * + * Returns @c getline(s,n,widen('\n')). + */ + inline __istream_type& + getline(char_type* __s, streamsize __n) + { return this->getline(__s, __n, this->widen('\n')); } + + /** + * @brief Discarding characters + * @param n Number of characters to discard. + * @param delim A "stop" character. + * @return *this + * + * Extracts characters and throws them away until one of the + * following happens: + * - if @a n @c != @c std::numeric_limits::max(), @a n + * characters are extracted + * - the input sequence reaches end-of-file + * - the next character equals @a delim (in this case, the character + * is extracted); note that this condition will never occur if + * @a delim equals @c traits::eof(). + */ + __istream_type& + ignore(streamsize __n = 1, int_type __delim = traits_type::eof()); + + /** + * @brief Looking ahead in the stream + * @return The next character, or eof(). + * + * If, after constructing the sentry object, @c good() is false, + * returns @c traits::eof(). Otherwise reads but does not extract + * the next input character. + */ + int_type + peek(); + + /** + * @brief Extraction without delimiters. + * @param s A character array. + * @param n Maximum number of characters to store. + * @return *this + * + * If the stream state is @c good(), extracts characters and stores + * them into @a s until one of the following happens: + * - @a n characters are stored + * - the input sequence reaches end-of-file, in which case the error + * state is set to @c failbit|eofbit. + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __istream_type& + read(char_type* __s, streamsize __n); + + /** + * @brief Extraction until the buffer is exhausted, but no more. + * @param s A character array. + * @param n Maximum number of characters to store. + * @return The number of characters extracted. + * + * Extracts characters and stores them into @a s depending on the + * number of characters remaining in the streambuf's buffer, + * @c rdbuf()->in_avail(), called @c A here: + * - if @c A @c == @c -1, sets eofbit and extracts no characters + * - if @c A @c == @c 0, extracts no characters + * - if @c A @c > @c 0, extracts @c min(A,n) + * + * The goal is to empty the current buffer, and to not request any + * more from the external input sequence controlled by the streambuf. + */ + streamsize + readsome(char_type* __s, streamsize __n); + + /** + * @brief Unextracting a single character. + * @param c The character to push back into the input stream. + * @return *this + * + * If @c rdbuf() is not null, calls @c rdbuf()->sputbackc(c). + * + * If @c rdbuf() is null or if @c sputbackc() fails, sets badbit in + * the error state. + * + * @note Since no characters are extracted, the next call to + * @c gcount() will return 0, as required by DR 60. + */ + __istream_type& + putback(char_type __c); + + /** + * @brief Unextracting the previous character. + * @return *this + * + * If @c rdbuf() is not null, calls @c rdbuf()->sungetc(c). + * + * If @c rdbuf() is null or if @c sungetc() fails, sets badbit in + * the error state. + * + * @note Since no characters are extracted, the next call to + * @c gcount() will return 0, as required by DR 60. + */ + __istream_type& + unget(); + + /** + * @brief Synchronizing the stream buffer. + * @return 0 on success, -1 on failure + * + * If @c rdbuf() is a null pointer, returns -1. + * + * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, + * sets badbit and returns -1. + * + * Otherwise, returns 0. + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + int + sync(); + + /** + * @brief Getting the current read position. + * @return A file position object. + * + * If @c fail() is not false, returns @c pos_type(-1) to indicate + * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,in). + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + pos_type + tellg(); + + /** + * @brief Changing the current read position. + * @param pos A file position object. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If + * that function fails, sets failbit. + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + __istream_type& + seekg(pos_type); + + /** + * @brief Changing the current read position. + * @param off A file offset object. + * @param dir The direction in which to seek. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). + * If that function fails, sets failbit. + * + * @note This function does not count the number of characters + * extracted, if any, and therefore does not affect the next + * call to @c gcount(). + */ + __istream_type& + seekg(off_type, ios_base::seekdir); + //@} + + protected: + explicit + basic_istream(): _M_gcount(streamsize(0)) { } + }; + + /** + * @brief Performs setup work for input streams. + * + * Objects of this class are created before all of the standard + * extractors are run. It is responsible for "exception-safe prefix and + * suffix operations," although only prefix actions are currently required + * by the standard. Additional actions may be added by the + * implementation, and we list them in + * http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/howto.html#5 + * under [27.6] notes. + */ + template + class basic_istream<_CharT, _Traits>::sentry + { + public: + /// Easy access to dependant types. + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename _Traits::int_type __int_type; + + /** + * @brief The constructor performs all the work. + * @param is The input stream to guard. + * @param noskipws Whether to consume whitespace or not. + * + * If the stream state is good (@a is.good() is true), then the + * following actions are performed, otherwise the sentry state is + * false ("not okay") and failbit is set in the stream state. + * + * The sentry's preparatory actions are: + * + * -# if the stream is tied to an output stream, @c is.tie()->flush() + * is called to synchronize the output sequence + * -# if @a noskipws is false, and @c ios_base::skipws is set in + * @c is.flags(), the sentry extracts and discards whitespace + * characters from the stream. The currently imbued locale is + * used to determine whether each character is whitespace. + * + * If the stream state is still good, then the sentry state becomes + * true ("okay"). + */ + explicit + sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); + + /** + * @brief Quick status checking. + * @return The sentry state. + * + * For ease of use, sentries may be converted to booleans. The + * return value is that of the sentry state (true == okay). + */ + operator bool() const { return _M_ok; } + + private: + bool _M_ok; + }; + + // [27.6.1.2.3] character extraction templates + //@{ + /** + * @brief Character extractors + * @param in An input stream. + * @param c A character reference. + * @return in + * + * Behaves like one of the formatted arithmetic extractors described in + * std::basic_istream. After constructing a sentry object with good + * status, this function extracts a character (if one is available) and + * stores it in @a c. Otherwise, sets failbit in the input stream. + */ + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); + + template + basic_istream& + operator>>(basic_istream& __in, unsigned char& __c) + { return (__in >> reinterpret_cast(__c)); } + + template + basic_istream& + operator>>(basic_istream& __in, signed char& __c) + { return (__in >> reinterpret_cast(__c)); } + //@} + + //@{ + /** + * @brief Character string extractors + * @param in An input stream. + * @param s A pointer to a character array. + * @return in + * + * Behaves like one of the formatted arithmetic extractors described in + * std::basic_istream. After constructing a sentry object with good + * status, this function extracts up to @c n characters and stores them + * into the array starting at @a s. @c n is defined as: + * + * - if @c width() is greater than zero, @c n is width() + * - otherwise @c n is "the number of elements of the largest array of + * @c char_type that can store a terminating @c eos." [27.6.1.2.3]/6 + * + * Characters are extracted and stored until one of the following happens: + * - @c n-1 characters are stored + * - EOF is reached + * - the next character is whitespace according to the current locale + * - the next character is a null byte (i.e., @c charT() ) + * + * @c width(0) is then called for the input stream. + * + * If no characters are extracted, sets failbit. + */ + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); + + template + basic_istream& + operator>>(basic_istream& __in, unsigned char* __s) + { return (__in >> reinterpret_cast(__s)); } + + template + basic_istream& + operator>>(basic_istream& __in, signed char* __s) + { return (__in >> reinterpret_cast(__s)); } + //@} + + // 27.6.1.5 Template class basic_iostream + /** + * @brief Merging istream and ostream capabilities. + * + * This class multiply inherits from the input and output stream classes + * simply to provide a single interface. + */ + template + class basic_iostream + : public basic_istream<_CharT, _Traits>, + public basic_ostream<_CharT, _Traits> + { + public: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 271. basic_iostream missing typedefs + // Types (inherited): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + + /** + * @brief Constructor does nothing. + * + * Both of the parent classes are initialized with the same + * streambuf pointer passed to this constructor. + */ + explicit + basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) + : __istream_type(), __ostream_type() + { this->init(__sb); } + + /** + * @brief Destructor does nothing. + */ + virtual + ~basic_iostream() { } + + protected: + explicit + basic_iostream() : __istream_type(), __ostream_type() + { } + }; + + // [27.6.1.4] standard basic_istream manipulators + /** + * @brief Quick and easy way to eat whitespace + * + * This manipulator extracts whitespace characters, stopping when the + * next character is non-whitespace, or when the input sequence is empty. + * If the sequence is empty, @c eofbit is set in the stream, but not + * @c failbit. + * + * The current locale is used to distinguish whitespace characters. + * + * Example: + * @code + * MyClass mc; + * + * std::cin >> std::ws >> mc; + * @endcode + * will skip leading whitespace before calling operator>> on cin and your + * object. Note that the same effect can be achieved by creating a + * std::basic_istream::sentry inside your definition of operator>>. + */ + template + basic_istream<_CharT, _Traits>& + ws(basic_istream<_CharT, _Traits>& __is); +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#pragma GCC visibility pop + +#endif /* _GLIBCXX_ISTREAM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/iterator b/reactos/tools/ppc-build/core-headers/g++-v3/iterator new file mode 100644 index 00000000000..6e3840b1e7e --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/iterator @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file iterator + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_ITERATOR +#define _GLIBCXX_ITERATOR 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* _GLIBCXX_ITERATOR */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/limits b/reactos/tools/ppc-build/core-headers/g++-v3/limits new file mode 100644 index 00000000000..7f96647f95d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/limits @@ -0,0 +1,1143 @@ +// The template and inlines for the -*- C++ -*- numeric_limits classes. + +// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Note: this is not a conforming implementation. +// Written by Gabriel Dos Reis + +// +// ISO 14882:1998 +// 18.2.1 +// + +/** @file limits + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_NUMERIC_LIMITS +#define _GLIBCXX_NUMERIC_LIMITS 1 + +#pragma GCC system_header + +#include + +// +// The numeric_limits<> traits document implementation-defined aspects +// of fundamental arithmetic data types (integers and floating points). +// From Standard C++ point of view, there are 13 such types: +// * integers +// bool (1) +// char, signed char, unsigned char (3) +// short, unsigned short (2) +// int, unsigned (2) +// long, unsigned long (2) +// +// * floating points +// float (1) +// double (1) +// long double (1) +// +// GNU C++ undertstands (where supported by the host C-library) +// * integer +// long long, unsigned long long (2) +// +// which brings us to 15 fundamental arithmetic data types in GNU C++. +// +// +// Since a numeric_limits<> is a bit tricky to get right, we rely on +// an interface composed of macros which should be defined in config/os +// or config/cpu when they differ from the generic (read arbitrary) +// definitions given here. +// + +// These values can be overridden in the target configuration file. +// The default values are appropriate for many 32-bit targets. + +// GCC only intrinsicly supports modulo integral types. The only remaining +// integral exceptional values is division by zero. Only targets that do not +// signal division by zero in some "hard to ignore" way should use false. +#ifndef __glibcxx_integral_traps +# define __glibcxx_integral_traps true +#endif + +// float +// + +// Default values. Should be overriden in configuration files if necessary. + +#ifndef __glibcxx_float_has_denorm_loss +# define __glibcxx_float_has_denorm_loss false +#endif +#ifndef __glibcxx_float_traps +# define __glibcxx_float_traps false +#endif +#ifndef __glibcxx_float_tinyness_before +# define __glibcxx_float_tinyness_before false +#endif + +// double + +// Default values. Should be overriden in configuration files if necessary. + +#ifndef __glibcxx_double_has_denorm_loss +# define __glibcxx_double_has_denorm_loss false +#endif +#ifndef __glibcxx_double_traps +# define __glibcxx_double_traps false +#endif +#ifndef __glibcxx_double_tinyness_before +# define __glibcxx_double_tinyness_before false +#endif + +// long double + +// Default values. Should be overriden in configuration files if necessary. + +#ifndef __glibcxx_long_double_has_denorm_loss +# define __glibcxx_long_double_has_denorm_loss false +#endif +#ifndef __glibcxx_long_double_traps +# define __glibcxx_long_double_traps false +#endif +#ifndef __glibcxx_long_double_tinyness_before +# define __glibcxx_long_double_tinyness_before false +#endif + +// You should not need to define any macros below this point. + +#define __glibcxx_signed(T) ((T)(-1) < 0) + +#define __glibcxx_min(T) \ + (__glibcxx_signed (T) ? (T)1 << __glibcxx_digits (T) : (T)0) + +#define __glibcxx_max(T) \ + (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0) + +#define __glibcxx_digits(T) \ + (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T)) + +// The fraction 643/2136 approximates log10(2) to 7 significant digits. +#define __glibcxx_digits10(T) \ + (__glibcxx_digits (T) * 643 / 2136) + + +namespace std +{ + /** + * @brief Describes the rounding style for floating-point types. + * + * This is used in the std::numeric_limits class. + */ + enum float_round_style + { + round_indeterminate = -1, ///< Self-explanatory. + round_toward_zero = 0, ///< Self-explanatory. + round_to_nearest = 1, ///< To the nearest representable value. + round_toward_infinity = 2, ///< Self-explanatory. + round_toward_neg_infinity = 3 ///< Self-explanatory. + }; + + /** + * @brief Describes the denormalization for floating-point types. + * + * These values represent the presence or absence of a variable number + * of exponent bits. This type is used in the std::numeric_limits class. + */ + enum float_denorm_style + { + /// Indeterminate at compile time whether denormalized values are allowed. + denorm_indeterminate = -1, + /// The type does not allow denormalized values. + denorm_absent = 0, + /// The type allows denormalized values. + denorm_present = 1 + }; + + /** + * @brief Part of std::numeric_limits. + * + * The @c static @c const members are usable as integral constant + * expressions. + * + * @note This is a seperate class for purposes of efficiency; you + * should only access these members as part of an instantiation + * of the std::numeric_limits class. + */ + struct __numeric_limits_base + { + /** This will be true for all fundamental types (which have + specializations), and false for everything else. */ + static const bool is_specialized = false; + + /** The number of @c radix digits that be represented without change: for + integer types, the number of non-sign bits in the mantissa; for + floating types, the number of @c radix digits in the mantissa. */ + static const int digits = 0; + /** The number of base 10 digits that can be represented without change. */ + static const int digits10 = 0; + /** True if the type is signed. */ + static const bool is_signed = false; + /** True if the type is integer. + * @if maint + * Is this supposed to be "if the type is integral"? + * @endif + */ + static const bool is_integer = false; + /** True if the type uses an exact representation. "All integer types are + exact, but not all exact types are integer. For example, rational and + fixed-exponent representations are exact but not integer." + [18.2.1.2]/15 */ + static const bool is_exact = false; + /** For integer types, specifies the base of the representation. For + floating types, specifies the base of the exponent representation. */ + static const int radix = 0; + + /** The minimum negative integer such that @c radix raised to the power of + (one less than that integer) is a normalized floating point number. */ + static const int min_exponent = 0; + /** The minimum negative integer such that 10 raised to that power is in + the range of normalized floating point numbers. */ + static const int min_exponent10 = 0; + /** The maximum positive integer such that @c radix raised to the power of + (one less than that integer) is a representable finite floating point + number. */ + static const int max_exponent = 0; + /** The maximum positive integer such that 10 raised to that power is in + the range of representable finite floating point numbers. */ + static const int max_exponent10 = 0; + + /** True if the type has a representation for positive infinity. */ + static const bool has_infinity = false; + /** True if the type has a representation for a quiet (non-signaling) + "Not a Number." */ + static const bool has_quiet_NaN = false; + /** True if the type has a representation for a signaling + "Not a Number." */ + static const bool has_signaling_NaN = false; + /** See std::float_denorm_style for more information. */ + static const float_denorm_style has_denorm = denorm_absent; + /** "True if loss of accuracy is detected as a denormalization loss, + rather than as an inexact result." [18.2.1.2]/42 */ + static const bool has_denorm_loss = false; + + /** True if-and-only-if the type adheres to the IEC 559 standard, also + known as IEEE 754. (Only makes sense for floating point types.) */ + static const bool is_iec559 = false; + /** "True if the set of values representable by the type is finite. All + built-in types are bounded, this member would be false for arbitrary + precision types." [18.2.1.2]/54 */ + static const bool is_bounded = false; + /** True if the type is @e modulo, that is, if it is possible to add two + positive numbers and have a result that wraps around to a third number + that is less. Typically false for floating types, true for unsigned + integers, and true for signed integers. */ + static const bool is_modulo = false; + + /** True if trapping is implemented for this type. */ + static const bool traps = false; + /** True if tinyness is detected before rounding. (see IEC 559) */ + static const bool tinyness_before = false; + /** See std::float_round_style for more information. This is only + meaningful for floating types; integer types will all be + round_toward_zero. */ + static const float_round_style round_style = round_toward_zero; + }; + + /** + * @brief Properties of fundamental types. + * + * This class allows a program to obtain information about the + * representation of a fundamental type on a given platform. For + * non-fundamental types, the functions will return 0 and the data + * members will all be @c false. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS: DRs 201 and 184 (hi Gaby!) are + * noted, but not incorporated in this documented (yet). + * @endif + */ + template + struct numeric_limits : public __numeric_limits_base + { + /** The minimum finite value, or for floating types with + denormalization, the minimum positive normalized value. */ + static _Tp min() throw() { return static_cast<_Tp>(0); } + /** The maximum finite value. */ + static _Tp max() throw() { return static_cast<_Tp>(0); } + /** The @e machine @e epsilon: the difference between 1 and the least + value greater than 1 that is representable. */ + static _Tp epsilon() throw() { return static_cast<_Tp>(0); } + /** The maximum rounding error measurement (see LIA-1). */ + static _Tp round_error() throw() { return static_cast<_Tp>(0); } + /** The representation of positive infinity, if @c has_infinity. */ + static _Tp infinity() throw() { return static_cast<_Tp>(0); } + /** The representation of a quiet "Not a Number," if @c has_quiet_NaN. */ + static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); } + /** The representation of a signaling "Not a Number," if + @c has_signaling_NaN. */ + static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); } + /** The minimum positive denormalized value. For types where + @c has_denorm is false, this is the minimum positive normalized + value. */ + static _Tp denorm_min() throw() { return static_cast<_Tp>(0); } + }; + + // Now there follow 15 explicit specializations. Yes, 15. Make sure + // you get the count right. + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static bool min() throw() + { return false; } + static bool max() throw() + { return true; } + + static const int digits = 1; + static const int digits10 = 0; + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static bool epsilon() throw() + { return false; } + static bool round_error() throw() + { return false; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static bool infinity() throw() + { return false; } + static bool quiet_NaN() throw() + { return false; } + static bool signaling_NaN() throw() + { return false; } + static bool denorm_min() throw() + { return false; } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + + // It is not clear what it means for a boolean type to trap. + // This is a DR on the LWG issue list. Here, I use integer + // promotion semantics. + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static char min() throw() + { return __glibcxx_min(char); } + static char max() throw() + { return __glibcxx_max(char); } + + static const int digits = __glibcxx_digits (char); + static const int digits10 = __glibcxx_digits10 (char); + static const bool is_signed = __glibcxx_signed (char); + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static char epsilon() throw() + { return 0; } + static char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static char infinity() throw() + { return char(); } + static char quiet_NaN() throw() + { return char(); } + static char signaling_NaN() throw() + { return char(); } + static char denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static signed char min() throw() + { return -__SCHAR_MAX__ - 1; } + static signed char max() throw() + { return __SCHAR_MAX__; } + + static const int digits = __glibcxx_digits (signed char); + static const int digits10 = __glibcxx_digits10 (signed char); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static signed char epsilon() throw() + { return 0; } + static signed char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static signed char infinity() throw() + { return static_cast(0); } + static signed char quiet_NaN() throw() + { return static_cast(0); } + static signed char signaling_NaN() throw() + { return static_cast(0); } + static signed char denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static unsigned char min() throw() + { return 0; } + static unsigned char max() throw() + { return __SCHAR_MAX__ * 2U + 1; } + + static const int digits = __glibcxx_digits (unsigned char); + static const int digits10 = __glibcxx_digits10 (unsigned char); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned char epsilon() throw() + { return 0; } + static unsigned char round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned char infinity() throw() + { return static_cast(0); } + static unsigned char quiet_NaN() throw() + { return static_cast(0); } + static unsigned char signaling_NaN() throw() + { return static_cast(0); } + static unsigned char denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static wchar_t min() throw() + { return __glibcxx_min (wchar_t); } + static wchar_t max() throw() + { return __glibcxx_max (wchar_t); } + + static const int digits = __glibcxx_digits (wchar_t); + static const int digits10 = __glibcxx_digits10 (wchar_t); + static const bool is_signed = __glibcxx_signed (wchar_t); + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static wchar_t epsilon() throw() + { return 0; } + static wchar_t round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static wchar_t infinity() throw() + { return wchar_t(); } + static wchar_t quiet_NaN() throw() + { return wchar_t(); } + static wchar_t signaling_NaN() throw() + { return wchar_t(); } + static wchar_t denorm_min() throw() + { return wchar_t(); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static short min() throw() + { return -__SHRT_MAX__ - 1; } + static short max() throw() + { return __SHRT_MAX__; } + + static const int digits = __glibcxx_digits (short); + static const int digits10 = __glibcxx_digits10 (short); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static short epsilon() throw() + { return 0; } + static short round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static short infinity() throw() + { return short(); } + static short quiet_NaN() throw() + { return short(); } + static short signaling_NaN() throw() + { return short(); } + static short denorm_min() throw() + { return short(); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static unsigned short min() throw() + { return 0; } + static unsigned short max() throw() + { return __SHRT_MAX__ * 2U + 1; } + + static const int digits = __glibcxx_digits (unsigned short); + static const int digits10 = __glibcxx_digits10 (unsigned short); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned short epsilon() throw() + { return 0; } + static unsigned short round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned short infinity() throw() + { return static_cast(0); } + static unsigned short quiet_NaN() throw() + { return static_cast(0); } + static unsigned short signaling_NaN() throw() + { return static_cast(0); } + static unsigned short denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static int min() throw() + { return -__INT_MAX__ - 1; } + static int max() throw() + { return __INT_MAX__; } + + static const int digits = __glibcxx_digits (int); + static const int digits10 = __glibcxx_digits10 (int); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static int epsilon() throw() + { return 0; } + static int round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static int infinity() throw() + { return static_cast(0); } + static int quiet_NaN() throw() + { return static_cast(0); } + static int signaling_NaN() throw() + { return static_cast(0); } + static int denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static unsigned int min() throw() + { return 0; } + static unsigned int max() throw() + { return __INT_MAX__ * 2U + 1; } + + static const int digits = __glibcxx_digits (unsigned int); + static const int digits10 = __glibcxx_digits10 (unsigned int); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned int epsilon() throw() + { return 0; } + static unsigned int round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned int infinity() throw() + { return static_cast(0); } + static unsigned int quiet_NaN() throw() + { return static_cast(0); } + static unsigned int signaling_NaN() throw() + { return static_cast(0); } + static unsigned int denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static long min() throw() + { return -__LONG_MAX__ - 1; } + static long max() throw() + { return __LONG_MAX__; } + + static const int digits = __glibcxx_digits (long); + static const int digits10 = __glibcxx_digits10 (long); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static long epsilon() throw() + { return 0; } + static long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static long infinity() throw() + { return static_cast(0); } + static long quiet_NaN() throw() + { return static_cast(0); } + static long signaling_NaN() throw() + { return static_cast(0); } + static long denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static unsigned long min() throw() + { return 0; } + static unsigned long max() throw() + { return __LONG_MAX__ * 2UL + 1; } + + static const int digits = __glibcxx_digits (unsigned long); + static const int digits10 = __glibcxx_digits10 (unsigned long); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned long epsilon() throw() + { return 0; } + static unsigned long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned long infinity() throw() + { return static_cast(0); } + static unsigned long quiet_NaN() throw() + { return static_cast(0); } + static unsigned long signaling_NaN() throw() + { return static_cast(0); } + static unsigned long denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static long long min() throw() + { return -__LONG_LONG_MAX__ - 1; } + static long long max() throw() + { return __LONG_LONG_MAX__; } + + static const int digits = __glibcxx_digits (long long); + static const int digits10 = __glibcxx_digits10 (long long); + static const bool is_signed = true; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static long long epsilon() throw() + { return 0; } + static long long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static long long infinity() throw() + { return static_cast(0); } + static long long quiet_NaN() throw() + { return static_cast(0); } + static long long signaling_NaN() throw() + { return static_cast(0); } + static long long denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static unsigned long long min() throw() + { return 0; } + static unsigned long long max() throw() + { return __LONG_LONG_MAX__ * 2ULL + 1; } + + static const int digits = __glibcxx_digits (unsigned long long); + static const int digits10 = __glibcxx_digits10 (unsigned long long); + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_exact = true; + static const int radix = 2; + static unsigned long long epsilon() throw() + { return 0; } + static unsigned long long round_error() throw() + { return 0; } + + static const int min_exponent = 0; + static const int min_exponent10 = 0; + static const int max_exponent = 0; + static const int max_exponent10 = 0; + + static const bool has_infinity = false; + static const bool has_quiet_NaN = false; + static const bool has_signaling_NaN = false; + static const float_denorm_style has_denorm = denorm_absent; + static const bool has_denorm_loss = false; + + static unsigned long long infinity() throw() + { return static_cast(0); } + static unsigned long long quiet_NaN() throw() + { return static_cast(0); } + static unsigned long long signaling_NaN() throw() + { return static_cast(0); } + static unsigned long long denorm_min() throw() + { return static_cast(0); } + + static const bool is_iec559 = false; + static const bool is_bounded = true; + static const bool is_modulo = true; + + static const bool traps = __glibcxx_integral_traps; + static const bool tinyness_before = false; + static const float_round_style round_style = round_toward_zero; + }; + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static float min() throw() + { return __FLT_MIN__; } + static float max() throw() + { return __FLT_MAX__; } + + static const int digits = __FLT_MANT_DIG__; + static const int digits10 = __FLT_DIG__; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = __FLT_RADIX__; + static float epsilon() throw() + { return __FLT_EPSILON__; } + static float round_error() throw() + { return 0.5F; } + + static const int min_exponent = __FLT_MIN_EXP__; + static const int min_exponent10 = __FLT_MIN_10_EXP__; + static const int max_exponent = __FLT_MAX_EXP__; + static const int max_exponent10 = __FLT_MAX_10_EXP__; + + static const bool has_infinity = __FLT_HAS_INFINITY__; + static const bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__; + static const bool has_signaling_NaN = has_quiet_NaN; + static const float_denorm_style has_denorm + = __FLT_DENORM_MIN__ ? denorm_present : denorm_absent; + static const bool has_denorm_loss = __glibcxx_float_has_denorm_loss; + + static float infinity() throw() + { return __builtin_huge_valf (); } + static float quiet_NaN() throw() + { return __builtin_nanf (""); } + static float signaling_NaN() throw() + { return __builtin_nansf (""); } + static float denorm_min() throw() + { return __FLT_DENORM_MIN__; } + + static const bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = __glibcxx_float_traps; + static const bool tinyness_before = __glibcxx_float_tinyness_before; + static const float_round_style round_style = round_to_nearest; + }; + +#undef __glibcxx_float_has_denorm_loss +#undef __glibcxx_float_traps +#undef __glibcxx_float_tinyness_before + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static double min() throw() + { return __DBL_MIN__; } + static double max() throw() + { return __DBL_MAX__; } + + static const int digits = __DBL_MANT_DIG__; + static const int digits10 = __DBL_DIG__; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = __FLT_RADIX__; + static double epsilon() throw() + { return __DBL_EPSILON__; } + static double round_error() throw() + { return 0.5; } + + static const int min_exponent = __DBL_MIN_EXP__; + static const int min_exponent10 = __DBL_MIN_10_EXP__; + static const int max_exponent = __DBL_MAX_EXP__; + static const int max_exponent10 = __DBL_MAX_10_EXP__; + + static const bool has_infinity = __DBL_HAS_INFINITY__; + static const bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__; + static const bool has_signaling_NaN = has_quiet_NaN; + static const float_denorm_style has_denorm + = __DBL_DENORM_MIN__ ? denorm_present : denorm_absent; + static const bool has_denorm_loss = __glibcxx_double_has_denorm_loss; + + static double infinity() throw() + { return __builtin_huge_val(); } + static double quiet_NaN() throw() + { return __builtin_nan (""); } + static double signaling_NaN() throw() + { return __builtin_nans (""); } + static double denorm_min() throw() + { return __DBL_DENORM_MIN__; } + + static const bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = __glibcxx_double_traps; + static const bool tinyness_before = __glibcxx_double_tinyness_before; + static const float_round_style round_style = round_to_nearest; + }; + +#undef __glibcxx_double_has_denorm_loss +#undef __glibcxx_double_traps +#undef __glibcxx_double_tinyness_before + + template<> + struct numeric_limits + { + static const bool is_specialized = true; + + static long double min() throw() + { return __LDBL_MIN__; } + static long double max() throw() + { return __LDBL_MAX__; } + + static const int digits = __LDBL_MANT_DIG__; + static const int digits10 = __LDBL_DIG__; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = __FLT_RADIX__; + static long double epsilon() throw() + { return __LDBL_EPSILON__; } + static long double round_error() throw() + { return 0.5L; } + + static const int min_exponent = __LDBL_MIN_EXP__; + static const int min_exponent10 = __LDBL_MIN_10_EXP__; + static const int max_exponent = __LDBL_MAX_EXP__; + static const int max_exponent10 = __LDBL_MAX_10_EXP__; + + static const bool has_infinity = __LDBL_HAS_INFINITY__; + static const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__; + static const bool has_signaling_NaN = has_quiet_NaN; + static const float_denorm_style has_denorm + = __LDBL_DENORM_MIN__ ? denorm_present : denorm_absent; + static const bool has_denorm_loss + = __glibcxx_long_double_has_denorm_loss; + + static long double infinity() throw() + { return __builtin_huge_vall (); } + static long double quiet_NaN() throw() + { return __builtin_nanl (""); } + static long double signaling_NaN() throw() + { return __builtin_nansl (""); } + static long double denorm_min() throw() + { return __LDBL_DENORM_MIN__; } + + static const bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static const bool is_bounded = true; + static const bool is_modulo = false; + + static const bool traps = __glibcxx_long_double_traps; + static const bool tinyness_before = __glibcxx_long_double_tinyness_before; + static const float_round_style round_style = round_to_nearest; + }; + +#undef __glibcxx_long_double_has_denorm_loss +#undef __glibcxx_long_double_traps +#undef __glibcxx_long_double_tinyness_before + +} // namespace std + +#undef __glibcxx_signed +#undef __glibcxx_min +#undef __glibcxx_max +#undef __glibcxx_digits +#undef __glibcxx_digits10 + +#endif // _GLIBCXX_NUMERIC_LIMITS diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/list b/reactos/tools/ppc-build/core-headers/g++-v3/list new file mode 100644 index 00000000000..285a29d8131 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/list @@ -0,0 +1,82 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file list + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_LIST +#define _GLIBCXX_LIST 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_LIST */ + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/locale b/reactos/tools/ppc-build/core-headers/g++-v3/locale new file mode 100644 index 00000000000..43417fbdddc --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/locale @@ -0,0 +1,49 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +/** @file locale + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_LOCALE +#define _GLIBCXX_LOCALE 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +#endif /* _GLIBCXX_LOCALE */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/map b/reactos/tools/ppc-build/core-headers/g++-v3/map new file mode 100644 index 00000000000..4a88ae22ea3 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/map @@ -0,0 +1,74 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file map + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_MAP +#define _GLIBCXX_MAP 1 + +#pragma GCC system_header + +#include +#include +#include + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_MAP */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/memory b/reactos/tools/ppc-build/core-headers/g++-v3/memory new file mode 100644 index 00000000000..1d278e6cb86 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/memory @@ -0,0 +1,375 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1997-1999 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file memory + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_MEMORY +#define _GLIBCXX_MEMORY 1 + +#pragma GCC system_header + +#include +#include +#include +#include //for iterator_traits +#include +#include +#include +#include + +namespace std +{ + /** + * @if maint + * This is a helper function. The unused second parameter exists to + * permit the real get_temporary_buffer to use template parameter deduction. + * + * XXX This should perhaps use the pool. + * @endif + */ + template + pair<_Tp*, ptrdiff_t> + __get_temporary_buffer(ptrdiff_t __len, _Tp*) + { + const ptrdiff_t __max = numeric_limits::max() / sizeof(_Tp); + if (__len > __max) + __len = __max; + + while (__len > 0) + { + _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), + nothrow)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; + } + return pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0); + } + + /** + * @brief Allocates a temporary buffer. + * @param len The number of objects of type Tp. + * @return See full description. + * + * Reinventing the wheel, but this time with prettier spokes! + * + * This function tries to obtain storage for @c len adjacent Tp + * objects. The objects themselves are not constructed, of course. + * A pair<> is returned containing "the buffer s address and + * capacity (in the units of sizeof(Tp)), or a pair of 0 values if + * no storage can be obtained." Note that the capacity obtained + * may be less than that requested if the memory is unavailable; + * you should compare len with the .second return value. + * + * Provides the nothrow exception guarantee. + */ + template + inline pair<_Tp*, ptrdiff_t> + get_temporary_buffer(ptrdiff_t __len) + { return std::__get_temporary_buffer(__len, static_cast<_Tp*>(0)); } + + /** + * @brief The companion to get_temporary_buffer(). + * @param p A buffer previously allocated by get_temporary_buffer. + * @return None. + * + * Frees the memory pointed to by p. + */ + template + void + return_temporary_buffer(_Tp* __p) + { ::operator delete(__p, nothrow); } + + /** + * A wrapper class to provide auto_ptr with reference semantics. + * For example, an auto_ptr can be assigned (or constructed from) + * the result of a function which returns an auto_ptr by value. + * + * All the auto_ptr_ref stuff should happen behind the scenes. + */ + template + struct auto_ptr_ref + { + _Tp1* _M_ptr; + + explicit + auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { } + }; + + + /** + * @brief A simple smart pointer providing strict ownership semantics. + * + * The Standard says: + *
+   *  An @c auto_ptr owns the object it holds a pointer to.  Copying
+   *  an @c auto_ptr copies the pointer and transfers ownership to the
+   *  destination.  If more than one @c auto_ptr owns the same object
+   *  at the same time the behavior of the program is undefined.
+   *
+   *  The uses of @c auto_ptr include providing temporary
+   *  exception-safety for dynamically allocated memory, passing
+   *  ownership of dynamically allocated memory to a function, and
+   *  returning dynamically allocated memory from a function.  @c
+   *  auto_ptr does not meet the CopyConstructible and Assignable
+   *  requirements for Standard Library container elements and thus
+   *  instantiating a Standard Library container with an @c auto_ptr
+   *  results in undefined behavior.
+   *  
+ * Quoted from [20.4.5]/3. + * + * Good examples of what can and cannot be done with auto_ptr can + * be found in the libstdc++ testsuite. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * 127. auto_ptr<> conversion issues + * These resolutions have all been incorporated. + * @endif + */ + template + class auto_ptr + { + private: + _Tp* _M_ptr; + + public: + /// The pointed-to type. + typedef _Tp element_type; + + /** + * @brief An %auto_ptr is usually constructed from a raw pointer. + * @param p A pointer (defaults to NULL). + * + * This object now @e owns the object pointed to by @a p. + */ + explicit + auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } + + /** + * @brief An %auto_ptr can be constructed from another %auto_ptr. + * @param a Another %auto_ptr of the same type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. + */ + auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } + + /** + * @brief An %auto_ptr can be constructed from another %auto_ptr. + * @param a Another %auto_ptr of a different but related type. + * + * A pointer-to-Tp1 must be convertible to a + * pointer-to-Tp/element_type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. + */ + template + auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } + + /** + * @brief %auto_ptr assignment operator. + * @param a Another %auto_ptr of the same type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. The object that this one @e + * used to own and track has been deleted. + */ + auto_ptr& + operator=(auto_ptr& __a) throw() + { + reset(__a.release()); + return *this; + } + + /** + * @brief %auto_ptr assignment operator. + * @param a Another %auto_ptr of a different but related type. + * + * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. + * + * This object now @e owns the object previously owned by @a a, + * which has given up ownsership. The object that this one @e + * used to own and track has been deleted. + */ + template + auto_ptr& + operator=(auto_ptr<_Tp1>& __a) throw() + { + reset(__a.release()); + return *this; + } + + /** + * When the %auto_ptr goes out of scope, the object it owns is + * deleted. If it no longer owns anything (i.e., @c get() is + * @c NULL), then this has no effect. + * + * @if maint + * The C++ standard says there is supposed to be an empty throw + * specification here, but omitting it is standard conforming. Its + * presence can be detected only if _Tp::~_Tp() throws, but this is + * prohibited. [17.4.3.6]/2 + * @end maint + */ + ~auto_ptr() { delete _M_ptr; } + + /** + * @brief Smart pointer dereferencing. + * + * If this %auto_ptr no longer owns anything, then this + * operation will crash. (For a smart pointer, "no longer owns + * anything" is the same as being a null pointer, and you know + * what happens when you dereference one of those...) + */ + element_type& + operator*() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return *_M_ptr; + } + + /** + * @brief Smart pointer dereferencing. + * + * This returns the pointer itself, which the language then will + * automatically cause to be dereferenced. + */ + element_type* + operator->() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return _M_ptr; + } + + /** + * @brief Bypassing the smart pointer. + * @return The raw pointer being managed. + * + * You can get a copy of the pointer that this object owns, for + * situations such as passing to a function which only accepts + * a raw pointer. + * + * @note This %auto_ptr still owns the memory. + */ + element_type* + get() const throw() { return _M_ptr; } + + /** + * @brief Bypassing the smart pointer. + * @return The raw pointer being managed. + * + * You can get a copy of the pointer that this object owns, for + * situations such as passing to a function which only accepts + * a raw pointer. + * + * @note This %auto_ptr no longer owns the memory. When this object + * goes out of scope, nothing will happen. + */ + element_type* + release() throw() + { + element_type* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; + } + + /** + * @brief Forcibly deletes the managed object. + * @param p A pointer (defaults to NULL). + * + * This object now @e owns the object pointed to by @a p. The + * previous object has been deleted. + */ + void + reset(element_type* __p = 0) throw() + { + if (__p != _M_ptr) + { + delete _M_ptr; + _M_ptr = __p; + } + } + + /** @{ + * @brief Automatic conversions + * + * These operations convert an %auto_ptr into and from an auto_ptr_ref + * automatically as needed. This allows constructs such as + * @code + * auto_ptr func_returning_auto_ptr(.....); + * ... + * auto_ptr ptr = func_returning_auto_ptr(.....); + * @endcode + */ + auto_ptr(auto_ptr_ref __ref) throw() + : _M_ptr(__ref._M_ptr) { } + + auto_ptr& + operator=(auto_ptr_ref __ref) throw() + { + if (__ref._M_ptr != this->get()) + { + delete _M_ptr; + _M_ptr = __ref._M_ptr; + } + return *this; + } + + template + operator auto_ptr_ref<_Tp1>() throw() + { return auto_ptr_ref<_Tp1>(this->release()); } + + template + operator auto_ptr<_Tp1>() throw() + { return auto_ptr<_Tp1>(this->release()); } + /** @} */ + }; +} // namespace std + +#endif /* _GLIBCXX_MEMORY */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/new b/reactos/tools/ppc-build/core-headers/g++-v3/new new file mode 100644 index 00000000000..00e99464b90 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/new @@ -0,0 +1,101 @@ +// The -*- C++ -*- dynamic memory management header. + +// Copyright (C) 1994, 1996, 1997, 1998, 2000, 2001, 2002 +// Free Software Foundation + +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file new + * The header @c new defines several functions to manage dynamic memory and + * handling memory allocation errors; see + * http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more. + */ + +#ifndef _NEW +#define _NEW + +#include +#include + +extern "C++" { + +namespace std +{ + /** + * @brief Exception possibly thrown by @c new. + * + * @c bad_alloc (or classes derived from it) is used to report allocation + * errors from the throwing forms of @c new. */ + class bad_alloc : public exception + { + public: + bad_alloc() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_alloc() throw(); + }; + + struct nothrow_t { }; + extern const nothrow_t nothrow; + /** If you write your own error handler to be called by @c new, it must + * be of this type. */ + typedef void (*new_handler)(); + /// Takes a replacement handler as the argument, returns the previous handler. + new_handler set_new_handler(new_handler) throw(); +} // namespace std + +//@{ +/** These are replaceable signatures: + * - normal single new and delete (no arguments, throw @c bad_alloc on error) + * - normal array new and delete (same) + * - @c nothrow single new and delete (take a @c nothrow argument, return + * @c NULL on error) + * - @c nothrow array new and delete (same) + * + * Placement new and delete signatures (take a memory address argument, + * does nothing) may not be replaced by a user's program. +*/ +void* operator new(std::size_t) throw (std::bad_alloc); +void* operator new[](std::size_t) throw (std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); +void* operator new(std::size_t, const std::nothrow_t&) throw(); +void* operator new[](std::size_t, const std::nothrow_t&) throw(); +void operator delete(void*, const std::nothrow_t&) throw(); +void operator delete[](void*, const std::nothrow_t&) throw(); + +// Default placement versions of operator new. +inline void* operator new(std::size_t, void* __p) throw() { return __p; } +inline void* operator new[](std::size_t, void* __p) throw() { return __p; } + +// Default placement versions of operator delete. +inline void operator delete (void*, void*) throw() { } +inline void operator delete[](void*, void*) throw() { } +//@} +} // extern "C++" + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/numeric b/reactos/tools/ppc-build/core-headers/g++-v3/numeric new file mode 100644 index 00000000000..88661e9f5a4 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/numeric @@ -0,0 +1,72 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file numeric + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_NUMERIC +#define _GLIBCXX_NUMERIC 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include + +#endif /* _GLIBCXX_NUMERIC */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/ostream b/reactos/tools/ppc-build/core-headers/g++-v3/ostream new file mode 100644 index 00000000000..c8b9e0f7c28 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/ostream @@ -0,0 +1,552 @@ +// Output streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.6.2 Output streams +// + +/** @file ostream + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_OSTREAM +#define _GLIBCXX_OSTREAM 1 + +#pragma GCC system_header + +#include + +#pragma GCC visibility push(default) + +namespace std +{ + // [27.6.2.1] Template class basic_ostream + /** + * @brief Controlling output. + * + * This is the base class for all output streams. It provides text + * formatting of all builtin types, and communicates with any class + * derived from basic_streambuf to do the actual output. + */ + template + class basic_ostream : virtual public basic_ios<_CharT, _Traits> + { + public: + // Types (inherited from basic_ios (27.4.4)): + typedef _CharT char_type; + typedef typename _Traits::int_type int_type; + typedef typename _Traits::pos_type pos_type; + typedef typename _Traits::off_type off_type; + typedef _Traits traits_type; + + // Non-standard Types: + typedef basic_streambuf<_CharT, _Traits> __streambuf_type; + typedef basic_ios<_CharT, _Traits> __ios_type; + typedef basic_ostream<_CharT, _Traits> __ostream_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef ctype<_CharT> __ctype_type; + + template + friend basic_ostream<_CharT2, _Traits2>& + operator<<(basic_ostream<_CharT2, _Traits2>&, _CharT2); + + template + friend basic_ostream& + operator<<(basic_ostream&, char); + + template + friend basic_ostream<_CharT2, _Traits2>& + operator<<(basic_ostream<_CharT2, _Traits2>&, const _CharT2*); + + template + friend basic_ostream& + operator<<(basic_ostream&, const char*); + + template + friend basic_ostream<_CharT2, _Traits2>& + operator<<(basic_ostream<_CharT2, _Traits2>&, const char*); + + // [27.6.2.2] constructor/destructor + /** + * @brief Base constructor. + * + * This ctor is almost never called by the user directly, rather from + * derived classes' initialization lists, which pass a pointer to + * their own stream buffer. + */ + explicit + basic_ostream(__streambuf_type* __sb) + { this->init(__sb); } + + /** + * @brief Base destructor. + * + * This does very little apart from providing a virtual base dtor. + */ + virtual + ~basic_ostream() { } + + // [27.6.2.3] prefix/suffix + class sentry; + friend class sentry; + + // [27.6.2.5] formatted output + // [27.6.2.5.3] basic_ostream::operator<< + //@{ + /** + * @brief Interface for manipulators. + * + * Manuipulators such as @c std::endl and @c std::hex use these + * functions in constructs like "std::cout << std::endl". For more + * information, see the iomanip header. + */ + inline __ostream_type& + operator<<(__ostream_type& (*__pf)(__ostream_type&)); + + inline __ostream_type& + operator<<(__ios_type& (*__pf)(__ios_type&)); + + inline __ostream_type& + operator<<(ios_base& (*__pf) (ios_base&)); + //@} + + // [27.6.2.5.2] arithmetic inserters + /** + * @name Arithmetic Inserters + * + * All the @c operator<< functions (aka formatted output + * functions) have some common behavior. Each starts by + * constructing a temporary object of type std::basic_ostream::sentry. + * This can have several effects, concluding with the setting of a + * status flag; see the sentry documentation for more. + * + * If the sentry status is good, the function tries to generate + * whatever data is appropriate for the type of the argument. + * + * If an exception is thrown during insertion, ios_base::badbit + * will be turned on in the stream's error state without causing an + * ios_base::failure to be thrown. The original exception will then + * be rethrown. + */ + //@{ + /** + * @brief Basic arithmetic inserters + * @param A variable of builtin type. + * @return @c *this if successful + * + * These functions use the stream's current locale (specifically, the + * @c num_get facet) to perform numeric formatting. + */ + __ostream_type& + operator<<(long __n); + + __ostream_type& + operator<<(unsigned long __n); + + __ostream_type& + operator<<(bool __n); + + __ostream_type& + operator<<(short __n) + { + ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt & ios_base::oct || __fmt & ios_base::hex) + return this->operator<<(static_cast + (static_cast(__n))); + else + return this->operator<<(static_cast(__n)); + } + + __ostream_type& + operator<<(unsigned short __n) + { return this->operator<<(static_cast(__n)); } + + __ostream_type& + operator<<(int __n) + { + ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; + if (__fmt & ios_base::oct || __fmt & ios_base::hex) + return this->operator<<(static_cast + (static_cast(__n))); + else + return this->operator<<(static_cast(__n)); + } + + __ostream_type& + operator<<(unsigned int __n) + { return this->operator<<(static_cast(__n)); } + +#ifdef _GLIBCXX_USE_LONG_LONG + __ostream_type& + operator<<(long long __n); + + __ostream_type& + operator<<(unsigned long long __n); +#endif + + __ostream_type& + operator<<(double __f); + + __ostream_type& + operator<<(float __f) + { return this->operator<<(static_cast(__f)); } + + __ostream_type& + operator<<(long double __f); + + __ostream_type& + operator<<(const void* __p); + + /** + * @brief Extracting from another streambuf. + * @param sb A pointer to a streambuf + * + * This function behaves like one of the basic arithmetic extractors, + * in that it also constructs a sentry object and has the same error + * handling behavior. + * + * If @a sb is NULL, the stream will set failbit in its error state. + * + * Characters are extracted from @a sb and inserted into @c *this + * until one of the following occurs: + * + * - the input stream reaches end-of-file, + * - insertion into the output sequence fails (in this case, the + * character that would have been inserted is not extracted), or + * - an exception occurs while getting a character from @a sb, which + * sets failbit in the error state + * + * If the function inserts no characters, failbit is set. + */ + __ostream_type& + operator<<(__streambuf_type* __sb); + //@} + + // [27.6.2.6] unformatted output functions + /** + * @name Unformatted Output Functions + * + * All the unformatted output functions have some common behavior. + * Each starts by constructing a temporary object of type + * std::basic_ostream::sentry. This has several effects, concluding + * with the setting of a status flag; see the sentry documentation + * for more. + * + * If the sentry status is good, the function tries to generate + * whatever data is appropriate for the type of the argument. + * + * If an exception is thrown during insertion, ios_base::badbit + * will be turned on in the stream's error state. If badbit is on in + * the stream's exceptions mask, the exception will be rethrown + * without completing its actions. + */ + //@{ + /** + * @brief Simple insertion. + * @param c The character to insert. + * @return *this + * + * Tries to insert @a c. + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __ostream_type& + put(char_type __c); + + // Core write functionality, without sentry. + void + _M_write(const char_type* __s, streamsize __n) + { + streamsize __put = this->rdbuf()->sputn(__s, __n); + if (__put != __n) + this->setstate(ios_base::badbit); + } + + /** + * @brief Character string insertion. + * @param s The array to insert. + * @param n Maximum number of characters to insert. + * @return *this + * + * Characters are copied from @a s and inserted into the stream until + * one of the following happens: + * + * - @a n characters are inserted + * - inserting into the output sequence fails (in this case, badbit + * will be set in the stream's error state) + * + * @note This function is not overloaded on signed char and + * unsigned char. + */ + __ostream_type& + write(const char_type* __s, streamsize __n); + //@} + + /** + * @brief Synchronizing the stream buffer. + * @return *this + * + * If @c rdbuf() is a null pointer, changes nothing. + * + * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, + * sets badbit. + */ + __ostream_type& + flush(); + + // [27.6.2.4] seek members + /** + * @brief Getting the current write position. + * @return A file position object. + * + * If @c fail() is not false, returns @c pos_type(-1) to indicate + * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,out). + */ + pos_type + tellp(); + + /** + * @brief Changing the current write position. + * @param pos A file position object. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If + * that function fails, sets failbit. + */ + __ostream_type& + seekp(pos_type); + + /** + * @brief Changing the current write position. + * @param off A file offset object. + * @param dir The direction in which to seek. + * @return *this + * + * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). + * If that function fails, sets failbit. + */ + __ostream_type& + seekp(off_type, ios_base::seekdir); + + protected: + explicit + basic_ostream() { } + }; + + /** + * @brief Performs setup work for output streams. + * + * Objects of this class are created before all of the standard + * inserters are run. It is responsible for "exception-safe prefix and + * suffix operations." Additional actions may be added by the + * implementation, and we list them in + * http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/howto.html#5 + * under [27.6] notes. + */ + template + class basic_ostream<_CharT, _Traits>::sentry + { + // Data Members: + bool _M_ok; + basic_ostream<_CharT,_Traits>& _M_os; + + public: + /** + * @brief The constructor performs preparatory work. + * @param os The output stream to guard. + * + * If the stream state is good (@a os.good() is true), then if the + * stream is tied to another output stream, @c is.tie()->flush() + * is called to synchronize the output sequences. + * + * If the stream state is still good, then the sentry state becomes + * true ("okay"). + */ + explicit + sentry(basic_ostream<_CharT,_Traits>& __os); + + /** + * @brief Possibly flushes the stream. + * + * If @c ios_base::unitbuf is set in @c os.flags(), and + * @c std::uncaught_exception() is true, the sentry destructor calls + * @c flush() on the output stream. + */ + ~sentry() + { + // XXX MT + if (_M_os.flags() & ios_base::unitbuf && !uncaught_exception()) + { + // Can't call flush directly or else will get into recursive lock. + if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) + _M_os.setstate(ios_base::badbit); + } + } + + /** + * @brief Quick status checking. + * @return The sentry state. + * + * For ease of use, sentries may be converted to booleans. The + * return value is that of the sentry state (true == okay). + */ + operator bool() const + { return _M_ok; } + }; + + // [27.6.2.5.4] character insertion templates + //@{ + /** + * @brief Character inserters + * @param out An output stream. + * @param c A character. + * @return out + * + * Behaves like one of the formatted arithmetic inserters described in + * std::basic_ostream. After constructing a sentry object with good + * status, this function inserts a single character and any required + * padding (as determined by [22.2.2.2.2]). @c out.width(0) is then + * called. + * + * If @a c is of type @c char and the character type of the stream is not + * @c char, the character is widened before insertion. + */ + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c); + + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) + { return (__out << __out.widen(__c)); } + + // Specialization + template + basic_ostream& + operator<<(basic_ostream& __out, char __c); + + // Signed and unsigned + template + basic_ostream& + operator<<(basic_ostream& __out, signed char __c) + { return (__out << static_cast(__c)); } + + template + basic_ostream& + operator<<(basic_ostream& __out, unsigned char __c) + { return (__out << static_cast(__c)); } + //@} + + //@{ + /** + * @brief String inserters + * @param out An output stream. + * @param s A character string. + * @return out + * @pre @a s must be a non-NULL pointer + * + * Behaves like one of the formatted arithmetic inserters described in + * std::basic_ostream. After constructing a sentry object with good + * status, this function inserts @c traits::length(s) characters starting + * at @a s, widened if necessary, followed by any required padding (as + * determined by [22.2.2.2.2]). @c out.width(0) is then called. + */ + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s); + + template + basic_ostream<_CharT, _Traits> & + operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); + + // Partial specializationss + template + basic_ostream& + operator<<(basic_ostream& __out, const char* __s); + + // Signed and unsigned + template + basic_ostream& + operator<<(basic_ostream& __out, const signed char* __s) + { return (__out << reinterpret_cast(__s)); } + + template + basic_ostream & + operator<<(basic_ostream& __out, const unsigned char* __s) + { return (__out << reinterpret_cast(__s)); } + //@} + + // [27.6.2.7] standard basic_ostream manipulators + /** + * @brief Write a newline and flush the stream. + * + * This manipulator is often mistakenly used when a simple newline is + * desired, leading to poor buffering performance. See + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for more + * on this subject. + */ + template + basic_ostream<_CharT, _Traits>& + endl(basic_ostream<_CharT, _Traits>& __os) + { return flush(__os.put(__os.widen('\n'))); } + + /** + * @brief Write a null character into the output sequence. + * + * "Null character" is @c CharT() by definition. For CharT of @c char, + * this correctly writes the ASCII @c NUL character string terminator. + */ + template + basic_ostream<_CharT, _Traits>& + ends(basic_ostream<_CharT, _Traits>& __os) + { return __os.put(_CharT()); } + + /** + * @brief Flushes the output stream. + * + * This manipulator simply calls the stream's @c flush() member function. + */ + template + basic_ostream<_CharT, _Traits>& + flush(basic_ostream<_CharT, _Traits>& __os) + { return __os.flush(); } + +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#pragma GCC visibility pop + +#endif /* _GLIBCXX_OSTREAM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/atomic_word.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/atomic_word.h new file mode 100644 index 00000000000..b46adc2a474 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/atomic_word.h @@ -0,0 +1,35 @@ +// Low-level type for atomic operations -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMIC_WORD_H +#define _GLIBCXX_ATOMIC_WORD_H 1 + +typedef int _Atomic_word; + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/basic_file.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/basic_file.h new file mode 100644 index 00000000000..6aa031b507d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/basic_file.h @@ -0,0 +1,110 @@ +// Wrapper of C-language FILE struct -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.8 File-based streams +// + +/** @file basic_file.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _BASIC_FILE_STDIO_H +#define _BASIC_FILE_STDIO_H 1 + +#pragma GCC system_header + +#include +#include + +namespace std +{ + // Generic declaration. + template + class __basic_file; + + // Specialization. + template<> + class __basic_file + { + // Underlying data source/sink. + __c_file* _M_cfile; + + // True iff we opened _M_cfile, and thus must close it ourselves. + bool _M_cfile_created; + + public: + __basic_file(__c_lock* __lock = 0); + + __basic_file* + open(const char* __name, ios_base::openmode __mode, int __prot = 0664); + + __basic_file* + sys_open(__c_file* __file, ios_base::openmode); + + __basic_file* + sys_open(int __fd, ios_base::openmode __mode); + + __basic_file* + close(); + + bool + is_open() const; + + int + fd(); + + __c_file* + file(); + + ~__basic_file(); + + streamsize + xsputn(const char* __s, streamsize __n); + + streamsize + xsputn_2(const char* __s1, streamsize __n1, + const char* __s2, streamsize __n2); + + streamsize + xsgetn(char* __s, streamsize __n); + + streamoff + seekoff(streamoff __off, ios_base::seekdir __way); + + int + sync(); + + streamsize + showmanyc(); + }; +} // namespace std + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++allocator.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++allocator.h new file mode 100644 index 00000000000..442f89cc535 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++allocator.h @@ -0,0 +1,37 @@ +// Base to std::allocator -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CXX_ALLOCATOR_H +#define _CXX_ALLOCATOR_H 1 + +// Define new_allocator as the base class to std::allocator. +#include +#define ___glibcxx_base_allocator __gnu_cxx::new_allocator + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++config.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++config.h new file mode 100644 index 00000000000..7e4259526d9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++config.h @@ -0,0 +1,1297 @@ +// Predefined symbols and macros -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CXXCONFIG +#define _CXXCONFIG 1 + +// Pick up any OS-specific definitions. +#include + +// The current version of the C++ library in compressed ISO date format. +#define __GLIBCXX__ 20050519 + +// Allow use of "export template." This is currently not a feature +// that g++ supports. +// #define _GLIBCXX_EXPORT_TEMPLATE 1 + +// Allow use of the GNU syntax extension, "extern template." This +// extension is fully documented in the g++ manual, but in a nutshell, +// it inhibits all implicit instantiations and is used throughout the +// library to avoid multiple weak definitions for required types that +// are already explicitly instantiated in the library binary. This +// substantially reduces the binary size of resulting executables. +#ifndef _GLIBCXX_EXTERN_TEMPLATE +# define _GLIBCXX_EXTERN_TEMPLATE 1 +#endif + +// Debug mode support. Debug mode basic_string is not allowed to be +// associated with std, because of locale and exception link +// dependence. +namespace __gnu_debug_def { } + +namespace __gnu_debug +{ + using namespace __gnu_debug_def; +} + +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_STD __gnu_norm +namespace __gnu_norm +{ + using namespace std; +} +namespace std +{ + using namespace __gnu_debug_def __attribute__ ((strong)); +} +#else +# define _GLIBCXX_STD std +#endif + + +// The remainder of the prewritten config is automatic; all the +// user hooks are listed above. + +// Create a boolean flag to be used to determine if --fast-math is set. +#ifdef __FAST_MATH__ +# define _GLIBCXX_FAST_MATH 1 +#else +# define _GLIBCXX_FAST_MATH 0 +#endif + +// This marks string literals in header files to be extracted for eventual +// translation. It is primarily used for messages in thrown exceptions; see +// src/functexcept.cc. We use __N because the more traditional _N is used +// for something else under certain OSes (see BADNAMES). +#define __N(msgid) (msgid) + +// End of prewritten config; the discovered settings follow. +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ +// acconfig.h symbols and macros for libstdc++ v3 -*- C++ -*- + +// Defines libstdc++ version. +/* #undef _GLIBCXX_PACKAGE */ +/* #undef _GLIBCXX_VERSION */ + +// Needed for gettext. +/* #undef ENABLE_NLS */ +/* #undef _GLIBCXX_HAVE_CATGETS */ +/* #undef _GLIBCXX_HAVE_GETTEXT */ +/* #undef _GLIBCXX_HAVE_STPCPY */ + +// Include I/O support for 'long long' and 'unsigned long long'. +#define _GLIBCXX_USE_LONG_LONG 1 + +// Include support for 'long double'. +/* #undef _GLIBCXX_USE_LONG_DOUBLE */ + +// Define if C99 math functions (like fpclassify) should be exposed. +#define _GLIBCXX_USE_C99_MATH 1 + +// Define if C99 features such as lldiv_t, llabs, lldiv should be exposed. +#define _GLIBCXX_USE_C99 1 + +// Define if code specialized for wchar_t should be used. +#define _GLIBCXX_USE_WCHAR_T 1 + +// Define if using setrlimit to set resource limits during 'make check'. +#define _GLIBCXX_RES_LIMITS 1 + +// Define to use concept checking code from the boost libraries. +/* #undef _GLIBCXX_CONCEPT_CHECKS */ + +// Define to use symbol versioning in the shared library. +#define _GLIBCXX_SYMVER 1 + +// Define symbol versioning in assember directives. If symbol +// versioning is beigng used, and the assembler supports this kind of +// thing, then use it. +// NB: _GLIBCXX_AT_AT is a hack to work around quoting issues in m4. +#if _GLIBCXX_SYMVER + #define _GLIBCXX_ASM_SYMVER(cur, old, version) \ + asm (".symver " #cur "," #old _GLIBCXX_AT_AT #version); +#else + #define _GLIBCXX_ASM_SYMVER(cur, old, version) +#endif + +// Define if LFS support is available. +#define _GLIBCXX_USE_LFS 1 + +// Define if a fully dynamic basic_string is wanted. +/* #undef _GLIBCXX_FULLY_DYNAMIC_STRING */ + +// Define if NLS translations are to be used. +#define _GLIBCXX_USE_NLS 1 + +// Define if gthr-default.h exists (meaning that threading support is enabled). +#define _GLIBCXX_HAVE_GTHR_DEFAULT 1 + +// Define if the atan2f function exists. +#define _GLIBCXX_HAVE_ATAN2F 1 + +// Define if the atan2l function exists. +/* #undef _GLIBCXX_HAVE_ATAN2L */ + +// Define if the tanl function exists. +/* #undef _GLIBCXX_HAVE_TANL */ + +// Define if the copysignf function exists. +#define _GLIBCXX_HAVE_COPYSIGNF 1 + +// Define if getpagesize exists. +#define _GLIBCXX_HAVE_GETPAGESIZE 1 + +// Define if setenv exists. +#define _GLIBCXX_HAVE_SETENV 1 + +// Define if sigsetjmp exists. +#define _GLIBCXX_HAVE_SIGSETJMP 1 + +// Define if mbstate_t exists in wchar.h. +#define _GLIBCXX_HAVE_MBSTATE_T 1 + +// Define if you have the modff function. +#define _GLIBCXX_HAVE_MODFF 1 + +// Define if you have the modfl function. +/* #undef _GLIBCXX_HAVE_MODFL */ + +// Define if you have the expf function. +#define _GLIBCXX_HAVE_EXPF 1 + +// Define if you have the expl function. +/* #undef _GLIBCXX_HAVE_EXPL */ + +// Define if you have the hypot function. +#define _GLIBCXX_HAVE_HYPOT 1 + +// Define if you have the hypotf function. +#define _GLIBCXX_HAVE_HYPOTF 1 + +// Define if you have the hypotl function. +/* #undef _GLIBCXX_HAVE_HYPOTL */ + +// Define if the compiler/host combination has __builtin_abs +#define _GLIBCXX_HAVE___BUILTIN_ABS 1 + +// Define if the compiler/host combination has __builtin_labs +#define _GLIBCXX_HAVE___BUILTIN_LABS 1 + +// Define if the compiler/host combination has __builtin_cos +#define _GLIBCXX_HAVE___BUILTIN_COS 1 + +// Define if the compiler/host combination has __builtin_cosf +#define _GLIBCXX_HAVE___BUILTIN_COSF 1 + +// Define if the compiler/host combination has __builtin_cosl +#define _GLIBCXX_HAVE___BUILTIN_COSL 1 + +// Define if the compiler/host combination has __builtin_fabs +#define _GLIBCXX_HAVE___BUILTIN_FABS 1 + +// Define if the compiler/host combination has __builtin_fabsf +#define _GLIBCXX_HAVE___BUILTIN_FABSF 1 + +// Define if the compiler/host combination has __builtin_fabsl +#define _GLIBCXX_HAVE___BUILTIN_FABSL 1 + +// Define if the compiler/host combination has __builtin_sin +#define _GLIBCXX_HAVE___BUILTIN_SIN 1 + +// Define if the compiler/host combination has __builtin_sinf +#define _GLIBCXX_HAVE___BUILTIN_SINF 1 + +// Define if the compiler/host combination has __builtin_sinl +#define _GLIBCXX_HAVE___BUILTIN_SINL 1 + +// Define if the compiler/host combination has __builtin_sqrt +#define _GLIBCXX_HAVE___BUILTIN_SQRT 1 + +// Define if the compiler/host combination has __builtin_sqrtf +#define _GLIBCXX_HAVE___BUILTIN_SQRTF 1 + +// Define if the compiler/host combination has __builtin_sqrtl +#define _GLIBCXX_HAVE___BUILTIN_SQRTL 1 + +// Define if poll is available in . +#define _GLIBCXX_HAVE_POLL 1 + +// Define if S_ISREG (Posix) is available in . +#define _GLIBCXX_HAVE_S_ISREG 1 + +// Define if S_IFREG is available in . +/* #undef _GLIBCXX_HAVE_S_IFREG */ + +// Define if writev is available in . +#define _GLIBCXX_HAVE_WRITEV 1 + +// Define if int64_t is available in . +#define _GLIBCXX_HAVE_INT64_T 1 + +// Define if LC_MESSAGES is available in . +#define _GLIBCXX_HAVE_LC_MESSAGES 1 + +// Define if exists. +#define _GLIBCXX_HAVE_FLOAT_H 1 + +// Define if modf is present in +/* #undef _GLIBCXX_HAVE_MODF */ + + +/* Define to 1 if you have the `acosf' function. */ +#define _GLIBCXX_HAVE_ACOSF 1 + +/* Define to 1 if you have the `acosl' function. */ +/* #undef _GLIBCXX_HAVE_ACOSL */ + +/* Define to 1 if you have the `asinf' function. */ +#define _GLIBCXX_HAVE_ASINF 1 + +/* Define to 1 if you have the `asinl' function. */ +/* #undef _GLIBCXX_HAVE_ASINL */ + +/* Define to 1 if you have the `atan2f' function. */ +#define _GLIBCXX_HAVE_ATAN2F 1 + +/* Define to 1 if you have the `atan2l' function. */ +/* #undef _GLIBCXX_HAVE_ATAN2L */ + +/* Define to 1 if you have the `atanf' function. */ +#define _GLIBCXX_HAVE_ATANF 1 + +/* Define to 1 if you have the `atanl' function. */ +/* #undef _GLIBCXX_HAVE_ATANL */ + +/* Define to 1 if you have the `btowc' function. */ +#define _GLIBCXX_HAVE_BTOWC 1 + +/* Define to 1 if you have the `ceilf' function. */ +#define _GLIBCXX_HAVE_CEILF 1 + +/* Define to 1 if you have the `ceill' function. */ +/* #undef _GLIBCXX_HAVE_CEILL */ + +/* Define to 1 if you have the `copysign' function. */ +#define _GLIBCXX_HAVE_COPYSIGN 1 + +/* Define to 1 if you have the `copysignf' function. */ +#define _GLIBCXX_HAVE_COPYSIGNF 1 + +/* Define to 1 if you have the `copysignl' function. */ +/* #undef _GLIBCXX_HAVE_COPYSIGNL */ + +/* Define to 1 if you have the `cosf' function. */ +#define _GLIBCXX_HAVE_COSF 1 + +/* Define to 1 if you have the `coshf' function. */ +#define _GLIBCXX_HAVE_COSHF 1 + +/* Define to 1 if you have the `coshl' function. */ +/* #undef _GLIBCXX_HAVE_COSHL */ + +/* Define to 1 if you have the `cosl' function. */ +/* #undef _GLIBCXX_HAVE_COSL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_ENDIAN_H 1 + +/* Define to 1 if you have the `expf' function. */ +#define _GLIBCXX_HAVE_EXPF 1 + +/* Define to 1 if you have the `expl' function. */ +/* #undef _GLIBCXX_HAVE_EXPL */ + +/* Define to 1 if you have the `fabsf' function. */ +#define _GLIBCXX_HAVE_FABSF 1 + +/* Define to 1 if you have the `fabsl' function. */ +/* #undef _GLIBCXX_HAVE_FABSL */ + +/* Define to 1 if you have the `fgetwc' function. */ +#define _GLIBCXX_HAVE_FGETWC 1 + +/* Define to 1 if you have the `fgetws' function. */ +#define _GLIBCXX_HAVE_FGETWS 1 + +/* Define to 1 if you have the `finite' function. */ +#define _GLIBCXX_HAVE_FINITE 1 + +/* Define to 1 if you have the `finitef' function. */ +#define _GLIBCXX_HAVE_FINITEF 1 + +/* Define to 1 if you have the `finitel' function. */ +/* #undef _GLIBCXX_HAVE_FINITEL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_FLOAT_H 1 + +/* Define to 1 if you have the `floorf' function. */ +#define _GLIBCXX_HAVE_FLOORF 1 + +/* Define to 1 if you have the `floorl' function. */ +/* #undef _GLIBCXX_HAVE_FLOORL */ + +/* Define to 1 if you have the `fmodf' function. */ +#define _GLIBCXX_HAVE_FMODF 1 + +/* Define to 1 if you have the `fmodl' function. */ +/* #undef _GLIBCXX_HAVE_FMODL */ + +/* Define to 1 if you have the `fpclass' function. */ +/* #undef _GLIBCXX_HAVE_FPCLASS */ + +/* Define to 1 if you have the `fputwc' function. */ +#define _GLIBCXX_HAVE_FPUTWC 1 + +/* Define to 1 if you have the `fputws' function. */ +#define _GLIBCXX_HAVE_FPUTWS 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_FP_H */ + +/* Define to 1 if you have the `frexpf' function. */ +#define _GLIBCXX_HAVE_FREXPF 1 + +/* Define to 1 if you have the `frexpl' function. */ +/* #undef _GLIBCXX_HAVE_FREXPL */ + +/* Define to 1 if you have the `fwide' function. */ +#define _GLIBCXX_HAVE_FWIDE 1 + +/* Define to 1 if you have the `fwprintf' function. */ +#define _GLIBCXX_HAVE_FWPRINTF 1 + +/* Define to 1 if you have the `fwscanf' function. */ +#define _GLIBCXX_HAVE_FWSCANF 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_GCONV_H 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define _GLIBCXX_HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `getwc' function. */ +#define _GLIBCXX_HAVE_GETWC 1 + +/* Define to 1 if you have the `getwchar' function. */ +#define _GLIBCXX_HAVE_GETWCHAR 1 + +/* Define to 1 if you have the `hypot' function. */ +#define _GLIBCXX_HAVE_HYPOT 1 + +/* Define to 1 if you have the `hypotf' function. */ +#define _GLIBCXX_HAVE_HYPOTF 1 + +/* Define to 1 if you have the `hypotl' function. */ +/* #undef _GLIBCXX_HAVE_HYPOTL */ + +/* Define to 1 if you have the `iconv' function. */ +#define _GLIBCXX_HAVE_ICONV 1 + +/* Define to 1 if you have the `iconv_close' function. */ +#define _GLIBCXX_HAVE_ICONV_CLOSE 1 + +/* Define to 1 if you have the `iconv_open' function. */ +#define _GLIBCXX_HAVE_ICONV_OPEN 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_IEEEFP_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isinf' function. */ +#define _GLIBCXX_HAVE_ISINF 1 + +/* Define to 1 if you have the `isinff' function. */ +#define _GLIBCXX_HAVE_ISINFF 1 + +/* Define to 1 if you have the `isinfl' function. */ +/* #undef _GLIBCXX_HAVE_ISINFL */ + +/* Define to 1 if you have the `isnan' function. */ +#define _GLIBCXX_HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +#define _GLIBCXX_HAVE_ISNANF 1 + +/* Define to 1 if you have the `isnanl' function. */ +/* #undef _GLIBCXX_HAVE_ISNANL */ + +/* Define to 1 if you have the `iswblank' function. */ +#define _GLIBCXX_HAVE_ISWBLANK 1 + +/* Define to 1 if you have the `ldexpf' function. */ +#define _GLIBCXX_HAVE_LDEXPF 1 + +/* Define to 1 if you have the `ldexpl' function. */ +/* #undef _GLIBCXX_HAVE_LDEXPL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_LIBINTL_H 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#define _GLIBCXX_HAVE_LIBM 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_LIMIT_AS 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_LIMIT_DATA 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_LIMIT_FSIZE 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_LIMIT_RSS 1 + +/* Only used in build directory testsuite_hooks.h. */ +#define _GLIBCXX_HAVE_LIMIT_VMEM 0 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `log10f' function. */ +#define _GLIBCXX_HAVE_LOG10F 1 + +/* Define to 1 if you have the `log10l' function. */ +/* #undef _GLIBCXX_HAVE_LOG10L */ + +/* Define to 1 if you have the `logf' function. */ +#define _GLIBCXX_HAVE_LOGF 1 + +/* Define to 1 if you have the `logl' function. */ +/* #undef _GLIBCXX_HAVE_LOGL */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_MACHINE_ENDIAN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_MACHINE_PARAM_H */ + +/* Define to 1 if you have the `mbrlen' function. */ +#define _GLIBCXX_HAVE_MBRLEN 1 + +/* Define to 1 if you have the `mbrtowc' function. */ +#define _GLIBCXX_HAVE_MBRTOWC 1 + +/* Define to 1 if you have the `mbsinit' function. */ +#define _GLIBCXX_HAVE_MBSINIT 1 + +/* Define to 1 if you have the `mbsrtowcs' function. */ +#define _GLIBCXX_HAVE_MBSRTOWCS 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MEMORY_H 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define _GLIBCXX_HAVE_MMAP 1 + +/* Define to 1 if you have the `modff' function. */ +#define _GLIBCXX_HAVE_MODFF 1 + +/* Define to 1 if you have the `modfl' function. */ +/* #undef _GLIBCXX_HAVE_MODFL */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_NAN_H */ + +/* Define to 1 if you have the `nl_langinfo' function. */ +#define _GLIBCXX_HAVE_NL_LANGINFO 1 + +/* Define to 1 if you have the `powf' function. */ +#define _GLIBCXX_HAVE_POWF 1 + +/* Define to 1 if you have the `powl' function. */ +/* #undef _GLIBCXX_HAVE_POWL */ + +/* Define to 1 if you have the `putwc' function. */ +#define _GLIBCXX_HAVE_PUTWC 1 + +/* Define to 1 if you have the `putwchar' function. */ +#define _GLIBCXX_HAVE_PUTWCHAR 1 + +/* Define to 1 if you have the `qfpclass' function. */ +/* #undef _GLIBCXX_HAVE_QFPCLASS */ + +/* Define to 1 if you have the `setenv' function. */ +#define _GLIBCXX_HAVE_SETENV 1 + +/* Define if sigsetjmp is available. */ +#define _GLIBCXX_HAVE_SIGSETJMP 1 + +/* Define to 1 if you have the `sincos' function. */ +#define _GLIBCXX_HAVE_SINCOS 1 + +/* Define to 1 if you have the `sincosf' function. */ +#define _GLIBCXX_HAVE_SINCOSF 1 + +/* Define to 1 if you have the `sincosl' function. */ +/* #undef _GLIBCXX_HAVE_SINCOSL */ + +/* Define to 1 if you have the `sinf' function. */ +#define _GLIBCXX_HAVE_SINF 1 + +/* Define to 1 if you have the `sinhf' function. */ +#define _GLIBCXX_HAVE_SINHF 1 + +/* Define to 1 if you have the `sinhl' function. */ +/* #undef _GLIBCXX_HAVE_SINHL */ + +/* Define to 1 if you have the `sinl' function. */ +/* #undef _GLIBCXX_HAVE_SINL */ + +/* Define to 1 if you have the `sqrtf' function. */ +#define _GLIBCXX_HAVE_SQRTF 1 + +/* Define to 1 if you have the `sqrtl' function. */ +/* #undef _GLIBCXX_HAVE_SQRTL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtof' function. */ +#define _GLIBCXX_HAVE_STRTOF 1 + +/* Define to 1 if you have the `strtold' function. */ +#define _GLIBCXX_HAVE_STRTOLD 1 + +/* Define to 1 if you have the `swprintf' function. */ +#define _GLIBCXX_HAVE_SWPRINTF 1 + +/* Define to 1 if you have the `swscanf' function. */ +#define _GLIBCXX_HAVE_SWSCANF 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_FILIO_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_PARAM_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the `tanf' function. */ +#define _GLIBCXX_HAVE_TANF 1 + +/* Define to 1 if you have the `tanhf' function. */ +#define _GLIBCXX_HAVE_TANHF 1 + +/* Define to 1 if you have the `tanhl' function. */ +/* #undef _GLIBCXX_HAVE_TANHL */ + +/* Define to 1 if you have the `tanl' function. */ +/* #undef _GLIBCXX_HAVE_TANL */ + +/* Define to 1 if you have the `ungetwc' function. */ +#define _GLIBCXX_HAVE_UNGETWC 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vfwprintf' function. */ +#define _GLIBCXX_HAVE_VFWPRINTF 1 + +/* Define to 1 if you have the `vfwscanf' function. */ +#define _GLIBCXX_HAVE_VFWSCANF 1 + +/* Define to 1 if you have the `vswprintf' function. */ +#define _GLIBCXX_HAVE_VSWPRINTF 1 + +/* Define to 1 if you have the `vswscanf' function. */ +#define _GLIBCXX_HAVE_VSWSCANF 1 + +/* Define to 1 if you have the `vwprintf' function. */ +#define _GLIBCXX_HAVE_VWPRINTF 1 + +/* Define to 1 if you have the `vwscanf' function. */ +#define _GLIBCXX_HAVE_VWSCANF 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCHAR_H 1 + +/* Define to 1 if you have the `wcrtomb' function. */ +#define _GLIBCXX_HAVE_WCRTOMB 1 + +/* Define to 1 if you have the `wcscat' function. */ +#define _GLIBCXX_HAVE_WCSCAT 1 + +/* Define to 1 if you have the `wcschr' function. */ +#define _GLIBCXX_HAVE_WCSCHR 1 + +/* Define to 1 if you have the `wcscmp' function. */ +#define _GLIBCXX_HAVE_WCSCMP 1 + +/* Define to 1 if you have the `wcscoll' function. */ +#define _GLIBCXX_HAVE_WCSCOLL 1 + +/* Define to 1 if you have the `wcscpy' function. */ +#define _GLIBCXX_HAVE_WCSCPY 1 + +/* Define to 1 if you have the `wcscspn' function. */ +#define _GLIBCXX_HAVE_WCSCSPN 1 + +/* Define to 1 if you have the `wcsftime' function. */ +#define _GLIBCXX_HAVE_WCSFTIME 1 + +/* Define to 1 if you have the `wcslen' function. */ +#define _GLIBCXX_HAVE_WCSLEN 1 + +/* Define to 1 if you have the `wcsncat' function. */ +#define _GLIBCXX_HAVE_WCSNCAT 1 + +/* Define to 1 if you have the `wcsncmp' function. */ +#define _GLIBCXX_HAVE_WCSNCMP 1 + +/* Define to 1 if you have the `wcsncpy' function. */ +#define _GLIBCXX_HAVE_WCSNCPY 1 + +/* Define to 1 if you have the `wcspbrk' function. */ +#define _GLIBCXX_HAVE_WCSPBRK 1 + +/* Define to 1 if you have the `wcsrchr' function. */ +#define _GLIBCXX_HAVE_WCSRCHR 1 + +/* Define to 1 if you have the `wcsrtombs' function. */ +#define _GLIBCXX_HAVE_WCSRTOMBS 1 + +/* Define to 1 if you have the `wcsspn' function. */ +#define _GLIBCXX_HAVE_WCSSPN 1 + +/* Define to 1 if you have the `wcsstr' function. */ +#define _GLIBCXX_HAVE_WCSSTR 1 + +/* Define to 1 if you have the `wcstod' function. */ +#define _GLIBCXX_HAVE_WCSTOD 1 + +/* Define to 1 if you have the `wcstof' function. */ +#define _GLIBCXX_HAVE_WCSTOF 1 + +/* Define to 1 if you have the `wcstok' function. */ +#define _GLIBCXX_HAVE_WCSTOK 1 + +/* Define to 1 if you have the `wcstol' function. */ +#define _GLIBCXX_HAVE_WCSTOL 1 + +/* Define to 1 if you have the `wcstoul' function. */ +#define _GLIBCXX_HAVE_WCSTOUL 1 + +/* Define to 1 if you have the `wcsxfrm' function. */ +#define _GLIBCXX_HAVE_WCSXFRM 1 + +/* Define to 1 if you have the `wctob' function. */ +#define _GLIBCXX_HAVE_WCTOB 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCTYPE_H 1 + +/* Define to 1 if you have the `wmemchr' function. */ +#define _GLIBCXX_HAVE_WMEMCHR 1 + +/* Define to 1 if you have the `wmemcmp' function. */ +#define _GLIBCXX_HAVE_WMEMCMP 1 + +/* Define to 1 if you have the `wmemcpy' function. */ +#define _GLIBCXX_HAVE_WMEMCPY 1 + +/* Define to 1 if you have the `wmemmove' function. */ +#define _GLIBCXX_HAVE_WMEMMOVE 1 + +/* Define to 1 if you have the `wmemset' function. */ +#define _GLIBCXX_HAVE_WMEMSET 1 + +/* Define to 1 if you have the `wprintf' function. */ +#define _GLIBCXX_HAVE_WPRINTF 1 + +/* Define to 1 if you have the `wscanf' function. */ +#define _GLIBCXX_HAVE_WSCANF 1 + +/* Define to 1 if you have the `_acosf' function. */ +/* #undef _GLIBCXX_HAVE__ACOSF */ + +/* Define to 1 if you have the `_acosl' function. */ +/* #undef _GLIBCXX_HAVE__ACOSL */ + +/* Define to 1 if you have the `_asinf' function. */ +/* #undef _GLIBCXX_HAVE__ASINF */ + +/* Define to 1 if you have the `_asinl' function. */ +/* #undef _GLIBCXX_HAVE__ASINL */ + +/* Define to 1 if you have the `_atan2f' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2F */ + +/* Define to 1 if you have the `_atan2l' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2L */ + +/* Define to 1 if you have the `_atanf' function. */ +/* #undef _GLIBCXX_HAVE__ATANF */ + +/* Define to 1 if you have the `_atanl' function. */ +/* #undef _GLIBCXX_HAVE__ATANL */ + +/* Define to 1 if you have the `_ceilf' function. */ +/* #undef _GLIBCXX_HAVE__CEILF */ + +/* Define to 1 if you have the `_ceill' function. */ +/* #undef _GLIBCXX_HAVE__CEILL */ + +/* Define to 1 if you have the `_copysign' function. */ +/* #undef _GLIBCXX_HAVE__COPYSIGN */ + +/* Define to 1 if you have the `_copysignl' function. */ +/* #undef _GLIBCXX_HAVE__COPYSIGNL */ + +/* Define to 1 if you have the `_cosf' function. */ +/* #undef _GLIBCXX_HAVE__COSF */ + +/* Define to 1 if you have the `_coshf' function. */ +/* #undef _GLIBCXX_HAVE__COSHF */ + +/* Define to 1 if you have the `_coshl' function. */ +/* #undef _GLIBCXX_HAVE__COSHL */ + +/* Define to 1 if you have the `_cosl' function. */ +/* #undef _GLIBCXX_HAVE__COSL */ + +/* Define to 1 if you have the `_expf' function. */ +/* #undef _GLIBCXX_HAVE__EXPF */ + +/* Define to 1 if you have the `_expl' function. */ +/* #undef _GLIBCXX_HAVE__EXPL */ + +/* Define to 1 if you have the `_fabsf' function. */ +/* #undef _GLIBCXX_HAVE__FABSF */ + +/* Define to 1 if you have the `_fabsl' function. */ +/* #undef _GLIBCXX_HAVE__FABSL */ + +/* Define to 1 if you have the `_finite' function. */ +/* #undef _GLIBCXX_HAVE__FINITE */ + +/* Define to 1 if you have the `_finitef' function. */ +/* #undef _GLIBCXX_HAVE__FINITEF */ + +/* Define to 1 if you have the `_finitel' function. */ +/* #undef _GLIBCXX_HAVE__FINITEL */ + +/* Define to 1 if you have the `_floorf' function. */ +/* #undef _GLIBCXX_HAVE__FLOORF */ + +/* Define to 1 if you have the `_floorl' function. */ +/* #undef _GLIBCXX_HAVE__FLOORL */ + +/* Define to 1 if you have the `_fmodf' function. */ +/* #undef _GLIBCXX_HAVE__FMODF */ + +/* Define to 1 if you have the `_fmodl' function. */ +/* #undef _GLIBCXX_HAVE__FMODL */ + +/* Define to 1 if you have the `_fpclass' function. */ +/* #undef _GLIBCXX_HAVE__FPCLASS */ + +/* Define to 1 if you have the `_frexpf' function. */ +/* #undef _GLIBCXX_HAVE__FREXPF */ + +/* Define to 1 if you have the `_frexpl' function. */ +/* #undef _GLIBCXX_HAVE__FREXPL */ + +/* Define to 1 if you have the `_hypot' function. */ +/* #undef _GLIBCXX_HAVE__HYPOT */ + +/* Define to 1 if you have the `_hypotf' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTF */ + +/* Define to 1 if you have the `_hypotl' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTL */ + +/* Define to 1 if you have the `_isinf' function. */ +/* #undef _GLIBCXX_HAVE__ISINF */ + +/* Define to 1 if you have the `_isinff' function. */ +/* #undef _GLIBCXX_HAVE__ISINFF */ + +/* Define to 1 if you have the `_isinfl' function. */ +/* #undef _GLIBCXX_HAVE__ISINFL */ + +/* Define to 1 if you have the `_isnan' function. */ +/* #undef _GLIBCXX_HAVE__ISNAN */ + +/* Define to 1 if you have the `_isnanf' function. */ +/* #undef _GLIBCXX_HAVE__ISNANF */ + +/* Define to 1 if you have the `_isnanl' function. */ +/* #undef _GLIBCXX_HAVE__ISNANL */ + +/* Define to 1 if you have the `_ldexpf' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPF */ + +/* Define to 1 if you have the `_ldexpl' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPL */ + +/* Define to 1 if you have the `_log10f' function. */ +/* #undef _GLIBCXX_HAVE__LOG10F */ + +/* Define to 1 if you have the `_log10l' function. */ +/* #undef _GLIBCXX_HAVE__LOG10L */ + +/* Define to 1 if you have the `_logf' function. */ +/* #undef _GLIBCXX_HAVE__LOGF */ + +/* Define to 1 if you have the `_logl' function. */ +/* #undef _GLIBCXX_HAVE__LOGL */ + +/* Define to 1 if you have the `_modff' function. */ +/* #undef _GLIBCXX_HAVE__MODFF */ + +/* Define to 1 if you have the `_modfl' function. */ +/* #undef _GLIBCXX_HAVE__MODFL */ + +/* Define to 1 if you have the `_powf' function. */ +/* #undef _GLIBCXX_HAVE__POWF */ + +/* Define to 1 if you have the `_powl' function. */ +/* #undef _GLIBCXX_HAVE__POWL */ + +/* Define to 1 if you have the `_qfpclass' function. */ +/* #undef _GLIBCXX_HAVE__QFPCLASS */ + +/* Define to 1 if you have the `_sincos' function. */ +/* #undef _GLIBCXX_HAVE__SINCOS */ + +/* Define to 1 if you have the `_sincosf' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSF */ + +/* Define to 1 if you have the `_sincosl' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSL */ + +/* Define to 1 if you have the `_sinf' function. */ +/* #undef _GLIBCXX_HAVE__SINF */ + +/* Define to 1 if you have the `_sinhf' function. */ +/* #undef _GLIBCXX_HAVE__SINHF */ + +/* Define to 1 if you have the `_sinhl' function. */ +/* #undef _GLIBCXX_HAVE__SINHL */ + +/* Define to 1 if you have the `_sinl' function. */ +/* #undef _GLIBCXX_HAVE__SINL */ + +/* Define to 1 if you have the `_sqrtf' function. */ +/* #undef _GLIBCXX_HAVE__SQRTF */ + +/* Define to 1 if you have the `_sqrtl' function. */ +/* #undef _GLIBCXX_HAVE__SQRTL */ + +/* Define to 1 if you have the `_tanf' function. */ +/* #undef _GLIBCXX_HAVE__TANF */ + +/* Define to 1 if you have the `_tanhf' function. */ +/* #undef _GLIBCXX_HAVE__TANHF */ + +/* Define to 1 if you have the `_tanhl' function. */ +/* #undef _GLIBCXX_HAVE__TANHL */ + +/* Define to 1 if you have the `_tanl' function. */ +/* #undef _GLIBCXX_HAVE__TANL */ + +/* Define to 1 if you have the `__signbit' function. */ +#define _GLIBCXX_HAVE___SIGNBIT 1 + +/* Define to 1 if you have the `__signbitf' function. */ +#define _GLIBCXX_HAVE___SIGNBITF 1 + +/* Define to 1 if you have the `__signbitl' function. */ +/* #undef _GLIBCXX_HAVE___SIGNBITL */ + +/* Define to the address where bug reports for this package should be sent. */ +#define _GLIBCXX_PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define _GLIBCXX_PACKAGE_NAME "package-unused" + +/* Define to the full name and version of this package. */ +#define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" + +/* Define to the one symbol short name of this package. */ +#define _GLIBCXX_PACKAGE_TARNAME "libstdc++" + +/* Define to the version of this package. */ +#define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if a full hosted library is built, or 0 if freestanding. */ +#define _GLIBCXX_HOSTED 1 + +/* Define if the compiler is configured for setjmp/longjmp exceptions. */ +/* #undef _GLIBCXX_SJLJ_EXCEPTIONS */ +// +// Systems that have certain non-standard functions prefixed with an +// underscore, we'll handle those here. Must come after config.h.in. +// +#if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) +# define _GLIBCXX_HAVE_ISNAN 1 +# define isnan _isnan +#endif + +#if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) +# define _GLIBCXX_HAVE_ISNANF 1 +# define isnanf _isnanf +#endif + +#if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) +# define _GLIBCXX_HAVE_ISNANL 1 +# define isnanl _isnanl +#endif + +#if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) +# define _GLIBCXX_HAVE_ISINF 1 +# define isinf _isinf +#endif + +#if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) +# define _GLIBCXX_HAVE_ISINFF 1 +# define isinff _isinff +#endif + +#if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) +# define _GLIBCXX_HAVE_ISINFL 1 +# define isinfl _isinfl +#endif + +#if defined (_GLIBCXX_HAVE__COPYSIGN) && ! defined (_GLIBCXX_HAVE_COPYSIGN) +# define _GLIBCXX_HAVE_COPYSIGN 1 +# define copysign _copysign +#endif + +#if defined (_GLIBCXX_HAVE__COPYSIGNL) && ! defined (_GLIBCXX_HAVE_COPYSIGNL) +# define _GLIBCXX_HAVE_COPYSIGNL 1 +# define copysignl _copysignl +#endif + +#if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) +# define _GLIBCXX_HAVE_COSF 1 +# define cosf _cosf +#endif + +#if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) +# define _GLIBCXX_HAVE_ACOSF 1 +# define acosf _acosf +#endif + +#if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) +# define _GLIBCXX_HAVE_ACOSL 1 +# define acosl _acosl +#endif + +#if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) +# define _GLIBCXX_HAVE_ASINF 1 +# define asinf _asinf +#endif + +#if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) +# define _GLIBCXX_HAVE_ASINL 1 +# define asinl _asinl +#endif + +#if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) +# define _GLIBCXX_HAVE_ATANF 1 +# define atanf _atanf +#endif + +#if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) +# define _GLIBCXX_HAVE_ATANL 1 +# define atanl _atanl +#endif + +#if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) +# define _GLIBCXX_HAVE_CEILF 1 +# define aceil _ceilf +#endif + +#if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) +# define _GLIBCXX_HAVE_CEILL 1 +# define aceil _ceill +#endif + +#if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) +# define _GLIBCXX_HAVE_COSHF 1 +# define coshf _coshf +#endif + +#if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) +# define _GLIBCXX_HAVE_COSL 1 +# define cosl _cosl +#endif + +#if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) +# define _GLIBCXX_HAVE_LOGF 1 +# define logf _logf +#endif + +#if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) +# define _GLIBCXX_HAVE_COSHL 1 +# define coshl _coshl +#endif + +#if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) +# define _GLIBCXX_HAVE_EXPF 1 +# define expf _expf +#endif + +#if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) +# define _GLIBCXX_HAVE_EXPL 1 +# define expl _expl +#endif + +#if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) +# define _GLIBCXX_HAVE_FABSF 1 +# define fabsf _fabsf +#endif + +#if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) +# define _GLIBCXX_HAVE_FABSL 1 +# define fabsl _fabsl +#endif + +#if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) +# define _GLIBCXX_HAVE_FLOORF 1 +# define floorf _floorf +#endif + +#if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) +# define _GLIBCXX_HAVE_FLOORL 1 +# define floorl _floorl +#endif + +#if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) +# define _GLIBCXX_HAVE_FMODF 1 +# define fmodf _fmodf +#endif + +#if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) +# define _GLIBCXX_HAVE_FMODL 1 +# define fmodl _fmodl +#endif + +#if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) +# define _GLIBCXX_HAVE_FREXPF 1 +# define frexpf _frexpf +#endif + +#if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) +# define _GLIBCXX_HAVE_FREXPL 1 +# define frexpl _frexpl +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) +# define _GLIBCXX_HAVE_LDEXPF 1 +# define ldexpf _ldexpf +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) +# define _GLIBCXX_HAVE_LDEXPL 1 +# define ldexpl _ldexpl +#endif + +#if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) +# define _GLIBCXX_HAVE_LOG10F 1 +# define log10f _log10f +#endif + +#if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) +# define _GLIBCXX_HAVE_LOGL 1 +# define logl _logl +#endif + +#if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) +# define _GLIBCXX_HAVE_POWF 1 +# define powf _powf +#endif + +#if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) +# define _GLIBCXX_HAVE_LOG10L 1 +# define log10l _log10l +#endif + +#if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) +# define _GLIBCXX_HAVE_MODF 1 +# define modf _modf +#endif + +#if defined (_GLIBCXX_HAVE__MODL) && ! defined (_GLIBCXX_HAVE_MODL) +# define _GLIBCXX_HAVE_MODL 1 +# define modl _modl +#endif + +#if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) +# define _GLIBCXX_HAVE_SINF 1 +# define sinf _sinf +#endif + +#if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) +# define _GLIBCXX_HAVE_POWL 1 +# define powl _powl +#endif + +#if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) +# define _GLIBCXX_HAVE_SINHF 1 +# define sinhf _sinhf +#endif + +#if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) +# define _GLIBCXX_HAVE_SINL 1 +# define sinl _sinl +#endif + +#if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) +# define _GLIBCXX_HAVE_SQRTF 1 +# define sqrtf _sqrtf +#endif + +#if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) +# define _GLIBCXX_HAVE_SINHL 1 +# define sinhl _sinhl +#endif + +#if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) +# define _GLIBCXX_HAVE_TANF 1 +# define tanf _tanf +#endif + +#if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) +# define _GLIBCXX_HAVE_SQRTL 1 +# define sqrtl _sqrtl +#endif + +#if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) +# define _GLIBCXX_HAVE_TANHF 1 +# define tanhf _tanhf +#endif + +#if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) +# define _GLIBCXX_HAVE_TANF 1 +# define tanf _tanf +#endif + +#if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) +# define _GLIBCXX_HAVE_STRTOF 1 +# define strtof _strtof +#endif + +#if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) +# define _GLIBCXX_HAVE_TANHL 1 +# define tanhl _tanhl +#endif + +#if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) +# define _GLIBCXX_HAVE_STRTOLD 1 +# define strtold _strtold +#endif + +#if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) +# define _GLIBCXX_HAVE_SINCOS 1 +# define sincos _sincos +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) +# define _GLIBCXX_HAVE_SINCOSF 1 +# define sincosf _sincosf +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) +# define _GLIBCXX_HAVE_SINCOSL 1 +# define sincosl _sincosl +#endif + +#if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) +# define _GLIBCXX_HAVE_FINITE 1 +# define finite _finite +#endif + +#if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) +# define _GLIBCXX_HAVE_FINITEF 1 +# define finitef _finitef +#endif + +#if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) +# define _GLIBCXX_HAVE_FINITEL 1 +# define finitel _finitel +#endif + +#if defined (_GLIBCXX_HAVE__QFINITE) && ! defined (_GLIBCXX_HAVE_QFINITE) +# define _GLIBCXX_HAVE_QFINITE 1 +# define qfinite _qfinite +#endif + +#if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) +# define _GLIBCXX_HAVE_FPCLASS 1 +# define fpclass _fpclass +#endif + +#if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) +# define _GLIBCXX_HAVE_QFPCLASS 1 +# define qfpclass _qfpclass +#endif + +#endif // _CXXCONFIG_ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++io.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++io.h new file mode 100644 index 00000000000..5659c139730 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++io.h @@ -0,0 +1,86 @@ +// underlying io library -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// c_io_stdio.h - Defines for using "C" stdio.h + +#ifndef _C_IO_STDIO_H +#define _C_IO_STDIO_H 1 + +#include +#include +#include + +namespace std +{ + typedef __gthread_mutex_t __c_lock; + + // for basic_file.h + typedef FILE __c_file; + + // XXX GLIBCXX_ABI Deprecated + // for ios_base.h + struct __ios_flags + { + typedef short __int_type; + + static const __int_type _S_boolalpha = 0x0001; + static const __int_type _S_dec = 0x0002; + static const __int_type _S_fixed = 0x0004; + static const __int_type _S_hex = 0x0008; + static const __int_type _S_internal = 0x0010; + static const __int_type _S_left = 0x0020; + static const __int_type _S_oct = 0x0040; + static const __int_type _S_right = 0x0080; + static const __int_type _S_scientific = 0x0100; + static const __int_type _S_showbase = 0x0200; + static const __int_type _S_showpoint = 0x0400; + static const __int_type _S_showpos = 0x0800; + static const __int_type _S_skipws = 0x1000; + static const __int_type _S_unitbuf = 0x2000; + static const __int_type _S_uppercase = 0x4000; + static const __int_type _S_adjustfield = 0x0020 | 0x0080 | 0x0010; + static const __int_type _S_basefield = 0x0002 | 0x0040 | 0x0008; + static const __int_type _S_floatfield = 0x0100 | 0x0004; + + // 27.4.2.1.3 Type ios_base::iostate + static const __int_type _S_badbit = 0x01; + static const __int_type _S_eofbit = 0x02; + static const __int_type _S_failbit = 0x04; + + // 27.4.2.1.4 Type openmode + static const __int_type _S_app = 0x01; + static const __int_type _S_ate = 0x02; + static const __int_type _S_bin = 0x04; + static const __int_type _S_in = 0x08; + static const __int_type _S_out = 0x10; + static const __int_type _S_trunc = 0x20; + }; +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++locale.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++locale.h new file mode 100644 index 00000000000..b6082a2e3fc --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/c++locale.h @@ -0,0 +1,99 @@ +// Wrapper for underlying C-language localization -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.8 Standard locale categories. +// + +// Written by Benjamin Kosnik + +#ifndef _C_LOCALE_H +#define _C_LOCALE_H 1 + +#pragma GCC system_header + +#include // get std::strlen +#include // get std::snprintf or std::sprintf +#include +#include // For codecvt +#include // For codecvt using iconv, iconv_t +#include // For messages + +#define _GLIBCXX_C_LOCALE_GNU 1 + +#define _GLIBCXX_NUM_CATEGORIES 6 + +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) +namespace __gnu_cxx +{ + extern "C" __typeof(uselocale) __uselocale; +} +#endif + +namespace std +{ + typedef __locale_t __c_locale; + + // Convert numeric value of type _Tv to string and return length of + // string. If snprintf is available use it, otherwise fall back to + // the unsafe sprintf which, in general, can be dangerous and should + // be avoided. + template + int + __convert_from_v(char* __out, const int __size, const char* __fmt, +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) + _Tv __v, const __c_locale& __cloc, int __prec) + { + __c_locale __old = __gnu_cxx::__uselocale(__cloc); +#else + _Tv __v, const __c_locale&, int __prec) + { + char* __old = std::setlocale(LC_ALL, NULL); + char* __sav = new char[std::strlen(__old) + 1]; + std::strcpy(__sav, __old); + std::setlocale(LC_ALL, "C"); +#endif + +#ifdef _GLIBCXX_USE_C99 + const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v); +#else + const int __ret = std::sprintf(__out, __fmt, __prec, __v); +#endif + +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) + __gnu_cxx::__uselocale(__old); +#else + std::setlocale(LC_ALL, __sav); + delete [] __sav; +#endif + return __ret; + } +} + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/codecvt_specializations.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/codecvt_specializations.h new file mode 100644 index 00000000000..79a033d17c8 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/codecvt_specializations.h @@ -0,0 +1,478 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Warning: this file is not meant for user inclusion. Use . + +// Written by Benjamin Kosnik + + // XXX + // Define this here so codecvt.cc can have _S_max_size definition. +#define _GLIBCXX_USE___ENC_TRAITS 1 + + // Extension to use icov for dealing with character encodings, + // including conversions and comparisons between various character + // sets. This object encapsulates data that may need to be shared between + // char_traits, codecvt and ctype. + class __enc_traits + { + public: + // Types: + // NB: A conversion descriptor subsumes and enhances the + // functionality of a simple state type such as mbstate_t. + typedef iconv_t __desc_type; + + protected: + // Data Members: + // Max size of charset encoding name + static const int _S_max_size = 32; + // Name of internal character set encoding. + char _M_int_enc[_S_max_size]; + // Name of external character set encoding. + char _M_ext_enc[_S_max_size]; + + // Conversion descriptor between external encoding to internal encoding. + __desc_type _M_in_desc; + // Conversion descriptor between internal encoding to external encoding. + __desc_type _M_out_desc; + + // Details the byte-order marker for the external encoding, if necessary. + int _M_ext_bom; + + // Details the byte-order marker for the internal encoding, if necessary. + int _M_int_bom; + + public: + explicit __enc_traits() + : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0) + { + memset(_M_int_enc, 0, _S_max_size); + memset(_M_ext_enc, 0, _S_max_size); + } + + explicit __enc_traits(const char* __int, const char* __ext, + int __ibom = 0, int __ebom = 0) + : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(__ebom), _M_int_bom(__ibom) + { + strncpy(_M_int_enc, __int, _S_max_size); + strncpy(_M_ext_enc, __ext, _S_max_size); + _M_init(); + } + + // 21.1.2 traits typedefs + // p4 + // typedef STATE_T state_type + // requires: state_type shall meet the requirements of + // CopyConstructible types (20.1.3) + // NB: This does not preseve the actual state of the conversion + // descriptor member, but it does duplicate the encoding + // information. + __enc_traits(const __enc_traits& __obj): _M_in_desc(0), _M_out_desc(0) + { + strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size); + strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size); + _M_ext_bom = __obj._M_ext_bom; + _M_int_bom = __obj._M_int_bom; + _M_destroy(); + _M_init(); + } + + // Need assignment operator as well. + __enc_traits& + operator=(const __enc_traits& __obj) + { + strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size); + strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size); + _M_ext_bom = __obj._M_ext_bom; + _M_int_bom = __obj._M_int_bom; + _M_destroy(); + _M_init(); + return *this; + } + + ~__enc_traits() + { _M_destroy(); } + + void + _M_init() + { + const __desc_type __err = reinterpret_cast(-1); + if (!_M_in_desc) + { + _M_in_desc = iconv_open(_M_int_enc, _M_ext_enc); + if (_M_in_desc == __err) + __throw_runtime_error(__N("__enc_traits::_M_init " + "creating iconv input descriptor failed")); + } + if (!_M_out_desc) + { + _M_out_desc = iconv_open(_M_ext_enc, _M_int_enc); + if (_M_out_desc == __err) + __throw_runtime_error(__N("__enc_traits::_M_init " + "creating iconv output descriptor failed")); + } + } + + void + _M_destroy() + { + const __desc_type __err = reinterpret_cast(-1); + if (_M_in_desc && _M_in_desc != __err) + { + iconv_close(_M_in_desc); + _M_in_desc = 0; + } + if (_M_out_desc && _M_out_desc != __err) + { + iconv_close(_M_out_desc); + _M_out_desc = 0; + } + } + + bool + _M_good() + { + const __desc_type __err = reinterpret_cast(-1); + bool __test = _M_in_desc && _M_in_desc != __err; + __test &= _M_out_desc && _M_out_desc != __err; + return __test; + } + + const __desc_type* + _M_get_in_descriptor() + { return &_M_in_desc; } + + const __desc_type* + _M_get_out_descriptor() + { return &_M_out_desc; } + + int + _M_get_external_bom() + { return _M_ext_bom; } + + int + _M_get_internal_bom() + { return _M_int_bom; } + + const char* + _M_get_internal_enc() + { return _M_int_enc; } + + const char* + _M_get_external_enc() + { return _M_ext_enc; } + }; + + // Partial specialization + // This specialization takes advantage of iconv to provide code + // conversions between a large number of character encodings. + template + class codecvt<_InternT, _ExternT, __enc_traits> + : public __codecvt_abstract_base<_InternT, _ExternT, __enc_traits> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef __enc_traits state_type; + typedef __enc_traits::__desc_type __desc_type; + typedef __enc_traits __enc_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base(__refs) + { } + + explicit + codecvt(__enc_type* __enc, size_t __refs = 0) + : __codecvt_abstract_base(__refs) + { } + + protected: + virtual + ~codecvt() { } + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template + locale::id + codecvt<_InternT, _ExternT, __enc_traits>::id; + + // This adaptor works around the signature problems of the second + // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 + // uses 'char**', which matches the POSIX 1003.1-2001 standard. + // Using this adaptor, g++ will do the work for us. + template + inline size_t + __iconv_adaptor(size_t(*__func)(iconv_t, _T, size_t*, char**, size_t*), + iconv_t __cd, char** __inbuf, size_t* __inbytes, + char** __outbuf, size_t* __outbytes) + { return __func(__cd, (_T)__inbuf, __inbytes, __outbuf, __outbytes); } + + template + codecvt_base::result + codecvt<_InternT, _ExternT, __enc_traits>:: + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state._M_good()) + { + const __desc_type* __desc = __state._M_get_out_descriptor(); + const size_t __fmultiple = sizeof(intern_type); + size_t __fbytes = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(extern_type); + size_t __tbytes = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast(__to); + char* __cfrom; + size_t __conv; + + // Some encodings need a byte order marker as the first item + // in the byte stream, to designate endian-ness. The default + // value for the byte order marker is NULL, so if this is + // the case, it's not necessary and we can just go on our + // merry way. + int __int_bom = __state._M_get_internal_bom(); + if (__int_bom) + { + size_t __size = __from_end - __from; + intern_type* __cfixed = static_cast + (__builtin_alloca(sizeof(intern_type) * (__size + 1))); + __cfixed[0] = static_cast(__int_bom); + char_traits::copy(__cfixed + 1, __from, __size); + __cfrom = reinterpret_cast(__cfixed); + __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, + &__fbytes, &__cto, &__tbytes); + } + else + { + intern_type* __cfixed = const_cast(__from); + __cfrom = reinterpret_cast(__cfixed); + __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, &__fbytes, + &__cto, &__tbytes); + } + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast(__cfrom); + __to_next = reinterpret_cast(__cto); + __ret = codecvt_base::ok; + } + else + { + if (__fbytes < __fmultiple * (__from_end - __from)) + { + __from_next = reinterpret_cast(__cfrom); + __to_next = reinterpret_cast(__cto); + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + } + return __ret; + } + + template + codecvt_base::result + codecvt<_InternT, _ExternT, __enc_traits>:: + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state._M_good()) + { + const __desc_type* __desc = __state._M_get_in_descriptor(); + const size_t __tmultiple = sizeof(intern_type); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast(__to); + size_t __conv = __iconv_adaptor(iconv,*__desc, NULL, NULL, + &__cto, &__tlen); + + if (__conv != size_t(-1)) + { + __to_next = reinterpret_cast(__cto); + if (__tlen == __tmultiple * (__to_end - __to)) + __ret = codecvt_base::noconv; + else if (__tlen == 0) + __ret = codecvt_base::ok; + else + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + return __ret; + } + + template + codecvt_base::result + codecvt<_InternT, _ExternT, __enc_traits>:: + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state._M_good()) + { + const __desc_type* __desc = __state._M_get_in_descriptor(); + const size_t __fmultiple = sizeof(extern_type); + size_t __flen = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(intern_type); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast(__to); + char* __cfrom; + size_t __conv; + + // Some encodings need a byte order marker as the first item + // in the byte stream, to designate endian-ness. The default + // value for the byte order marker is NULL, so if this is + // the case, it's not necessary and we can just go on our + // merry way. + int __ext_bom = __state._M_get_external_bom(); + if (__ext_bom) + { + size_t __size = __from_end - __from; + extern_type* __cfixed = static_cast + (__builtin_alloca(sizeof(extern_type) * (__size + 1))); + __cfixed[0] = static_cast(__ext_bom); + char_traits::copy(__cfixed + 1, __from, __size); + __cfrom = reinterpret_cast(__cfixed); + __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, + &__flen, &__cto, &__tlen); + } + else + { + extern_type* __cfixed = const_cast(__from); + __cfrom = reinterpret_cast(__cfixed); + __conv = __iconv_adaptor(iconv, *__desc, &__cfrom, + &__flen, &__cto, &__tlen); + } + + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast(__cfrom); + __to_next = reinterpret_cast(__cto); + __ret = codecvt_base::ok; + } + else + { + if (__flen < static_cast(__from_end - __from)) + { + __from_next = reinterpret_cast(__cfrom); + __to_next = reinterpret_cast(__cto); + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + } + return __ret; + } + + template + int + codecvt<_InternT, _ExternT, __enc_traits>:: + do_encoding() const throw() + { + int __ret = 0; + if (sizeof(_ExternT) <= sizeof(_InternT)) + __ret = sizeof(_InternT)/sizeof(_ExternT); + return __ret; + } + + template + bool + codecvt<_InternT, _ExternT, __enc_traits>:: + do_always_noconv() const throw() + { return false; } + + template + int + codecvt<_InternT, _ExternT, __enc_traits>:: + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return std::min(__max, static_cast(__end - __from)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 74. Garbled text for codecvt::do_max_length + template + int + codecvt<_InternT, _ExternT, __enc_traits>:: + do_max_length() const throw() + { return 1; } + diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_base.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_base.h new file mode 100644 index 00000000000..fc27a3f5863 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_base.h @@ -0,0 +1,56 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// Information as gleaned from /usr/include/ctype.h + + struct ctype_base + { + // Non-standard typedefs. + typedef const int* __to_type; + + // NB: Offsets into ctype::_M_table force a particular size + // on the mask type. Because of this, we don't use an enum. + typedef unsigned short mask; + static const mask upper = _ISupper; + static const mask lower = _ISlower; + static const mask alpha = _ISalpha; + static const mask digit = _ISdigit; + static const mask xdigit = _ISxdigit; + static const mask space = _ISspace; + static const mask print = _ISprint; + static const mask graph = _ISalpha | _ISdigit | _ISpunct; + static const mask cntrl = _IScntrl; + static const mask punct = _ISpunct; + static const mask alnum = _ISalpha | _ISdigit; + }; diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_inline.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_inline.h new file mode 100644 index 00000000000..af409c87629 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_inline.h @@ -0,0 +1,69 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) +// functions go in ctype.cc + + bool + ctype:: + is(mask __m, char __c) const + { return _M_table[static_cast(__c)] & __m; } + + const char* + ctype:: + is(const char* __low, const char* __high, mask* __vec) const + { + while (__low < __high) + *__vec++ = _M_table[static_cast(*__low++)]; + return __high; + } + + const char* + ctype:: + scan_is(mask __m, const char* __low, const char* __high) const + { + while (__low < __high + && !(_M_table[static_cast(*__low)] & __m)) + ++__low; + return __low; + } + + const char* + ctype:: + scan_not(mask __m, const char* __low, const char* __high) const + { + while (__low < __high + && (_M_table[static_cast(*__low)] & __m) != 0) + ++__low; + return __low; + } diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_noninline.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_noninline.h new file mode 100644 index 00000000000..925a5d0122f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/ctype_noninline.h @@ -0,0 +1,159 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.1 Locales +// + +// Information as gleaned from /usr/include/ctype.h + +#if _GLIBCXX_C_LOCALE_GNU + const ctype_base::mask* + ctype::classic_table() throw() + { return _S_get_c_locale()->__ctype_b; } +#else + const ctype_base::mask* + ctype::classic_table() throw() + { + const ctype_base::mask* __ret; + char* __old = strdup(setlocale(LC_CTYPE, NULL)); + setlocale(LC_CTYPE, "C"); +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) + __ret = *__ctype_b_loc(); +#else + __ret = __ctype_b; +#endif + setlocale(LC_CTYPE, __old); + free(__old); + return __ret; + } +#endif + +#if _GLIBCXX_C_LOCALE_GNU + ctype::ctype(__c_locale __cloc, const mask* __table, bool __del, + size_t __refs) + : facet(__refs), _M_c_locale_ctype(_S_clone_c_locale(__cloc)), + _M_del(__table != 0 && __del), + _M_toupper(_M_c_locale_ctype->__ctype_toupper), + _M_tolower(_M_c_locale_ctype->__ctype_tolower), + _M_table(__table ? __table : _M_c_locale_ctype->__ctype_b), + _M_widen_ok(0), _M_narrow_ok(0) + { + memset(_M_widen, 0, sizeof(_M_widen)); + memset(_M_narrow, 0, sizeof(_M_narrow)); + } +#else + ctype::ctype(__c_locale, const mask* __table, bool __del, + size_t __refs) + : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), + _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0) + { + char* __old=strdup(setlocale(LC_CTYPE, NULL)); + setlocale(LC_CTYPE, "C"); +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) + _M_toupper = *__ctype_toupper_loc(); + _M_tolower = *__ctype_tolower_loc(); + _M_table = __table ? __table : *__ctype_b_loc(); +#else + _M_toupper = __ctype_toupper; + _M_tolower = __ctype_tolower; + _M_table = __table ? __table : __ctype_b; +#endif + setlocale(LC_CTYPE, __old); + free(__old); + memset(_M_widen, 0, sizeof(_M_widen)); + memset(_M_narrow, 0, sizeof(_M_narrow)); + } +#endif + +#if _GLIBCXX_C_LOCALE_GNU + ctype::ctype(const mask* __table, bool __del, size_t __refs) + : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), + _M_del(__table != 0 && __del), + _M_toupper(_M_c_locale_ctype->__ctype_toupper), + _M_tolower(_M_c_locale_ctype->__ctype_tolower), + _M_table(__table ? __table : _M_c_locale_ctype->__ctype_b), + _M_widen_ok(0), _M_narrow_ok(0) + { + memset(_M_widen, 0, sizeof(_M_widen)); + memset(_M_narrow, 0, sizeof(_M_narrow)); + } +#else + ctype::ctype(const mask* __table, bool __del, size_t __refs) + : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), + _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0) + { + char* __old=strdup(setlocale(LC_CTYPE, NULL)); + setlocale(LC_CTYPE, "C"); +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) + _M_toupper = *__ctype_toupper_loc(); + _M_tolower = *__ctype_tolower_loc(); + _M_table = __table ? __table : *__ctype_b_loc(); +#else + _M_toupper = __ctype_toupper; + _M_tolower = __ctype_tolower; + _M_table = __table ? __table : __ctype_b; +#endif + setlocale(LC_CTYPE, __old); + free(__old); + memset(_M_widen, 0, sizeof(_M_widen)); + memset(_M_narrow, 0, sizeof(_M_narrow)); + } +#endif + + char + ctype::do_toupper(char __c) const + { return _M_toupper[static_cast(__c)]; } + + const char* + ctype::do_toupper(char* __low, const char* __high) const + { + while (__low < __high) + { + *__low = _M_toupper[static_cast(*__low)]; + ++__low; + } + return __high; + } + + char + ctype::do_tolower(char __c) const + { return _M_tolower[static_cast(__c)]; } + + const char* + ctype::do_tolower(char* __low, const char* __high) const + { + while (__low < __high) + { + *__low = _M_tolower[static_cast(*__low)]; + ++__low; + } + return __high; + } diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-default.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-default.h new file mode 100644 index 00000000000..1898d24dbda --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-default.h @@ -0,0 +1,517 @@ +/* Threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_POSIX_H +#define _GLIBCXX_GCC_GTHR_POSIX_H + +/* POSIX threads specific definitions. + Easy, since the interface is just one-to-one mapping. */ + +#define __GTHREADS 1 + +/* Some implementations of require this to be defined. */ +#ifndef _REENTRANT +#define _REENTRANT 1 +#endif + +#include +#include + +typedef pthread_key_t __gthread_key_t; +typedef pthread_once_t __gthread_once_t; +typedef pthread_mutex_t __gthread_mutex_t; + +#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT + +#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific +#pragma weak pthread_create + +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_trylock +#pragma weak pthread_mutex_unlock + +#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) +/* Objective-C. */ +#pragma weak pthread_cond_broadcast +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_init +#pragma weak pthread_cond_signal +#pragma weak pthread_cond_wait +#pragma weak pthread_exit +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_self +/* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but + we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block. */ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak sched_get_priority_max +#pragma weak sched_get_priority_min +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#pragma weak sched_yield +#pragma weak pthread_attr_destroy +#pragma weak pthread_attr_init +#pragma weak pthread_attr_setdetachstate +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak pthread_getschedparam +#pragma weak pthread_setschedparam +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#endif /* _LIBOBJC || _LIBOBJC_WEAK */ + +static inline int +__gthread_active_p (void) +{ + static void *const __gthread_active_ptr = (void *) &pthread_create; + return __gthread_active_ptr != 0; +} + +#else /* not __GXX_WEAK__ */ + +static inline int +__gthread_active_p (void) +{ + return 1; +} + +#endif /* __GXX_WEAK__ */ + +#ifdef _LIBOBJC + +/* This is the config.h file in libobjc/ */ +#include + +#ifdef HAVE_SCHED_H +# include +#endif + +/* Key structure for maintaining thread specific storage */ +static pthread_key_t _objc_thread_storage; +static pthread_attr_t _objc_thread_attribs; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system (void) +{ + if (__gthread_active_p ()) + { + /* Initialize the thread storage key */ + if (pthread_key_create (&_objc_thread_storage, NULL) == 0) + { + /* The normal default detach state for threads is + * PTHREAD_CREATE_JOINABLE which causes threads to not die + * when you think they should. */ + if (pthread_attr_init (&_objc_thread_attribs) == 0 + && pthread_attr_setdetachstate (&_objc_thread_attribs, + PTHREAD_CREATE_DETACHED) == 0) + return 0; + } + } + + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system (void) +{ + if (__gthread_active_p () + && pthread_key_delete (_objc_thread_storage) == 0 + && pthread_attr_destroy (&_objc_thread_attribs) == 0) + return 0; + + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach (void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + pthread_t new_thread_handle; + + if (!__gthread_active_p ()) + return NULL; + + if (!(pthread_create (&new_thread_handle, NULL, (void *) func, arg))) + thread_id = (objc_thread_t) new_thread_handle; + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority (int priority) +{ + if (!__gthread_active_p ()) + return -1; + else + { +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + pthread_t thread_id = pthread_self (); + int policy; + struct sched_param params; + int priority_min, priority_max; + + if (pthread_getschedparam (thread_id, &policy, ¶ms) == 0) + { + if ((priority_max = sched_get_priority_max (policy)) == -1) + return -1; + + if ((priority_min = sched_get_priority_min (policy)) == -1) + return -1; + + if (priority > priority_max) + priority = priority_max; + else if (priority < priority_min) + priority = priority_min; + params.sched_priority = priority; + + /* + * The solaris 7 and several other man pages incorrectly state that + * this should be a pointer to policy but pthread.h is universally + * at odds with this. + */ + if (pthread_setschedparam (thread_id, policy, ¶ms) == 0) + return 0; + } +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return -1; + } +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority (void) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + if (__gthread_active_p ()) + { + int policy; + struct sched_param params; + + if (pthread_getschedparam (pthread_self (), &policy, ¶ms) == 0) + return params.sched_priority; + else + return -1; + } + else +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield (void) +{ + if (__gthread_active_p ()) + sched_yield (); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit (void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + pthread_exit (&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id (void) +{ + if (__gthread_active_p ()) + return (objc_thread_t) pthread_self (); + else + return (objc_thread_t) 1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data (void *value) +{ + if (__gthread_active_p ()) + return pthread_setspecific (_objc_thread_storage, value); + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data (void) +{ + if (__gthread_active_p ()) + return pthread_getspecific (_objc_thread_storage); + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); + + if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL)) + { + objc_free (mutex->backend); + mutex->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + int count; + + /* + * Posix Threads specifically require that the thread be unlocked + * for pthread_mutex_destroy to work. + */ + + do + { + count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend); + if (count < 0) + return -1; + } + while (count); + + if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend)) + return -1; + + objc_free (mutex->backend); + mutex->backend = NULL; + } + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + condition->backend = objc_malloc (sizeof (pthread_cond_t)); + + if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL)) + { + objc_free (condition->backend); + condition->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + if (pthread_cond_destroy ((pthread_cond_t *) condition->backend)) + return -1; + + objc_free (condition->backend); + condition->backend = NULL; + } + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_cond_wait ((pthread_cond_t *) condition->backend, + (pthread_mutex_t *) mutex->backend); + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_broadcast ((pthread_cond_t *) condition->backend); + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_signal ((pthread_cond_t *) condition->backend); + else + return 0; +} + +#else /* _LIBOBJC */ + +static inline int +__gthread_once (__gthread_once_t *once, void (*func) (void)) +{ + if (__gthread_active_p ()) + return pthread_once (once, func); + else + return -1; +} + +static inline int +__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) +{ + return pthread_key_create (key, dtor); +} + +static inline int +__gthread_key_delete (__gthread_key_t key) +{ + return pthread_key_delete (key); +} + +static inline void * +__gthread_getspecific (__gthread_key_t key) +{ + return pthread_getspecific (key); +} + +static inline int +__gthread_setspecific (__gthread_key_t key, const void *ptr) +{ + return pthread_setspecific (key, ptr); +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_lock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_trylock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_unlock (mutex); + else + return 0; +} + +#endif /* _LIBOBJC */ + +#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-posix.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-posix.h new file mode 100644 index 00000000000..1898d24dbda --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-posix.h @@ -0,0 +1,517 @@ +/* Threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_POSIX_H +#define _GLIBCXX_GCC_GTHR_POSIX_H + +/* POSIX threads specific definitions. + Easy, since the interface is just one-to-one mapping. */ + +#define __GTHREADS 1 + +/* Some implementations of require this to be defined. */ +#ifndef _REENTRANT +#define _REENTRANT 1 +#endif + +#include +#include + +typedef pthread_key_t __gthread_key_t; +typedef pthread_once_t __gthread_once_t; +typedef pthread_mutex_t __gthread_mutex_t; + +#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT + +#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK + +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific +#pragma weak pthread_create + +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_trylock +#pragma weak pthread_mutex_unlock + +#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) +/* Objective-C. */ +#pragma weak pthread_cond_broadcast +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_init +#pragma weak pthread_cond_signal +#pragma weak pthread_cond_wait +#pragma weak pthread_exit +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_self +/* These really should be protected by _POSIX_PRIORITY_SCHEDULING, but + we use them inside a _POSIX_THREAD_PRIORITY_SCHEDULING block. */ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak sched_get_priority_max +#pragma weak sched_get_priority_min +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#pragma weak sched_yield +#pragma weak pthread_attr_destroy +#pragma weak pthread_attr_init +#pragma weak pthread_attr_setdetachstate +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#pragma weak pthread_getschedparam +#pragma weak pthread_setschedparam +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +#endif /* _LIBOBJC || _LIBOBJC_WEAK */ + +static inline int +__gthread_active_p (void) +{ + static void *const __gthread_active_ptr = (void *) &pthread_create; + return __gthread_active_ptr != 0; +} + +#else /* not __GXX_WEAK__ */ + +static inline int +__gthread_active_p (void) +{ + return 1; +} + +#endif /* __GXX_WEAK__ */ + +#ifdef _LIBOBJC + +/* This is the config.h file in libobjc/ */ +#include + +#ifdef HAVE_SCHED_H +# include +#endif + +/* Key structure for maintaining thread specific storage */ +static pthread_key_t _objc_thread_storage; +static pthread_attr_t _objc_thread_attribs; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system (void) +{ + if (__gthread_active_p ()) + { + /* Initialize the thread storage key */ + if (pthread_key_create (&_objc_thread_storage, NULL) == 0) + { + /* The normal default detach state for threads is + * PTHREAD_CREATE_JOINABLE which causes threads to not die + * when you think they should. */ + if (pthread_attr_init (&_objc_thread_attribs) == 0 + && pthread_attr_setdetachstate (&_objc_thread_attribs, + PTHREAD_CREATE_DETACHED) == 0) + return 0; + } + } + + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system (void) +{ + if (__gthread_active_p () + && pthread_key_delete (_objc_thread_storage) == 0 + && pthread_attr_destroy (&_objc_thread_attribs) == 0) + return 0; + + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach (void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + pthread_t new_thread_handle; + + if (!__gthread_active_p ()) + return NULL; + + if (!(pthread_create (&new_thread_handle, NULL, (void *) func, arg))) + thread_id = (objc_thread_t) new_thread_handle; + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority (int priority) +{ + if (!__gthread_active_p ()) + return -1; + else + { +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + pthread_t thread_id = pthread_self (); + int policy; + struct sched_param params; + int priority_min, priority_max; + + if (pthread_getschedparam (thread_id, &policy, ¶ms) == 0) + { + if ((priority_max = sched_get_priority_max (policy)) == -1) + return -1; + + if ((priority_min = sched_get_priority_min (policy)) == -1) + return -1; + + if (priority > priority_max) + priority = priority_max; + else if (priority < priority_min) + priority = priority_min; + params.sched_priority = priority; + + /* + * The solaris 7 and several other man pages incorrectly state that + * this should be a pointer to policy but pthread.h is universally + * at odds with this. + */ + if (pthread_setschedparam (thread_id, policy, ¶ms) == 0) + return 0; + } +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return -1; + } +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority (void) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + if (__gthread_active_p ()) + { + int policy; + struct sched_param params; + + if (pthread_getschedparam (pthread_self (), &policy, ¶ms) == 0) + return params.sched_priority; + else + return -1; + } + else +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield (void) +{ + if (__gthread_active_p ()) + sched_yield (); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit (void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + pthread_exit (&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id (void) +{ + if (__gthread_active_p ()) + return (objc_thread_t) pthread_self (); + else + return (objc_thread_t) 1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data (void *value) +{ + if (__gthread_active_p ()) + return pthread_setspecific (_objc_thread_storage, value); + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data (void) +{ + if (__gthread_active_p ()) + return pthread_getspecific (_objc_thread_storage); + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); + + if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL)) + { + objc_free (mutex->backend); + mutex->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate (objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + int count; + + /* + * Posix Threads specifically require that the thread be unlocked + * for pthread_mutex_destroy to work. + */ + + do + { + count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend); + if (count < 0) + return -1; + } + while (count); + + if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend)) + return -1; + + objc_free (mutex->backend); + mutex->backend = NULL; + } + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock (objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0) + { + return -1; + } + + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + condition->backend = objc_malloc (sizeof (pthread_cond_t)); + + if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL)) + { + objc_free (condition->backend); + condition->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate (objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + if (pthread_cond_destroy ((pthread_cond_t *) condition->backend)) + return -1; + + objc_free (condition->backend); + condition->backend = NULL; + } + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_cond_wait ((pthread_cond_t *) condition->backend, + (pthread_mutex_t *) mutex->backend); + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_broadcast ((pthread_cond_t *) condition->backend); + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal (objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_signal ((pthread_cond_t *) condition->backend); + else + return 0; +} + +#else /* _LIBOBJC */ + +static inline int +__gthread_once (__gthread_once_t *once, void (*func) (void)) +{ + if (__gthread_active_p ()) + return pthread_once (once, func); + else + return -1; +} + +static inline int +__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) +{ + return pthread_key_create (key, dtor); +} + +static inline int +__gthread_key_delete (__gthread_key_t key) +{ + return pthread_key_delete (key); +} + +static inline void * +__gthread_getspecific (__gthread_key_t key) +{ + return pthread_getspecific (key); +} + +static inline int +__gthread_setspecific (__gthread_key_t key, const void *ptr) +{ + return pthread_setspecific (key, ptr); +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_lock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_trylock (mutex); + else + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t *mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_unlock (mutex); + else + return 0; +} + +#endif /* _LIBOBJC */ + +#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-single.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-single.h new file mode 100644 index 00000000000..68e425b21e2 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr-single.h @@ -0,0 +1,239 @@ +/* Threads compatibility routines for libgcc2 and libobjc. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_SINGLE_H +#define _GLIBCXX_GCC_GTHR_SINGLE_H + +/* Just provide compatibility for mutex handling. */ + +typedef int __gthread_mutex_t; + +#define __GTHREAD_MUTEX_INIT 0 + +#ifdef __cplusplus +#define _GLIBCXX_UNUSED(x) +#else +#define _GLIBCXX_UNUSED(x) x __attribute__((unused)) +#endif + +#ifdef _LIBOBJC + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system (void) +{ + /* No thread support available */ + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system (void) +{ + /* No thread support available */ + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach (void (* func)(void *), void * _GLIBCXX_UNUSED(arg)) +{ + /* No thread support available */ + return NULL; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority (int _GLIBCXX_UNUSED(priority)) +{ + /* No thread support available */ + return -1; +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority (void) +{ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield (void) +{ + return; +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit (void) +{ + /* No thread support available */ + /* Should we really exit the program */ + /* exit (&__objc_thread_exit_status); */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id (void) +{ + /* No thread support, use 1. */ + return (objc_thread_t) 1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data (void *value) +{ + thread_local_storage = value; + return 0; +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data (void) +{ + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock (objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait (objc_condition_t _GLIBCXX_UNUSED(condition), + objc_mutex_t _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal (objc_condition_t _GLIBCXX_UNUSED(condition)) +{ + return 0; +} + +#else /* _LIBOBJC */ + +static inline int +__gthread_active_p (void) +{ + return 0; +} + +static inline int +__gthread_mutex_lock (__gthread_mutex_t * _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +static inline int +__gthread_mutex_trylock (__gthread_mutex_t * _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +static inline int +__gthread_mutex_unlock (__gthread_mutex_t * _GLIBCXX_UNUSED(mutex)) +{ + return 0; +} + +#endif /* _LIBOBJC */ + +#undef _GLIBCXX_UNUSED + +#endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr.h new file mode 100644 index 00000000000..fe5740c1ca0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/gthr.h @@ -0,0 +1,103 @@ +/* Threads compatibility routines for libgcc2. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +#ifndef _GLIBCXX_GCC_GTHR_H +#define _GLIBCXX_GCC_GTHR_H + +/* If this file is compiled with threads support, it must + #define __GTHREADS 1 + to indicate that threads support is present. Also it has define + function + int __gthread_active_p () + that returns 1 if thread system is active, 0 if not. + + The threads interface must define the following types: + __gthread_key_t + __gthread_once_t + __gthread_mutex_t + + The threads interface must define the following macros: + + __GTHREAD_ONCE_INIT + to initialize __gthread_once_t + __GTHREAD_MUTEX_INIT + to initialize __gthread_mutex_t to get a fast + non-recursive mutex. + __GTHREAD_MUTEX_INIT_FUNCTION + some systems can't initialize a mutex without a + function call. On such systems, define this to a + function which looks like this: + void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *) + Don't define __GTHREAD_MUTEX_INIT in this case + + The threads interface must define the following static functions: + + int __gthread_once (__gthread_once_t *once, void (*func) ()) + + int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *)) + int __gthread_key_delete (__gthread_key_t key) + + void *__gthread_getspecific (__gthread_key_t key) + int __gthread_setspecific (__gthread_key_t key, const void *ptr) + + int __gthread_mutex_lock (__gthread_mutex_t *mutex); + int __gthread_mutex_trylock (__gthread_mutex_t *mutex); + int __gthread_mutex_unlock (__gthread_mutex_t *mutex); + + All functions returning int should return zero on success or the error + number. If the operation is not supported, -1 is returned. + + Currently supported threads packages are + POSIX threads with -D_PTHREADS + DCE threads with -D_DCE_THREADS + Solaris/UI threads with -D_SOLARIS_THREADS +*/ + +/* Check first for thread specific defines. */ +#if _GLIBCXX__PTHREADS +#include +#elif _GLIBCXX__DCE_THREADS +#include +#elif _GLIBCXX__SOLARIS_THREADS +#include + +/* Include GTHREAD_FILE if one is defined. */ +#elif defined(_GLIBCXX_HAVE_GTHR_DEFAULT) +#if __GXX_WEAK__ +#ifndef _GLIBCXX_GTHREAD_USE_WEAK +#define _GLIBCXX_GTHREAD_USE_WEAK 1 +#endif +#endif +#include + +/* Fallback to single thread definitions. */ +#else +#include +#endif + +#endif /* ! _GLIBCXX_GCC_GTHR_H */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/messages_members.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/messages_members.h new file mode 100644 index 00000000000..a7cd1cd02de --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/messages_members.h @@ -0,0 +1,104 @@ +// std::messages implementation details, GNU version -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.7.1.2 messages functions +// + +// Written by Benjamin Kosnik + + // Non-virtual member functions. + template + messages<_CharT>::messages(size_t __refs) + : facet(__refs), _M_c_locale_messages(_S_get_c_locale()), + _M_name_messages(_S_get_c_name()) + { } + + template + messages<_CharT>::messages(__c_locale __cloc, const char* __s, + size_t __refs) + : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)), + _M_name_messages(__s) + { + char* __tmp = new char[std::strlen(__s) + 1]; + std::strcpy(__tmp, __s); + _M_name_messages = __tmp; + } + + template + typename messages<_CharT>::catalog + messages<_CharT>::open(const basic_string& __s, const locale& __loc, + const char* __dir) const + { + bindtextdomain(__s.c_str(), __dir); + return this->do_open(__s, __loc); + } + + // Virtual member functions. + template + messages<_CharT>::~messages() + { + if (_M_name_messages != _S_get_c_name()) + delete [] _M_name_messages; + _S_destroy_c_locale(_M_c_locale_messages); + } + + template + typename messages<_CharT>::catalog + messages<_CharT>::do_open(const basic_string& __s, + const locale&) const + { + // No error checking is done, assume the catalog exists and can + // be used. + textdomain(__s.c_str()); + return 0; + } + + template + void + messages<_CharT>::do_close(catalog) const + { } + + // messages_byname + template + messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs) + : messages<_CharT>(__refs) + { + if (this->_M_name_messages != locale::facet::_S_get_c_name()) + delete [] this->_M_name_messages; + char* __tmp = new char[std::strlen(__s) + 1]; + std::strcpy(__tmp, __s); + this->_M_name_messages = __tmp; + + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_messages); + this->_S_create_c_locale(this->_M_c_locale_messages, __s); + } + } diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/os_defines.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/os_defines.h new file mode 100644 index 00000000000..0e0194aea75 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/os_defines.h @@ -0,0 +1,46 @@ +// Specific definitions for GNU/Linux -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_OS_DEFINES +#define _GLIBCXX_OS_DEFINES 1 + +// System-specific #define, typedefs, corrections, etc, go here. This +// file will come before all others. + +// This keeps isanum, et al from being propagated as macros. +#define __NO_CTYPE 1 + +#include + +// We must not see the optimized string functions GNU libc defines. +#if defined __GLIBC__ && __GLIBC__ >= 2 +#define __NO_STRING_INLINES +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/time_members.h b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/time_members.h new file mode 100644 index 00000000000..9cb3594ca07 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/powerpc-unknown-linux-gnu/bits/time_members.h @@ -0,0 +1,68 @@ +// std::time_get, std::time_put implementation, GNU version -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.5.1.2 - time_get functions +// ISO C++ 14882: 22.2.5.3.2 - time_put functions +// + +// Written by Benjamin Kosnik + + template + __timepunct<_CharT>::__timepunct(size_t __refs) + : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), + _M_name_timepunct(_S_get_c_name()) + { _M_initialize_timepunct(); } + + template + __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) + : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(NULL), + _M_name_timepunct(_S_get_c_name()) + { _M_initialize_timepunct(); } + + template + __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s, + size_t __refs) + : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), + _M_name_timepunct(__s) + { + char* __tmp = new char[std::strlen(__s) + 1]; + std::strcpy(__tmp, __s); + _M_name_timepunct = __tmp; + _M_initialize_timepunct(__cloc); + } + + template + __timepunct<_CharT>::~__timepunct() + { + if (_M_name_timepunct != _S_get_c_name()) + delete [] _M_name_timepunct; + delete _M_data; + _S_destroy_c_locale(_M_c_locale_timepunct); + } diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/queue b/reactos/tools/ppc-build/core-headers/g++-v3/queue new file mode 100644 index 00000000000..9a6523bef87 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/queue @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file queue + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_QUEUE +#define _GLIBCXX_QUEUE 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* _GLIBCXX_QUEUE */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/set b/reactos/tools/ppc-build/core-headers/g++-v3/set new file mode 100644 index 00000000000..7ef8c9fef3b --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/set @@ -0,0 +1,74 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file set + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_SET +#define _GLIBCXX_SET 1 + +#pragma GCC system_header + +#include +#include +#include + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_SET */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/sstream b/reactos/tools/ppc-build/core-headers/g++-v3/sstream new file mode 100644 index 00000000000..0a6738adf8a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/sstream @@ -0,0 +1,643 @@ +// String based streams -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.7 String-based streams +// + +/** @file sstream + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_SSTREAM +#define _GLIBCXX_SSTREAM 1 + +#pragma GCC system_header + +#include +#include + +namespace std +{ + // [27.7.1] template class basic_stringbuf + /** + * @brief The actual work of input and output (for std::string). + * + * This class associates either or both of its input and output sequences + * with a sequence of characters, which can be initialized from, or made + * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) + * + * For this class, open modes (of type @c ios_base::openmode) have + * @c in set if the input sequence can be read, and @c out set if the + * output sequence can be written. + */ + template + class basic_stringbuf : public basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + //@{ + /** + * @if maint + * @doctodo + * @endif + */ + typedef basic_streambuf __streambuf_type; + typedef basic_string __string_type; + typedef typename __string_type::size_type __size_type; + //@} + + protected: + /** + * @if maint + * Place to stash in || out || in | out settings for current stringbuf. + * @endif + */ + ios_base::openmode _M_mode; + + // Data Members: + /** + * @if maint + * @doctodo + * @endif + */ + __string_type _M_string; + + public: + // Constructors: + /** + * @brief Starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * The default constructor initializes the parent class using its + * own default ctor. + */ + explicit + basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) + : __streambuf_type(), _M_mode(__mode), _M_string() + { } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * This constructor initializes the parent class using its + * own default ctor. + */ + explicit + basic_stringbuf(const __string_type& __str, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) + { _M_stringbuf_init(__mode); } + + // Get and set: + /** + * @brief Copying out the string buffer. + * @return A copy of one of the underlying sequences. + * + * "If the buffer is only created in input mode, the underlying + * character sequence is equal to the input sequence; otherwise, it + * is equal to the output sequence." [27.7.1.2]/1 + */ + __string_type + str() const + { + if (this->pptr()) + { + // The current egptr() may not be the actual string end. + if (this->pptr() > this->egptr()) + return __string_type(this->pbase(), this->pptr()); + else + return __string_type(this->pbase(), this->egptr()); + } + else + return _M_string; + } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Deallocates any previous stored sequence, then copies @a s to + * use as a new one. + */ + void + str(const __string_type& __s) + { + // Cannot use _M_string = __s, since v3 strings are COW. + _M_string.assign(__s.data(), __s.size()); + _M_stringbuf_init(this->_M_mode); + } + + protected: + // Common initialization code goes here. + /** + * @if maint + * @doctodo + * @endif + */ + void + _M_stringbuf_init(ios_base::openmode __mode) + { + this->_M_mode = __mode; + + __size_type __len = 0; + if (this->_M_mode & (ios_base::ate | ios_base::app)) + __len = _M_string.size(); + _M_sync(const_cast(_M_string.data()), 0, __len); + } + + // [documentation is inherited] + virtual int_type + underflow(); + + // [documentation is inherited] + virtual int_type + pbackfail(int_type __c = traits_type::eof()); + + // [documentation is inherited] + virtual int_type + overflow(int_type __c = traits_type::eof()); + + /** + * @brief Manipulates the buffer. + * @param s Pointer to a buffer area. + * @param n Size of @a s. + * @return @c this + * + * If no buffer has already been created, and both @a s and @a n are + * non-zero, then @c s is used as a buffer; see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 + * for more. + */ + virtual __streambuf_type* + setbuf(char_type* __s, streamsize __n) + { + if (__s && __n >= 0) + { + // This is implementation-defined behavior, and assumes + // that an external char_type array of length __n exists + // and has been pre-allocated. If this is not the case, + // things will quickly blow up. + + // Step 1: Destroy the current internal array. + _M_string = __string_type(__s, __n); + + // Step 2: Use the external array. + _M_sync(__s, 0, 0); + } + return this; + } + + // [documentation is inherited] + virtual pos_type + seekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // [documentation is inherited] + virtual pos_type + seekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out); + + // Internal function for correctly updating the internal buffer + // for a particular _M_string, due to initialization or + // re-sizing of an existing _M_string. + // Assumes: contents of _M_string and internal buffer match exactly. + // __i == _M_in_cur - _M_in_beg + // __o == _M_out_cur - _M_out_beg + /** + * @if maint + * @doctodo + * @endif + */ + void + _M_sync(char_type* __base, __size_type __i, __size_type __o) + { + const bool __testin = this->_M_mode & ios_base::in; + const bool __testout = this->_M_mode & ios_base::out; + const __size_type __len = _M_string.size(); + + if (__testin) + this->setg(__base, __base + __i, __base + __len); + if (__testout) + { + this->setp(__base, __base + _M_string.capacity()); + this->pbump(__o); + // We need a pointer to the string end anyway, even when + // !__testin: in that case, however, for the correct + // functioning of the streambuf inlines all the get area + // pointers must be identical. + if (!__testin) + this->setg(__base + __len, __base + __len, __base + __len); + } + } + + // Internal function for correctly updating egptr() to the actual + // string end. + void + _M_update_egptr() + { + const bool __testin = this->_M_mode & ios_base::in; + + if (this->pptr() && this->pptr() > this->egptr()) + if (__testin) + this->setg(this->eback(), this->gptr(), this->pptr()); + else + this->setg(this->pptr(), this->pptr(), this->pptr()); + } + }; + + + // [27.7.2] Template class basic_istringstream + /** + * @brief Controlling input for std::string. + * + * This class supports reading from objects of type std::basic_string, + * using the inherited functions from std::basic_istream. To control + * the associated sequence, an instance of std::basic_stringbuf is used, + * which this page refers to as @c sb. + */ + template + class basic_istringstream : public basic_istream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_istream __istream_type; + + private: + /** + * @if maint + * @doctodo + * @endif + */ + __stringbuf_type _M_stringbuf; + + public: + // Constructors: + /** + * @brief Default constructor starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::in is automatically included in @a mode. + * + * Initializes @c sb using @c mode|in, and passes @c &sb to the base + * class initializer. Does not allocate any buffer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_istringstream(ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_stringbuf(__mode | ios_base::in) + { this->init(&_M_stringbuf); } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::in is automatically included in @a mode. + * + * Initializes @c sb using @a str and @c mode|in, and passes @c &sb + * to the base class initializer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_istringstream(const __string_type& __str, + ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) + { this->init(&_M_stringbuf); } + + /** + * @brief The destructor does nothing. + * + * The buffer is deallocated by the stringbuf object, not the + * formatting stream. + */ + ~basic_istringstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_stringbuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __stringbuf_type* + rdbuf() const + { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + + /** + * @brief Copying out the string buffer. + * @return @c rdbuf()->str() + */ + __string_type + str() const + { return _M_stringbuf.str(); } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Calls @c rdbuf()->str(s). + */ + void + str(const __string_type& __s) + { _M_stringbuf.str(__s); } + }; + + + // [27.7.3] Template class basic_ostringstream + /** + * @brief Controlling output for std::string. + * + * This class supports writing to objects of type std::basic_string, + * using the inherited functions from std::basic_ostream. To control + * the associated sequence, an instance of std::basic_stringbuf is used, + * which this page refers to as @c sb. + */ + template + class basic_ostringstream : public basic_ostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_ostream __ostream_type; + + private: + /** + * @if maint + * @doctodo + * @endif + */ + __stringbuf_type _M_stringbuf; + + public: + // Constructors/destructor: + /** + * @brief Default constructor starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::out is automatically included in @a mode. + * + * Initializes @c sb using @c mode|out, and passes @c &sb to the base + * class initializer. Does not allocate any buffer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_ostringstream(ios_base::openmode __mode = ios_base::out) + : __ostream_type(), _M_stringbuf(__mode | ios_base::out) + { this->init(&_M_stringbuf); } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * @c ios_base::out is automatically included in @a mode. + * + * Initializes @c sb using @a str and @c mode|out, and passes @c &sb + * to the base class initializer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_ostringstream(const __string_type& __str, + ios_base::openmode __mode = ios_base::out) + : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) + { this->init(&_M_stringbuf); } + + /** + * @brief The destructor does nothing. + * + * The buffer is deallocated by the stringbuf object, not the + * formatting stream. + */ + ~basic_ostringstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_stringbuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __stringbuf_type* + rdbuf() const + { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + + /** + * @brief Copying out the string buffer. + * @return @c rdbuf()->str() + */ + __string_type + str() const + { return _M_stringbuf.str(); } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Calls @c rdbuf()->str(s). + */ + void + str(const __string_type& __s) + { _M_stringbuf.str(__s); } + }; + + + // [27.7.4] Template class basic_stringstream + /** + * @brief Controlling input and output for std::string. + * + * This class supports reading from and writing to objects of type + * std::basic_string, using the inherited functions from + * std::basic_iostream. To control the associated sequence, an instance + * of std::basic_stringbuf is used, which this page refers to as @c sb. + */ + template + class basic_stringstream : public basic_iostream<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type + typedef _Alloc allocator_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + // Non-standard Types: + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; + typedef basic_iostream __iostream_type; + + private: + /** + * @if maint + * @doctodo + * @endif + */ + __stringbuf_type _M_stringbuf; + + public: + // Constructors/destructors + /** + * @brief Default constructor starts with an empty string buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * Initializes @c sb using @c mode, and passes @c &sb to the base + * class initializer. Does not allocate any buffer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) + : __iostream_type(), _M_stringbuf(__m) + { this->init(&_M_stringbuf); } + + /** + * @brief Starts with an existing string buffer. + * @param str A string to copy as a starting buffer. + * @param mode Whether the buffer can read, or write, or both. + * + * Initializes @c sb using @a str and @c mode, and passes @c &sb + * to the base class initializer. + * + * @if maint + * That's a lie. We initialize the base class with NULL, because the + * string class does its own memory management. + * @endif + */ + explicit + basic_stringstream(const __string_type& __str, + ios_base::openmode __m = ios_base::out | ios_base::in) + : __iostream_type(), _M_stringbuf(__str, __m) + { this->init(&_M_stringbuf); } + + /** + * @brief The destructor does nothing. + * + * The buffer is deallocated by the stringbuf object, not the + * formatting stream. + */ + ~basic_stringstream() + { } + + // Members: + /** + * @brief Accessing the underlying buffer. + * @return The current basic_stringbuf buffer. + * + * This hides both signatures of std::basic_ios::rdbuf(). + */ + __stringbuf_type* + rdbuf() const + { return const_cast<__stringbuf_type*>(&_M_stringbuf); } + + /** + * @brief Copying out the string buffer. + * @return @c rdbuf()->str() + */ + __string_type + str() const + { return _M_stringbuf.str(); } + + /** + * @brief Setting a new buffer. + * @param s The string to use as a new sequence. + * + * Calls @c rdbuf()->str(s). + */ + void + str(const __string_type& __s) + { _M_stringbuf.str(__s); } + }; +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif /* _GLIBCXX_SSTREAM */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/stack b/reactos/tools/ppc-build/core-headers/g++-v3/stack new file mode 100644 index 00000000000..70f045684e0 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/stack @@ -0,0 +1,73 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file stack + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_STACK +#define _GLIBCXX_STACK 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include + +#endif /* _GLIBCXX_STACK */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/stdexcept b/reactos/tools/ppc-build/core-headers/g++-v3/stdexcept new file mode 100644 index 00000000000..ebd97f50f88 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/stdexcept @@ -0,0 +1,148 @@ +// Standard exception classes -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 19.1 Exception classes +// + +/** @file stdexcept + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_STDEXCEPT +#define _GLIBCXX_STDEXCEPT 1 + +#pragma GCC system_header + +#include +#include + +namespace std +{ + /** Logic errors represent problems in the internal logic of a program; + * in theory, these are preventable, and even detectable before the + * program runs (e.g., violations of class invariants). + * @brief One of two subclasses of exception. + */ + class logic_error : public exception + { + string _M_msg; + + public: + /** Takes a character string describing the error. */ + explicit + logic_error(const string& __arg); + + virtual + ~logic_error() throw(); + + /** Returns a C-style character string describing the general cause of + * the current error (the same string passed to the ctor). */ + virtual const char* + what() const throw(); + }; + + /** Thrown by the library, or by you, to report domain errors (domain in + * the mathmatical sense). */ + class domain_error : public logic_error + { + public: + explicit domain_error(const string& __arg); + }; + + /** Thrown to report invalid arguments to functions. */ + class invalid_argument : public logic_error + { + public: + explicit invalid_argument(const string& __arg); + }; + + /** Thrown when an object is constructed that would exceed its maximum + * permitted size (e.g., a basic_string instance). */ + class length_error : public logic_error + { + public: + explicit length_error(const string& __arg); + }; + + /** This represents an argument whose value is not within the expected + * range (e.g., boundary checks in basic_string). */ + class out_of_range : public logic_error + { + public: + explicit out_of_range(const string& __arg); + }; + + /** Runtime errors represent problems outside the scope of a program; + * they cannot be easily predicted and can generally only be caught as + * the program executes. + * @brief One of two subclasses of exception. + */ + class runtime_error : public exception + { + string _M_msg; + + public: + /** Takes a character string describing the error. */ + explicit + runtime_error(const string& __arg); + + virtual + ~runtime_error() throw(); + + /** Returns a C-style character string describing the general cause of + * the current error (the same string passed to the ctor). */ + virtual const char* + what() const throw(); + }; + + /** Thrown to indicate range errors in internal computations. */ + class range_error : public runtime_error + { + public: + explicit range_error(const string& __arg); + }; + + /** Thrown to indicate arithmetic overflow. */ + class overflow_error : public runtime_error + { + public: + explicit overflow_error(const string& __arg); + }; + + /** Thrown to indicate arithmetic underflow. */ + class underflow_error : public runtime_error + { + public: + explicit underflow_error(const string& __arg); + }; +} // namespace std + +#endif /* _GLIBCXX_STDEXCEPT */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/streambuf b/reactos/tools/ppc-build/core-headers/g++-v3/streambuf new file mode 100644 index 00000000000..42b3d782b0f --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/streambuf @@ -0,0 +1,784 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +/** @file streambuf + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _CLIBXX_STREAMBUF +#define _CLIBXX_STREAMBUF 1 + +#pragma GCC system_header + +#include +#include +#include +#include + +namespace std +{ + /** + * @if maint + * Does stuff. + * @endif + */ + template + streamsize + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout); + + /** + * @brief The actual work of input and output (interface). + * + * This is a base class. Derived stream buffers each control a + * pair of character sequences: one for input, and one for output. + * + * Section [27.5.1] of the standard describes the requirements and + * behavior of stream buffer classes. That section (three paragraphs) + * is reproduced here, for simplicity and accuracy. + * + * -# Stream buffers can impose various constraints on the sequences + * they control. Some constraints are: + * - The controlled input sequence can be not readable. + * - The controlled output sequence can be not writable. + * - The controlled sequences can be associated with the contents of + * other representations for character sequences, such as external + * files. + * - The controlled sequences can support operations @e directly to or + * from associated sequences. + * - The controlled sequences can impose limitations on how the + * program can read characters from a sequence, write characters to + * a sequence, put characters back into an input sequence, or alter + * the stream position. + * . + * -# Each sequence is characterized by three pointers which, if non-null, + * all point into the same @c charT array object. The array object + * represents, at any moment, a (sub)sequence of characters from the + * sequence. Operations performed on a sequence alter the values + * stored in these pointers, perform reads and writes directly to or + * from associated sequences, and alter "the stream position" and + * conversion state as needed to maintain this subsequence relationship. + * The three pointers are: + * - the beginning pointer, or lowest element address in the + * array (called @e xbeg here); + * - the next pointer, or next element address that is a + * current candidate for reading or writing (called @e xnext here); + * - the end pointer, or first element address beyond the + * end of the array (called @e xend here). + * . + * -# The following semantic constraints shall always apply for any set + * of three pointers for a sequence, using the pointer names given + * immediately above: + * - If @e xnext is not a null pointer, then @e xbeg and @e xend shall + * also be non-null pointers into the same @c charT array, as + * described above; otherwise, @e xbeg and @e xend shall also be null. + * - If @e xnext is not a null pointer and @e xnext < @e xend for an + * output sequence, then a write position is available. + * In this case, @e *xnext shall be assignable as the next element + * to write (to put, or to store a character value, into the sequence). + * - If @e xnext is not a null pointer and @e xbeg < @e xnext for an + * input sequence, then a putback position is available. + * In this case, @e xnext[-1] shall have a defined value and is the + * next (preceding) element to store a character that is put back + * into the input sequence. + * - If @e xnext is not a null pointer and @e xnext< @e xend for an + * input sequence, then a read position is available. + * In this case, @e *xnext shall have a defined value and is the + * next element to read (to get, or to obtain a character value, + * from the sequence). + */ + template + class basic_streambuf + { + public: + //@{ + /** + * These are standard types. They permit a standardized way of + * referring to names of (or names dependant on) the template + * parameters, which are specific to the implementation. + */ + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + //@} + + //@{ + /** + * @if maint + * This is a non-standard type. + * @endif + */ + typedef basic_streambuf __streambuf_type; + //@} + + friend class basic_ios; + friend class basic_istream; + friend class basic_ostream; + friend class istreambuf_iterator; + friend class ostreambuf_iterator; + + friend streamsize + __copy_streambufs<>(__streambuf_type* __sbin, + __streambuf_type* __sbout); + + protected: + //@{ + /** + * @if maint + * This is based on _IO_FILE, just reordered to be more consistent, + * and is intended to be the most minimal abstraction for an + * internal buffer. + * - get == input == read + * - put == output == write + * @endif + */ + char_type* _M_in_beg; // Start of get area. + char_type* _M_in_cur; // Current read area. + char_type* _M_in_end; // End of get area. + char_type* _M_out_beg; // Start of put area. + char_type* _M_out_cur; // Current put area. + char_type* _M_out_end; // End of put area. + + /** + * @if maint + * Current locale setting. + * @endif + */ + locale _M_buf_locale; + + public: + /// Destructor deallocates no buffer space. + virtual + ~basic_streambuf() + { } + + // [27.5.2.2.1] locales + /** + * @brief Entry point for imbue(). + * @param loc The new locale. + * @return The previous locale. + * + * Calls the derived imbue(loc). + */ + locale + pubimbue(const locale &__loc) + { + locale __tmp(this->getloc()); + this->imbue(__loc); + _M_buf_locale = __loc; + return __tmp; + } + + /** + * @brief Locale access. + * @return The current locale in effect. + * + * If pubimbue(loc) has been called, then the most recent @c loc + * is returned. Otherwise the global locale in effect at the time + * of construction is returned. + */ + locale + getloc() const + { return _M_buf_locale; } + + // [27.5.2.2.2] buffer management and positioning + //@{ + /** + * @brief Entry points for derived buffer functions. + * + * The public versions of @c pubfoo dispatch to the protected + * derived @c foo member functions, passing the arguments (if any) + * and returning the result unchanged. + */ + __streambuf_type* + pubsetbuf(char_type* __s, streamsize __n) + { return this->setbuf(__s, __n); } + + pos_type + pubseekoff(off_type __off, ios_base::seekdir __way, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekoff(__off, __way, __mode); } + + pos_type + pubseekpos(pos_type __sp, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { return this->seekpos(__sp, __mode); } + + int + pubsync() { return this->sync(); } + //@} + + // [27.5.2.2.3] get area + /** + * @brief Looking ahead into the stream. + * @return The number of characters available. + * + * If a read position is available, returns the number of characters + * available for reading before the buffer must be refilled. + * Otherwise returns the derived @c showmanyc(). + */ + streamsize + in_avail() + { + const streamsize __ret = this->egptr() - this->gptr(); + return __ret ? __ret : this->showmanyc(); + } + + /** + * @brief Getting the next character. + * @return The next character, or eof. + * + * Calls @c sbumpc(), and if that function returns + * @c traits::eof(), so does this function. Otherwise, @c sgetc(). + */ + int_type + snextc() + { + int_type __ret = traits_type::eof(); + if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), + __ret), true)) + __ret = this->sgetc(); + return __ret; + } + + /** + * @brief Getting the next character. + * @return The next character, or eof. + * + * If the input read position is available, returns that character + * and increments the read pointer, otherwise calls and returns + * @c uflow(). + */ + int_type + sbumpc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + else + __ret = this->uflow(); + return __ret; + } + + /** + * @brief Getting the next character. + * @return The next character, or eof. + * + * If the input read position is available, returns that character, + * otherwise calls and returns @c underflow(). Does not move the + * read position after fetching the character. + */ + int_type + sgetc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + __ret = traits_type::to_int_type(*this->gptr()); + else + __ret = this->underflow(); + return __ret; + } + + /** + * @brief Entry point for xsgetn. + * @param s A buffer area. + * @param n A count. + * + * Returns xsgetn(s,n). The effect is to fill @a s[0] through + * @a s[n-1] with characters from the input sequence, if possible. + */ + streamsize + sgetn(char_type* __s, streamsize __n) + { return this->xsgetn(__s, __n); } + + // [27.5.2.2.4] putback + /** + * @brief Pushing characters back into the input stream. + * @param c The character to push back. + * @return The previous character, if possible. + * + * Similar to sungetc(), but @a c is pushed onto the stream instead + * of "the previous character". If successful, the next character + * fetched from the input stream will be @a c. + */ + int_type + sputbackc(char_type __c) + { + int_type __ret; + const bool __testpos = this->eback() < this->gptr(); + if (__builtin_expect(!__testpos || + !traits_type::eq(__c, this->gptr()[-1]), false)) + __ret = this->pbackfail(traits_type::to_int_type(__c)); + else + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } + + /** + * @brief Moving backwards in the input stream. + * @return The previous character, if possible. + * + * If a putback position is available, this function decrements the + * input pointer and returns that character. Otherwise, calls and + * returns pbackfail(). The effect is to "unget" the last character + * "gotten". + */ + int_type + sungetc() + { + int_type __ret; + if (__builtin_expect(this->eback() < this->gptr(), true)) + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + else + __ret = this->pbackfail(); + return __ret; + } + + // [27.5.2.2.5] put area + /** + * @brief Entry point for all single-character output functions. + * @param c A character to output. + * @return @a c, if possible. + * + * One of two public output functions. + * + * If a write position is available for the output sequence (i.e., + * the buffer is not full), stores @a c in that position, increments + * the position, and returns @c traits::to_int_type(c). If a write + * position is not available, returns @c overflow(c). + */ + int_type + sputc(char_type __c) + { + int_type __ret; + if (__builtin_expect(this->pptr() < this->epptr(), true)) + { + *this->pptr() = __c; + this->pbump(1); + __ret = traits_type::to_int_type(__c); + } + else + __ret = this->overflow(traits_type::to_int_type(__c)); + return __ret; + } + + /** + * @brief Entry point for all single-character output functions. + * @param s A buffer read area. + * @param n A count. + * + * One of two public output functions. + * + * + * Returns xsputn(s,n). The effect is to write @a s[0] through + * @a s[n-1] to the output sequence, if possible. + */ + streamsize + sputn(const char_type* __s, streamsize __n) + { return this->xsputn(__s, __n); } + + protected: + /** + * @brief Base constructor. + * + * Only called from derived constructors, and sets up all the + * buffer data to zero, including the pointers described in the + * basic_streambuf class description. Note that, as a result, + * - the class starts with no read nor write positions available, + * - this is not an error + */ + basic_streambuf() + : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), + _M_out_beg(0), _M_out_cur(0), _M_out_end(0), + _M_buf_locale(locale()) + { } + + // [27.5.2.3.1] get area access + //@{ + /** + * @brief Access to the get area. + * + * These functions are only available to other protected functions, + * including derived classes. + * + * - eback() returns the beginning pointer for the input sequence + * - gptr() returns the next pointer for the input sequence + * - egptr() returns the end pointer for the input sequence + */ + char_type* + eback() const { return _M_in_beg; } + + char_type* + gptr() const { return _M_in_cur; } + + char_type* + egptr() const { return _M_in_end; } + //@} + + /** + * @brief Moving the read position. + * @param n The delta by which to move. + * + * This just advances the read position without returning any data. + */ + void + gbump(int __n) { _M_in_cur += __n; } + + /** + * @brief Setting the three read area pointers. + * @param gbeg A pointer. + * @param gnext A pointer. + * @param gend A pointer. + * @post @a gbeg == @c eback(), @a gnext == @c gptr(), and + * @a gend == @c egptr() + */ + void + setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) + { + _M_in_beg = __gbeg; + _M_in_cur = __gnext; + _M_in_end = __gend; + } + + // [27.5.2.3.2] put area access + //@{ + /** + * @brief Access to the put area. + * + * These functions are only available to other protected functions, + * including derived classes. + * + * - pbase() returns the beginning pointer for the output sequence + * - pptr() returns the next pointer for the output sequence + * - epptr() returns the end pointer for the output sequence + */ + char_type* + pbase() const { return _M_out_beg; } + + char_type* + pptr() const { return _M_out_cur; } + + char_type* + epptr() const { return _M_out_end; } + //@} + + /** + * @brief Moving the write position. + * @param n The delta by which to move. + * + * This just advances the write position without returning any data. + */ + void + pbump(int __n) { _M_out_cur += __n; } + + /** + * @brief Setting the three write area pointers. + * @param pbeg A pointer. + * @param pend A pointer. + * @post @a pbeg == @c pbase(), @a pbeg == @c pptr(), and + * @a pend == @c epptr() + */ + void + setp(char_type* __pbeg, char_type* __pend) + { + _M_out_beg = _M_out_cur = __pbeg; + _M_out_end = __pend; + } + + // [27.5.2.4] virtual functions + // [27.5.2.4.1] locales + /** + * @brief Changes translations. + * @param loc A new locale. + * + * Translations done during I/O which depend on the current locale + * are changed by this call. The standard adds, "Between invocations + * of this function a class derived from streambuf can safely cache + * results of calls to locale functions and to members of facets + * so obtained." + * + * @note Base class version does nothing. + */ + virtual void + imbue(const locale&) + { } + + // [27.5.2.4.2] buffer management and positioning + /** + * @brief Maniuplates the buffer. + * + * Each derived class provides its own appropriate behavior. See + * the next-to-last paragraph of + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 for + * more on this function. + * + * @note Base class version does nothing, returns @c this. + */ + virtual basic_streambuf* + setbuf(char_type*, streamsize) + { return this; } + + /** + * @brief Alters the stream positions. + * + * Each derived class provides its own appropriate behavior. + * @note Base class version does nothing, returns a @c pos_type + * that represents an invalid stream position. + */ + virtual pos_type + seekoff(off_type, ios_base::seekdir, + ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } + + /** + * @brief Alters the stream positions. + * + * Each derived class provides its own appropriate behavior. + * @note Base class version does nothing, returns a @c pos_type + * that represents an invalid stream position. + */ + virtual pos_type + seekpos(pos_type, + ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) + { return pos_type(off_type(-1)); } + + /** + * @brief Synchronizes the buffer arrays with the controlled sequences. + * @return -1 on failure. + * + * Each derived class provides its own appropriate behavior, + * including the definition of "failure". + * @note Base class version does nothing, returns zero. + */ + virtual int + sync() { return 0; } + + // [27.5.2.4.3] get area + /** + * @brief Investigating the data available. + * @return An estimate of the number of characters available in the + * input sequence, or -1. + * + * "If it returns a positive value, then successive calls to + * @c underflow() will not return @c traits::eof() until at least that + * number of characters have been supplied. If @c showmanyc() + * returns -1, then calls to @c underflow() or @c uflow() will fail." + * [27.5.2.4.3]/1 + * + * @note Base class version does nothing, returns zero. + * @note The standard adds that "the intention is not only that the + * calls [to underflow or uflow] will not return @c eof() but + * that they will return "immediately". + * @note The standard adds that "the morphemes of @c showmanyc are + * "es-how-many-see", not "show-manic". + */ + virtual streamsize + showmanyc() { return 0; } + + /** + * @brief Multiple character extraction. + * @param s A buffer area. + * @param n Maximum number of characters to assign. + * @return The number of characters assigned. + * + * Fills @a s[0] through @a s[n-1] with characters from the input + * sequence, as if by @c sbumpc(). Stops when either @a n characters + * have been copied, or when @c traits::eof() would be copied. + * + * It is expected that derived classes provide a more efficient + * implementation by overriding this definition. + */ + virtual streamsize + xsgetn(char_type* __s, streamsize __n); + + /** + * @brief Fetches more data from the controlled sequence. + * @return The first character from the pending sequence. + * + * Informally, this function is called when the input buffer is + * exhausted (or does not exist, as buffering need not actually be + * done). If a buffer exists, it is "refilled". In either case, the + * next available character is returned, or @c traits::eof() to + * indicate a null pending sequence. + * + * For a formal definiton of the pending sequence, see a good text + * such as Langer & Kreft, or [27.5.2.4.3]/7-14. + * + * A functioning input streambuf can be created by overriding only + * this function (no buffer area will be used). For an example, see + * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#6 + * + * @note Base class version does nothing, returns eof(). + */ + virtual int_type + underflow() + { return traits_type::eof(); } + + /** + * @brief Fetches more data from the controlled sequence. + * @return The first character from the pending sequence. + * + * Informally, this function does the same thing as @c underflow(), + * and in fact is required to call that function. It also returns + * the new character, like @c underflow() does. However, this + * function also moves the read position forward by one. + */ + virtual int_type + uflow() + { + int_type __ret = traits_type::eof(); + const bool __testeof = traits_type::eq_int_type(this->underflow(), + __ret); + if (!__testeof) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + return __ret; + } + + // [27.5.2.4.4] putback + /** + * @brief Tries to back up the input sequence. + * @param c The character to be inserted back into the sequence. + * @return eof() on failure, "some other value" on success + * @post The constraints of @c gptr(), @c eback(), and @c pptr() + * are the same as for @c underflow(). + * + * @note Base class version does nothing, returns eof(). + */ + virtual int_type + pbackfail(int_type /* __c */ = traits_type::eof()) + { return traits_type::eof(); } + + // Put area: + /** + * @brief Multiple character insertion. + * @param s A buffer area. + * @param n Maximum number of characters to write. + * @return The number of characters written. + * + * Writes @a s[0] through @a s[n-1] to the output sequence, as if + * by @c sputc(). Stops when either @a n characters have been + * copied, or when @c sputc() would return @c traits::eof(). + * + * It is expected that derived classes provide a more efficient + * implementation by overriding this definition. + */ + virtual streamsize + xsputn(const char_type* __s, streamsize __n); + + /** + * @brief Consumes data from the buffer; writes to the + * controlled sequence. + * @param c An additional character to consume. + * @return eof() to indicate failure, something else (usually + * @a c, or not_eof()) + * + * Informally, this function is called when the output buffer is full + * (or does not exist, as buffering need not actually be done). If a + * buffer exists, it is "consumed", with "some effect" on the + * controlled sequence. (Typically, the buffer is written out to the + * sequence verbatim.) In either case, the character @a c is also + * written out, if @a c is not @c eof(). + * + * For a formal definiton of this function, see a good text + * such as Langer & Kreft, or [27.5.2.4.5]/3-7. + * + * A functioning output streambuf can be created by overriding only + * this function (no buffer area will be used). + * + * @note Base class version does nothing, returns eof(). + */ + virtual int_type + overflow(int_type /* __c */ = traits_type::eof()) + { return traits_type::eof(); } + +#ifdef _GLIBCXX_DEPRECATED + // Annex D.6 + public: + /** + * @brief Tosses a character. + * + * Advances the read pointer, ignoring the character that would have + * been read. + * + * See http://gcc.gnu.org/ml/libstdc++/2002-05/msg00168.html + * + * @note This function has been deprecated by the standard. You + * must define @c _GLIBCXX_DEPRECATED to make this visible; see + * c++config.h. + */ + void + stossc() + { + if (this->gptr() < this->egptr()) + this->gbump(1); + else + this->uflow(); + } +#endif + + private: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // Side effect of DR 50. + basic_streambuf(const __streambuf_type& __sb) + : _M_in_beg(__sb._M_in_beg), _M_in_cur(__sb._M_in_cur), + _M_in_end(__sb._M_in_end), _M_out_beg(__sb._M_out_beg), + _M_out_cur(__sb._M_out_cur), _M_out_end(__sb._M_out_cur), + _M_buf_locale(__sb._M_buf_locale) + { } + + __streambuf_type& + operator=(const __streambuf_type&) { return *this; }; + }; +} // namespace std + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#endif /* _GLIBCXX_STREAMBUF */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/string b/reactos/tools/ppc-build/core-headers/g++-v3/string new file mode 100644 index 00000000000..2b15658c768 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/string @@ -0,0 +1,60 @@ +// Components for manipulating sequences of characters -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 21 Strings library +// + +/** @file string + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_STRING +#define _GLIBCXX_STRING 1 + +#pragma GCC system_header + +#include +#include +#include +#include // For allocator. +#include +#include // For operators >>, <<, and getline decls. +#include +#include // For less +#include + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include // for find_if +# include +#endif + +#endif /* _GLIBCXX_STRING */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/typeinfo b/reactos/tools/ppc-build/core-headers/g++-v3/typeinfo new file mode 100644 index 00000000000..1396baa6fc2 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/typeinfo @@ -0,0 +1,156 @@ +// RTTI support for -*- C++ -*- +// Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002 +// Free Software Foundation +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file typeinfo + * This header provides RTTI support. + */ + +#ifndef _TYPEINFO +#define _TYPEINFO + +#include + +extern "C++" { + +namespace __cxxabiv1 +{ + class __class_type_info; +} // namespace __cxxabiv1 + +#if !__GXX_WEAK__ + // If weak symbols are not supported, typeinfo names are not merged. + #define __GXX_MERGED_TYPEINFO_NAMES 0 +#else + // On platforms that support weak symbols, typeinfo names are merged. + #define __GXX_MERGED_TYPEINFO_NAMES 1 +#endif + +namespace std +{ + /** + * @brief Part of RTTI. + * + * The @c type_info class describes type information generated by + * an implementation. + */ + class type_info + { + public: + /** Destructor. Being the first non-inline virtual function, this + * controls in which translation unit the vtable is emitted. The + * compiler makes use of that information to know where to emit + * the runtime-mandated type_info structures in the new-abi. */ + virtual ~type_info(); + + private: + /// Assigning type_info is not supported. Made private. + type_info& operator=(const type_info&); + type_info(const type_info&); + + protected: + const char *__name; + + protected: + explicit type_info(const char *__n): __name(__n) { } + + public: + // the public interface + /** Returns an @e implementation-defined byte string; this is not + * portable between compilers! */ + const char* name() const + { return __name; } + +#if !__GXX_MERGED_TYPEINFO_NAMES + bool before(const type_info& __arg) const; + // In old abi, or when weak symbols are not supported, there can + // be multiple instances of a type_info object for one + // type. Uniqueness must use the _name value, not object address. + bool operator==(const type_info& __arg) const; +#else + /** Returns true if @c *this precedes @c __arg in the implementation's + * collation order. */ + // In new abi we can rely on type_info's NTBS being unique, + // and therefore address comparisons are sufficient. + bool before(const type_info& __arg) const + { return __name < __arg.__name; } + bool operator==(const type_info& __arg) const + { return __name == __arg.__name; } +#endif + bool operator!=(const type_info& __arg) const + { return !operator==(__arg); } + + // the internal interface + public: + // return true if this is a pointer type of some kind + virtual bool __is_pointer_p() const; + // return true if this is a function type + virtual bool __is_function_p() const; + + // Try and catch a thrown type. Store an adjusted pointer to the + // caught type in THR_OBJ. If THR_TYPE is not a pointer type, then + // THR_OBJ points to the thrown object. If THR_TYPE is a pointer + // type, then THR_OBJ is the pointer itself. OUTER indicates the + // number of outer pointers, and whether they were const + // qualified. + virtual bool __do_catch(const type_info *__thr_type, void **__thr_obj, + unsigned __outer) const; + + // internally used during catch matching + virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target, + void **__obj_ptr) const; + }; + + /** + * @brief Thrown during incorrect typecasting. + * + * If you attempt an invalid @c dynamic_cast expression, an instance of + * this class (or something derived from this class) is thrown. */ + class bad_cast : public exception + { + public: + bad_cast() throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_cast() throw(); + }; + + /** If you use a NULL pointer in a @c typeid expression, this is thrown. */ + class bad_typeid : public exception + { + public: + bad_typeid () throw() { } + // This declaration is not useless: + // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 + virtual ~bad_typeid() throw(); + }; +} // namespace std + +} // extern "C++" +#endif diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/utility b/reactos/tools/ppc-build/core-headers/g++-v3/utility new file mode 100644 index 00000000000..fe93090f939 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/utility @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file utility + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_UTILITY +#define _GLIBCXX_UTILITY 1 + +#pragma GCC system_header + +#include +#include +#include + +#endif /* _GLIBCXX_UTILITY */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/valarray b/reactos/tools/ppc-build/core-headers/g++-v3/valarray new file mode 100644 index 00000000000..b893b335415 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/valarray @@ -0,0 +1,1017 @@ +// The template and inlines for the -*- C++ -*- valarray class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +/** @file valarray + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_VALARRAY +#define _GLIBCXX_VALARRAY 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include +#include + +namespace std +{ + template + class _Expr; + + template + class _ValArray; + + template class _Meta, class _Dom> + struct _UnClos; + + template class _Meta1, + template class _Meta2, + class _Dom1, class _Dom2> + class _BinClos; + + template class _Meta, class _Dom> + class _SClos; + + template class _Meta, class _Dom> + class _GClos; + + template class _Meta, class _Dom> + class _IClos; + + template class _Meta, class _Dom> + class _ValFunClos; + + template class _Meta, class _Dom> + class _RefFunClos; + + template class valarray; // An array of type _Tp + class slice; // BLAS-like slice out of an array + template class slice_array; + class gslice; // generalized slice out of an array + template class gslice_array; + template class mask_array; // masked array + template class indirect_array; // indirected array + +} // namespace std + +#include +#include + +namespace std +{ + /** + * @brief Smart array designed to support numeric processing. + * + * A valarray is an array that provides constraints intended to allow for + * effective optimization of numeric array processing by reducing the + * aliasing that can result from pointer representations. It represents a + * one-dimensional array from which different multidimensional subsets can + * be accessed and modified. + * + * @param Tp Type of object in the array. + */ + template + class valarray + { + template + struct _UnaryOp + { + typedef typename __fun<_Op, _Tp>::result_type __rt; + typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; + }; + public: + typedef _Tp value_type; + + // _lib.valarray.cons_ construct/destroy: + /// Construct an empty array. + valarray(); + + /// Construct an array with @a n elements. + explicit valarray(size_t); + + /// Construct an array with @a n elements initialized to @a t. + valarray(const _Tp&, size_t); + + /// Construct an array initialized to the first @a n elements of @a t. + valarray(const _Tp* __restrict__, size_t); + + /// Copy constructor. + valarray(const valarray&); + + /// Construct an array with the same size and values in @a sa. + valarray(const slice_array<_Tp>&); + + /// Construct an array with the same size and values in @a ga. + valarray(const gslice_array<_Tp>&); + + /// Construct an array with the same size and values in @a ma. + valarray(const mask_array<_Tp>&); + + /// Construct an array with the same size and values in @a ia. + valarray(const indirect_array<_Tp>&); + + template + valarray(const _Expr<_Dom,_Tp>& __e); + ~valarray(); + + // _lib.valarray.assign_ assignment: + /** + * @brief Assign elements to an array. + * + * Assign elements of array to values in @a v. Results are undefined + * if @a v is not the same size as this array. + * + * @param v Valarray to get values from. + */ + valarray<_Tp>& operator=(const valarray<_Tp>&); + + /** + * @brief Assign elements to a value. + * + * Assign all elements of array to @a t. + * + * @param t Value for elements. + */ + valarray<_Tp>& operator=(const _Tp&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a sa. Results are undefined + * if @a sa is not the same size as this array. + * + * @param sa Array slice to get values from. + */ + valarray<_Tp>& operator=(const slice_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ga. Results are undefined + * if @a ga is not the same size as this array. + * + * @param ga Array slice to get values from. + */ + valarray<_Tp>& operator=(const gslice_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ma. Results are undefined + * if @a ma is not the same size as this array. + * + * @param ma Array slice to get values from. + */ + valarray<_Tp>& operator=(const mask_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ia. Results are undefined + * if @a ia is not the same size as this array. + * + * @param ia Array slice to get values from. + */ + valarray<_Tp>& operator=(const indirect_array<_Tp>&); + + template valarray<_Tp>& + operator= (const _Expr<_Dom,_Tp>&); + + // _lib.valarray.access_ element access: + /** + * Return a reference to the i'th array element. + * + * @param i Index of element to return. + * @return Reference to the i'th element. + */ + _Tp& operator[](size_t); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 389. Const overload of valarray::operator[] returns by value. + const _Tp& operator[](size_t) const; + + // _lib.valarray.sub_ subset operations: + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the slice argument. The new valarray is the size of + * the input slice. @see slice. + * + * @param s The source slice. + * @return New valarray containing elements in @a s. + */ + _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the slice argument. The new valarray is the size of + * the input slice. @see slice. + * + * @param s The source slice. + * @return New valarray containing elements in @a s. + */ + slice_array<_Tp> operator[](slice); + + /** + * @brief Return an array subset. + * + * Returns a slice_array referencing the elements of the array + * indicated by the slice argument. @see gslice. + * + * @param s The source slice. + * @return Slice_array referencing elements indicated by @a s. + */ + _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the gslice argument. The new valarray is + * the size of the input gslice. @see gslice. + * + * @param s The source gslice. + * @return New valarray containing elements in @a s. + */ + gslice_array<_Tp> operator[](const gslice&); + + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the argument. The input is a valarray of bool which + * represents a bitmask indicating which elements should be copied into + * the new valarray. Each element of the array is added to the return + * valarray if the corresponding element of the argument is true. + * + * @param m The valarray bitmask. + * @return New valarray containing elements indicated by @a m. + */ + valarray<_Tp> operator[](const valarray&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new mask_array referencing the elements of the array + * indicated by the argument. The input is a valarray of bool which + * represents a bitmask indicating which elements are part of the + * subset. Elements of the array are part of the subset if the + * corresponding element of the argument is true. + * + * @param m The valarray bitmask. + * @return New valarray containing elements indicated by @a m. + */ + mask_array<_Tp> operator[](const valarray&); + + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the argument. The elements in the argument are + * interpreted as the indices of elements of this valarray to copy to + * the return valarray. + * + * @param i The valarray element index list. + * @return New valarray containing elements in @a s. + */ + _Expr<_IClos<_ValArray, _Tp>, _Tp> + operator[](const valarray&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns an indirect_array referencing the elements of the array + * indicated by the argument. The elements in the argument are + * interpreted as the indices of elements of this valarray to include + * in the subset. The returned indirect_array refers to these + * elements. + * + * @param i The valarray element index list. + * @return Indirect_array referencing elements in @a i. + */ + indirect_array<_Tp> operator[](const valarray&); + + // _lib.valarray.unary_ unary operators: + /// Return a new valarray by applying unary + to each element. + typename _UnaryOp<__unary_plus>::_Rt operator+() const; + + /// Return a new valarray by applying unary - to each element. + typename _UnaryOp<__negate>::_Rt operator-() const; + + /// Return a new valarray by applying unary ~ to each element. + typename _UnaryOp<__bitwise_not>::_Rt operator~() const; + + /// Return a new valarray by applying unary ! to each element. + typename _UnaryOp<__logical_not>::_Rt operator!() const; + + // _lib.valarray.cassign_ computed assignment: + /// Multiply each element of array by @a t. + valarray<_Tp>& operator*=(const _Tp&); + + /// Divide each element of array by @a t. + valarray<_Tp>& operator/=(const _Tp&); + + /// Set each element e of array to e % @a t. + valarray<_Tp>& operator%=(const _Tp&); + + /// Add @a t to each element of array. + valarray<_Tp>& operator+=(const _Tp&); + + /// Subtract @a t to each element of array. + valarray<_Tp>& operator-=(const _Tp&); + + /// Set each element e of array to e ^ @a t. + valarray<_Tp>& operator^=(const _Tp&); + + /// Set each element e of array to e & @a t. + valarray<_Tp>& operator&=(const _Tp&); + + /// Set each element e of array to e | @a t. + valarray<_Tp>& operator|=(const _Tp&); + + /// Left shift each element e of array by @a t bits. + valarray<_Tp>& operator<<=(const _Tp&); + + /// Right shift each element e of array by @a t bits. + valarray<_Tp>& operator>>=(const _Tp&); + + /// Multiply elements of array by corresponding elements of @a v. + valarray<_Tp>& operator*=(const valarray<_Tp>&); + + /// Divide elements of array by corresponding elements of @a v. + valarray<_Tp>& operator/=(const valarray<_Tp>&); + + /// Modulo elements of array by corresponding elements of @a v. + valarray<_Tp>& operator%=(const valarray<_Tp>&); + + /// Add corresponding elements of @a v to elements of array. + valarray<_Tp>& operator+=(const valarray<_Tp>&); + + /// Subtract corresponding elements of @a v from elements of array. + valarray<_Tp>& operator-=(const valarray<_Tp>&); + + /// Logical xor corresponding elements of @a v with elements of array. + valarray<_Tp>& operator^=(const valarray<_Tp>&); + + /// Logical or corresponding elements of @a v with elements of array. + valarray<_Tp>& operator|=(const valarray<_Tp>&); + + /// Logical and corresponding elements of @a v with elements of array. + valarray<_Tp>& operator&=(const valarray<_Tp>&); + + /// Left shift elements of array by corresponding elements of @a v. + valarray<_Tp>& operator<<=(const valarray<_Tp>&); + + /// Right shift elements of array by corresponding elements of @a v. + valarray<_Tp>& operator>>=(const valarray<_Tp>&); + + template + valarray<_Tp>& operator*=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator/=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator%=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator+=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator-=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator^=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator|=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator&=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&); + + + // _lib.valarray.members_ member functions: + /// Return the number of elements in array. + size_t size() const; + + /** + * @brief Return the sum of all elements in the array. + * + * Accumulates the sum of all elements into a Tp using +=. The order + * of adding the elements is unspecified. + */ + _Tp sum() const; + + /// Return the minimum element using operator<(). + _Tp min() const; + + /// Return the maximum element using operator<(). + _Tp max() const; + + // // FIXME: Extension + // _Tp product () const; + + /** + * @brief Return a shifted array. + * + * A new valarray is constructed as a copy of this array with elements + * in shifted positions. For an element with index i, the new position + * is i - n. The new valarray is the same size as the current one. + * New elements without a value are set to 0. Elements whos new + * position is outside the bounds of the array are discarded. + * + * Positive arguments shift toward index 0, discarding elements [0, n). + * Negative arguments discard elements from the top of the array. + * + * @param n Number of element positions to shift. + * @return New valarray with elements in shifted positions. + */ + valarray<_Tp> shift (int) const; + + /** + * @brief Return a rotated array. + * + * A new valarray is constructed as a copy of this array with elements + * in shifted positions. For an element with index i, the new position + * is (i - n) % size(). The new valarray is the same size as the + * current one. Elements that are shifted beyond the array bounds are + * shifted into the other end of the array. No elements are lost. + * + * Positive arguments shift toward index 0, wrapping around the top. + * Negative arguments shift towards the top, wrapping around to 0. + * + * @param n Number of element positions to rotate. + * @return New valarray with elements in shifted positions. + */ + valarray<_Tp> cshift(int) const; + + /** + * @brief Apply a function to the array. + * + * Returns a new valarray with elements assigned to the result of + * applying func to the corresponding element of this array. The new + * array is the same size as this one. + * + * @param func Function of Tp returning Tp to apply. + * @return New valarray with transformed elements. + */ + _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const; + + /** + * @brief Apply a function to the array. + * + * Returns a new valarray with elements assigned to the result of + * applying func to the corresponding element of this array. The new + * array is the same size as this one. + * + * @param func Function of const Tp& returning Tp to apply. + * @return New valarray with transformed elements. + */ + _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const; + + /** + * @brief Resize array. + * + * Resize this array to be @a size and set all elements to @a c. All + * references and iterators are invalidated. + * + * @param size New array size. + * @param c New value for all elements. + */ + void resize(size_t __size, _Tp __c = _Tp()); + + private: + size_t _M_size; + _Tp* __restrict__ _M_data; + + friend class _Array<_Tp>; + }; + + template + inline const _Tp& + valarray<_Tp>::operator[](size_t __i) const + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } + + template + inline _Tp& + valarray<_Tp>::operator[](size_t __i) + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } + +} // std:: + +#include + +#include +#include +#include +#include +#include + +namespace std +{ + template + inline + valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {} + + template + inline + valarray<_Tp>::valarray(size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_default_construct(_M_data, _M_data + __n); } + + template + inline + valarray<_Tp>::valarray(const _Tp& __t, size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } + + template + inline + valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) + : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) + { + _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0); + std::__valarray_copy_construct(__p, __p + __n, _M_data); + } + + template + inline + valarray<_Tp>::valarray(const valarray<_Tp>& __v) + : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) + { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); } + + template + inline + valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) + : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) + { + std::__valarray_copy + (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); + } + + template + inline + valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) + : _M_size(__ga._M_index.size()), + _M_data(__valarray_get_storage<_Tp>(_M_size)) + { + std::__valarray_copy + (__ga._M_array, _Array(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + } + + template + inline + valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) + : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) + { + std::__valarray_copy + (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); + } + + template + inline + valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) + : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) + { + std::__valarray_copy + (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); + } + + template template + inline + valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) + : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) + { std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); } + + template + inline + valarray<_Tp>::~valarray() + { + std::__valarray_destroy_elements(_M_data, _M_data + _M_size); + std::__valarray_release_memory(_M_data); + } + + template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const valarray<_Tp>& __v) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); + std::__valarray_copy(__v._M_data, _M_size, _M_data); + return *this; + } + + template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const _Tp& __t) + { + std::__valarray_fill(_M_data, _M_size, __t); + return *this; + } + + template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz); + std::__valarray_copy(__sa._M_array, __sa._M_sz, + __sa._M_stride, _Array<_Tp>(_M_data)); + return *this; + } + + template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size()); + std::__valarray_copy(__ga._M_array, _Array(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz); + std::__valarray_copy(__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz); + std::__valarray_copy(__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); + return *this; + } + + template template + inline valarray<_Tp>& + valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) + { + _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size()); + std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); + return *this; + } + + template + inline _Expr<_SClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[](slice __s) const + { + typedef _SClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); + } + + template + inline slice_array<_Tp> + valarray<_Tp>::operator[](slice __s) + { + return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); + } + + template + inline _Expr<_GClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[](const gslice& __gs) const + { + typedef _GClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> + (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); + } + + template + inline gslice_array<_Tp> + valarray<_Tp>::operator[](const gslice& __gs) + { + return gslice_array<_Tp> + (_Array<_Tp>(_M_data), __gs._M_index->_M_index); + } + + template + inline valarray<_Tp> + valarray<_Tp>::operator[](const valarray& __m) const + { + size_t __s = 0; + size_t __e = __m.size(); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, + _Array (__m))); + } + + template + inline mask_array<_Tp> + valarray<_Tp>::operator[](const valarray& __m) + { + size_t __s = 0; + size_t __e = __m.size(); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array(__m)); + } + + template + inline _Expr<_IClos<_ValArray,_Tp>, _Tp> + valarray<_Tp>::operator[](const valarray& __i) const + { + typedef _IClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp>(_Closure(*this, __i)); + } + + template + inline indirect_array<_Tp> + valarray<_Tp>::operator[](const valarray& __i) + { + return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), + _Array(__i)); + } + + template + inline size_t + valarray<_Tp>::size() const + { return _M_size; } + + template + inline _Tp + valarray<_Tp>::sum() const + { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return std::__valarray_sum(_M_data, _M_data + _M_size); + } + +// template +// inline _Tp +// valarray<_Tp>::product () const +// { +// return __valarray_product(_M_data, _M_data + _M_size); +// } + + template + inline valarray<_Tp> + valarray<_Tp>::shift(int __n) const + { + _Tp* const __a = static_cast<_Tp*> + (__builtin_alloca(sizeof(_Tp) * _M_size)); + if (__n == 0) // no shift + std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a); + else if (__n > 0) // __n > 0: shift left + { + if (size_t(__n) > _M_size) + std::__valarray_default_construct(__a, __a + __n); + else + { + std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); + std::__valarray_default_construct(__a+_M_size-__n, __a + _M_size); + } + } + else // __n < 0: shift right + { + std::__valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n); + std::__valarray_default_construct(__a, __a - __n); + } + return valarray<_Tp> (__a, _M_size); + } + + template + inline valarray<_Tp> + valarray<_Tp>::cshift (int __n) const + { + _Tp* const __a = static_cast<_Tp*> + (__builtin_alloca (sizeof(_Tp) * _M_size)); + if (__n == 0) // no cshift + std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a); + else if (__n > 0) // cshift left + { + std::__valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n); + std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); + } + else // cshift right + { + std::__valarray_copy_construct + (_M_data + _M_size+__n, _M_data + _M_size, __a); + std::__valarray_copy_construct + (_M_data, _M_data + _M_size+__n, __a - __n); + } + return valarray<_Tp>(__a, _M_size); + } + + template + inline void + valarray<_Tp>::resize (size_t __n, _Tp __c) + { + // This complication is so to make valarray > work + // even though it is not required by the standard. Nobody should + // be saying valarray > anyway. See the specs. + std::__valarray_destroy_elements(_M_data, _M_data + _M_size); + if (_M_size != __n) + { + std::__valarray_release_memory(_M_data); + _M_size = __n; + _M_data = __valarray_get_storage<_Tp>(__n); + } + std::__valarray_fill_construct(_M_data, _M_data + __n, __c); + } + + template + inline _Tp + valarray<_Tp>::min() const + { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return *std::min_element (_M_data, _M_data+_M_size); + } + + template + inline _Tp + valarray<_Tp>::max() const + { + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return *std::max_element (_M_data, _M_data+_M_size); + } + + template + inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> + valarray<_Tp>::apply(_Tp func(_Tp)) const + { + typedef _ValFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp>(_Closure(*this, func)); + } + + template + inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> + valarray<_Tp>::apply(_Tp func(const _Tp &)) const + { + typedef _RefFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp>(_Closure(*this, func)); + } + +#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ + template \ + inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ + valarray<_Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name,_ValArray,_Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Rt>(_Closure(*this)); \ + } + + _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) + _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) + _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) + _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) + +#undef _DEFINE_VALARRAY_UNARY_OPERATOR + +#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template \ + inline valarray<_Tp>& \ + valarray<_Tp>::operator _Op##=(const _Tp &__t) \ + { \ + _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ + return *this; \ + } \ + \ + template \ + inline valarray<_Tp>& \ + valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ + { \ + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \ + _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ + _Array<_Tp>(__v._M_data)); \ + return *this; \ + } + +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) + +#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT + +#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template template \ + inline valarray<_Tp>& \ + valarray<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) \ + { \ + _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ + return *this; \ + } + +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) + +#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, \ + typename __fun<_Name, _Tp>::result_type> \ + operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ + { \ + _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ + } \ + \ + template \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>, \ + typename __fun<_Name, _Tp>::result_type> \ + operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>, \ + typename __fun<_Name, _Tp>::result_type> \ + operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + typedef typename __fun<_Name, _Tp>::result_type _Rt; \ + return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \ + } + +_DEFINE_BINARY_OPERATOR(+, __plus) +_DEFINE_BINARY_OPERATOR(-, __minus) +_DEFINE_BINARY_OPERATOR(*, __multiplies) +_DEFINE_BINARY_OPERATOR(/, __divides) +_DEFINE_BINARY_OPERATOR(%, __modulus) +_DEFINE_BINARY_OPERATOR(^, __bitwise_xor) +_DEFINE_BINARY_OPERATOR(&, __bitwise_and) +_DEFINE_BINARY_OPERATOR(|, __bitwise_or) +_DEFINE_BINARY_OPERATOR(<<, __shift_left) +_DEFINE_BINARY_OPERATOR(>>, __shift_right) +_DEFINE_BINARY_OPERATOR(&&, __logical_and) +_DEFINE_BINARY_OPERATOR(||, __logical_or) +_DEFINE_BINARY_OPERATOR(==, __equal_to) +_DEFINE_BINARY_OPERATOR(!=, __not_equal_to) +_DEFINE_BINARY_OPERATOR(<, __less) +_DEFINE_BINARY_OPERATOR(>, __greater) +_DEFINE_BINARY_OPERATOR(<=, __less_equal) +_DEFINE_BINARY_OPERATOR(>=, __greater_equal) + +} // namespace std + +#endif /* _GLIBCXX_VALARRAY */ diff --git a/reactos/tools/ppc-build/core-headers/g++-v3/vector b/reactos/tools/ppc-build/core-headers/g++-v3/vector new file mode 100644 index 00000000000..16e50a99ec8 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g++-v3/vector @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * 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. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file vector + * This is a Standard C++ Library header. You should @c #include this header + * in your programs, rather than any of the "st[dl]_*.h" implementation files. + */ + +#ifndef _GLIBCXX_VECTOR +#define _GLIBCXX_VECTOR 1 + +#pragma GCC system_header + +#include +#include +#include +#include +#include +#include +#include + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +#endif + +#ifdef _GLIBCXX_DEBUG +# include +#endif + +#endif /* _GLIBCXX_VECTOR */ + diff --git a/reactos/tools/ppc-build/core-headers/g2c.h b/reactos/tools/ppc-build/core-headers/g2c.h new file mode 100644 index 00000000000..577ea2b1a8d --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/g2c.h @@ -0,0 +1,234 @@ +/* g2c.h -- g77 version of f2c (Standard Fortran to C header file) */ + +/* This file is generated by the g77 libg2c configuration process from a + file named g2c.hin. This process sets up the appropriate types, + defines the appropriate macros, and so on. The resulting g2c.h file + is used to build g77's copy of libf2c, named libg2c, and also can + be used when compiling C code produced by f2c to link the resulting + object file(s) with those produced by the same version of g77 that + produced this file, allowing inter-operability of f2c-compiled and + g77-compiled code. */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +#ifndef F2C_INCLUDE +#define F2C_INCLUDE + +/* F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems */ +/* we assume short, float are OK */ +typedef __g77_integer integer; +typedef __g77_uinteger uinteger; +typedef char *address; +typedef short int shortint; +typedef float real; +typedef double doublereal; +typedef struct { real r, i; } complex; +typedef struct { doublereal r, i; } doublecomplex; +typedef __g77_integer logical; +typedef short int shortlogical; +typedef char logical1; +typedef char integer1; +typedef __g77_longint longint; /* system-dependent */ +typedef __g77_ulongint ulongint; /* system-dependent */ +#define qbit_clear(a,b) ((a) & ~((ulongint)1 << (b))) +#define qbit_set(a,b) ((a) | ((ulongint)1 << (b))) + +#define TRUE_ (1) +#define FALSE_ (0) + +/* Extern is for use with -E */ +#ifndef Extern +#define Extern extern +#endif + +/* I/O stuff */ + +#ifdef f2c_i2 +#error "f2c_i2 will not work with g77!!!!" +/* for -i2 */ +typedef short flag; +typedef short ftnlen; +typedef short ftnint; +#else +typedef __g77_integer flag; +typedef __g77_integer ftnlen; +typedef __g77_integer ftnint; +#endif + +/*external read, write*/ +typedef struct +{ flag cierr; + ftnint ciunit; + flag ciend; + char *cifmt; + ftnint cirec; +} cilist; + +/*internal read, write*/ +typedef struct +{ flag icierr; + char *iciunit; + flag iciend; + char *icifmt; + ftnint icirlen; + ftnint icirnum; +} icilist; + +/*open*/ +typedef struct +{ flag oerr; + ftnint ounit; + char *ofnm; + ftnlen ofnmlen; + char *osta; + char *oacc; + char *ofm; + ftnint orl; + char *oblnk; +} olist; + +/*close*/ +typedef struct +{ flag cerr; + ftnint cunit; + char *csta; +} cllist; + +/*rewind, backspace, endfile*/ +typedef struct +{ flag aerr; + ftnint aunit; +} alist; + +/* inquire */ +typedef struct +{ flag inerr; + ftnint inunit; + char *infile; + ftnlen infilen; + ftnint *inex; /*parameters in standard's order*/ + ftnint *inopen; + ftnint *innum; + ftnint *innamed; + char *inname; + ftnlen innamlen; + char *inacc; + ftnlen inacclen; + char *inseq; + ftnlen inseqlen; + char *indir; + ftnlen indirlen; + char *infmt; + ftnlen infmtlen; + char *inform; + ftnint informlen; + char *inunf; + ftnlen inunflen; + ftnint *inrecl; + ftnint *innrec; + char *inblank; + ftnlen inblanklen; +} inlist; + +union Multitype { /* for multiple entry points */ + integer1 g; + shortint h; + integer i; + /* longint j; */ + real r; + doublereal d; + complex c; + doublecomplex z; + }; + +typedef union Multitype Multitype; + +/*typedef long int Long;*/ /* No longer used; formerly in Namelist */ + +struct Vardesc { /* for Namelist */ + char *name; + char *addr; + ftnlen *dims; + int type; + }; +typedef struct Vardesc Vardesc; + +struct Namelist { + char *name; + Vardesc **vars; + int nvars; + }; +typedef struct Namelist Namelist; + +#define abs(x) ((x) >= 0 ? (x) : -(x)) +#define dabs(x) (doublereal)abs(x) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#define dmin(a,b) (doublereal)min(a,b) +#define dmax(a,b) (doublereal)max(a,b) +#define bit_test(a,b) ((a) >> (b) & 1) +#define bit_clear(a,b) ((a) & ~((uinteger)1 << (b))) +#define bit_set(a,b) ((a) | ((uinteger)1 << (b))) + +/* procedure parameter types for -A and -C++ */ + +#define F2C_proc_par_types 1 +#ifdef __cplusplus +typedef int /* Unknown procedure type */ (*U_fp)(...); +typedef shortint (*J_fp)(...); +typedef integer (*I_fp)(...); +typedef real (*R_fp)(...); +typedef doublereal (*D_fp)(...), (*E_fp)(...); +typedef /* Complex */ void (*C_fp)(...); +typedef /* Double Complex */ void (*Z_fp)(...); +typedef logical (*L_fp)(...); +typedef shortlogical (*K_fp)(...); +typedef /* Character */ void (*H_fp)(...); +typedef /* Subroutine */ int (*S_fp)(...); +#else +typedef int /* Unknown procedure type */ (*U_fp)(); +typedef shortint (*J_fp)(); +typedef integer (*I_fp)(); +typedef real (*R_fp)(); +typedef doublereal (*D_fp)(), (*E_fp)(); +typedef /* Complex */ void (*C_fp)(); +typedef /* Double Complex */ void (*Z_fp)(); +typedef logical (*L_fp)(); +typedef shortlogical (*K_fp)(); +typedef /* Character */ void (*H_fp)(); +typedef /* Subroutine */ int (*S_fp)(); +#endif +/* E_fp is for real functions when -R is not specified */ +typedef void C_f; /* complex function */ +typedef void H_f; /* character function */ +typedef void Z_f; /* double complex function */ +typedef doublereal E_f; /* real function with -R not specified */ + +/* undef any lower-case symbols that your C compiler predefines, e.g.: */ + +#ifndef Skip_f2c_Undefs +/* (No such symbols should be defined in a strict ANSI C compiler. + We can avoid trouble with f2c-translated code by using + gcc -ansi [-traditional].) */ +#undef cray +#undef gcos +#undef mc68010 +#undef mc68020 +#undef mips +#undef pdp11 +#undef sgi +#undef sparc +#undef sun +#undef sun2 +#undef sun3 +#undef sun4 +#undef u370 +#undef u3b +#undef u3b2 +#undef u3b5 +#undef unix +#undef vax +#endif +#endif diff --git a/reactos/tools/ppc-build/core-headers/iso646.h b/reactos/tools/ppc-build/core-headers/iso646.h new file mode 100644 index 00000000000..f09672a9787 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/iso646.h @@ -0,0 +1,48 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.9 Alternative spellings + */ + +#ifndef _ISO646_H +#define _ISO646_H + +#ifndef __cplusplus +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= +#endif + +#endif diff --git a/reactos/tools/ppc-build/core-headers/limits.h b/reactos/tools/ppc-build/core-headers/limits.h new file mode 100644 index 00000000000..30e08a716a9 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/limits.h @@ -0,0 +1,125 @@ +/* This administrivia gets added to the beginning of limits.h + if the system has its own version of limits.h. */ + +/* We use _GCC_LIMITS_H_ because we want this not to match + any macros that the system's limits.h uses for its own purposes. */ +#ifndef _GCC_LIMITS_H_ /* Terminated in limity.h. */ +#define _GCC_LIMITS_H_ + +#ifndef _LIBC_LIMITS_H_ +/* Use "..." so that we find syslimits.h only in this same directory. */ +#include "syslimits.h" +#endif +#ifndef _LIMITS_H___ +#define _LIMITS_H___ + +/* Number of bits in a `char'. */ +#undef CHAR_BIT +#define CHAR_BIT __CHAR_BIT__ + +/* Maximum length of a multibyte character. */ +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1 +#endif + +/* Minimum and maximum values a `signed char' can hold. */ +#undef SCHAR_MIN +#define SCHAR_MIN (-SCHAR_MAX - 1) +#undef SCHAR_MAX +#define SCHAR_MAX __SCHAR_MAX__ + +/* Maximum value an `unsigned char' can hold. (Minimum is 0). */ +#undef UCHAR_MAX +#if __SCHAR_MAX__ == __INT_MAX__ +# define UCHAR_MAX (SCHAR_MAX * 2U + 1U) +#else +# define UCHAR_MAX (SCHAR_MAX * 2 + 1) +#endif + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +# undef CHAR_MIN +# if __SCHAR_MAX__ == __INT_MAX__ +# define CHAR_MIN 0U +# else +# define CHAR_MIN 0 +# endif +# undef CHAR_MAX +# define CHAR_MAX UCHAR_MAX +#else +# undef CHAR_MIN +# define CHAR_MIN SCHAR_MIN +# undef CHAR_MAX +# define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#undef SHRT_MIN +#define SHRT_MIN (-SHRT_MAX - 1) +#undef SHRT_MAX +#define SHRT_MAX __SHRT_MAX__ + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */ +#undef USHRT_MAX +#if __SHRT_MAX__ == __INT_MAX__ +# define USHRT_MAX (SHRT_MAX * 2U + 1U) +#else +# define USHRT_MAX (SHRT_MAX * 2 + 1) +#endif + +/* Minimum and maximum values a `signed int' can hold. */ +#undef INT_MIN +#define INT_MIN (-INT_MAX - 1) +#undef INT_MAX +#define INT_MAX __INT_MAX__ + +/* Maximum value an `unsigned int' can hold. (Minimum is 0). */ +#undef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1U) + +/* Minimum and maximum values a `signed long int' can hold. + (Same as `int'). */ +#undef LONG_MIN +#define LONG_MIN (-LONG_MAX - 1L) +#undef LONG_MAX +#define LONG_MAX __LONG_MAX__ + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ +#undef ULONG_MAX +#define ULONG_MAX (LONG_MAX * 2UL + 1UL) + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +# undef LLONG_MAX +# define LLONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULLONG_MAX +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +#endif + +#if defined (__GNU_LIBRARY__) ? defined (__USE_GNU) : !defined (__STRICT_ANSI__) +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LONG_LONG_MIN +# define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL) +# undef LONG_LONG_MAX +# define LONG_LONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULONG_LONG_MAX +# define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL) +#endif + +#endif /* _LIMITS_H___ */ +/* This administrivia gets added to the end of limits.h + if the system has its own version of limits.h. */ + +#else /* not _GCC_LIMITS_H_ */ + +#ifdef _GCC_NEXT_LIMITS_H +#include_next /* recurse down to the real one */ +#endif + +#endif /* not _GCC_LIMITS_H_ */ diff --git a/reactos/tools/ppc-build/core-headers/ppc-asm.h b/reactos/tools/ppc-build/core-headers/ppc-asm.h new file mode 100644 index 00000000000..74e14836286 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/ppc-asm.h @@ -0,0 +1,164 @@ +/* PowerPC asm definitions for GNU C. */ +/* Under winnt, 1) gas supports the following as names and 2) in particular + defining "toc" breaks the FUNC_START macro as ".toc" becomes ".2" */ + +#define r0 0 +#define sp 1 +#define toc 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + +#define f0 0 +#define f1 1 +#define f2 2 +#define f3 3 +#define f4 4 +#define f5 5 +#define f6 6 +#define f7 7 +#define f8 8 +#define f9 9 +#define f10 10 +#define f11 11 +#define f12 12 +#define f13 13 +#define f14 14 +#define f15 15 +#define f16 16 +#define f17 17 +#define f18 18 +#define f19 19 +#define f20 20 +#define f21 21 +#define f22 22 +#define f23 23 +#define f24 24 +#define f25 25 +#define f26 26 +#define f27 27 +#define f28 28 +#define f29 29 +#define f30 30 +#define f31 31 + +/* + * Macros to glue together two tokens. + */ + +#ifdef __STDC__ +#define XGLUE(a,b) a##b +#else +#define XGLUE(a,b) a/**/b +#endif + +#define GLUE(a,b) XGLUE(a,b) + +/* + * Macros to begin and end a function written in assembler. If -mcall-aixdesc + * or -mcall-nt, create a function descriptor with the given name, and create + * the real function with one or two leading periods respectively. + */ + +#if defined (__powerpc64__) +#define FUNC_NAME(name) GLUE(.,name) +#define JUMP_TARGET(name) FUNC_NAME(name) +#define FUNC_START(name) \ + .section ".opd","aw"; \ +name: \ + .quad GLUE(.,name); \ + .quad .TOC.@tocbase; \ + .quad 0; \ + .previous; \ + .type GLUE(.,name),@function; \ + .globl name; \ + .globl GLUE(.,name); \ +GLUE(.,name): + +#define FUNC_END(name) \ +GLUE(.L,name): \ + .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name) + +#elif defined(_CALL_AIXDESC) + +#ifdef _RELOCATABLE +#define DESC_SECTION ".got2" +#else +#define DESC_SECTION ".got1" +#endif + +#define FUNC_NAME(name) GLUE(.,name) +#define JUMP_TARGET(name) FUNC_NAME(name) +#define FUNC_START(name) \ + .section DESC_SECTION,"aw"; \ +name: \ + .long GLUE(.,name); \ + .long _GLOBAL_OFFSET_TABLE_; \ + .long 0; \ + .previous; \ + .type GLUE(.,name),@function; \ + .globl name; \ + .globl GLUE(.,name); \ +GLUE(.,name): + +#define FUNC_END(name) \ +GLUE(.L,name): \ + .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name) + +#else + +#define FUNC_NAME(name) GLUE(__USER_LABEL_PREFIX__,name) +#if defined __PIC__ || defined __pic__ +#define JUMP_TARGET(name) FUNC_NAME(name@plt) +#else +#define JUMP_TARGET(name) FUNC_NAME(name) +#endif +#define FUNC_START(name) \ + .type FUNC_NAME(name),@function; \ + .globl FUNC_NAME(name); \ +FUNC_NAME(name): + +#define FUNC_END(name) \ +GLUE(.L,name): \ + .size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name) +#endif + +#if defined __linux__ && !defined __powerpc64__ + .section .note.GNU-stack + .previous +#endif diff --git a/reactos/tools/ppc-build/core-headers/spe.h b/reactos/tools/ppc-build/core-headers/spe.h new file mode 100644 index 00000000000..878fc72b2e5 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/spe.h @@ -0,0 +1,1110 @@ +/* PowerPC E500 user include file. + Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +#ifndef _SPE_H +#define _SPE_H + +#define __vector __attribute__((vector_size(8))) + +typedef int int32_t; +typedef unsigned uint32_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; + +typedef short __vector __ev64_s16__; +typedef unsigned short __vector __ev64_u16__; +typedef int __vector __ev64_s32__; +typedef unsigned __vector __ev64_u32__; +typedef long long __vector __ev64_s64__; +typedef unsigned long long __vector __ev64_u64__; +typedef float __vector __ev64_fs__; + +#define __v2si __ev64_opaque__ +#define __v2sf __ev64_fs__ + +#define __ev_addw __builtin_spe_evaddw +#define __ev_addiw __builtin_spe_evaddiw +#define __ev_subfw(a,b) __builtin_spe_evsubfw ((b), (a)) +#define __ev_subw __builtin_spe_evsubfw +#define __ev_subifw(a,b) __builtin_spe_evsubifw ((b), (a)) +#define __ev_subiw __builtin_spe_evsubifw +#define __ev_abs __builtin_spe_evabs +#define __ev_neg __builtin_spe_evneg +#define __ev_extsb __builtin_spe_evextsb +#define __ev_extsh __builtin_spe_evextsh +#define __ev_and __builtin_spe_evand +#define __ev_or __builtin_spe_evor +#define __ev_xor __builtin_spe_evxor +#define __ev_nand __builtin_spe_evnand +#define __ev_nor __builtin_spe_evnor +#define __ev_eqv __builtin_spe_eveqv +#define __ev_andc __builtin_spe_evandc +#define __ev_orc __builtin_spe_evorc +#define __ev_rlw __builtin_spe_evrlw +#define __ev_rlwi __builtin_spe_evrlwi +#define __ev_slw __builtin_spe_evslw +#define __ev_slwi __builtin_spe_evslwi +#define __ev_srws __builtin_spe_evsrws +#define __ev_srwu __builtin_spe_evsrwu +#define __ev_srwis __builtin_spe_evsrwis +#define __ev_srwiu __builtin_spe_evsrwiu +#define __ev_cntlzw __builtin_spe_evcntlzw +#define __ev_cntlsw __builtin_spe_evcntlsw +#define __ev_rndw __builtin_spe_evrndw +#define __ev_mergehi __builtin_spe_evmergehi +#define __ev_mergelo __builtin_spe_evmergelo +#define __ev_mergelohi __builtin_spe_evmergelohi +#define __ev_mergehilo __builtin_spe_evmergehilo +#define __ev_splati __builtin_spe_evsplati +#define __ev_splatfi __builtin_spe_evsplatfi +#define __ev_divws __builtin_spe_evdivws +#define __ev_divwu __builtin_spe_evdivwu +#define __ev_mra __builtin_spe_evmra + +#define __brinc __builtin_spe_brinc + +/* Loads. */ + +#define __ev_lddx __builtin_spe_evlddx +#define __ev_ldwx __builtin_spe_evldwx +#define __ev_ldhx __builtin_spe_evldhx +#define __ev_lwhex __builtin_spe_evlwhex +#define __ev_lwhoux __builtin_spe_evlwhoux +#define __ev_lwhosx __builtin_spe_evlwhosx +#define __ev_lwwsplatx __builtin_spe_evlwwsplatx +#define __ev_lwhsplatx __builtin_spe_evlwhsplatx +#define __ev_lhhesplatx __builtin_spe_evlhhesplatx +#define __ev_lhhousplatx __builtin_spe_evlhhousplatx +#define __ev_lhhossplatx __builtin_spe_evlhhossplatx +#define __ev_ldd __builtin_spe_evldd +#define __ev_ldw __builtin_spe_evldw +#define __ev_ldh __builtin_spe_evldh +#define __ev_lwhe __builtin_spe_evlwhe +#define __ev_lwhou __builtin_spe_evlwhou +#define __ev_lwhos __builtin_spe_evlwhos +#define __ev_lwwsplat __builtin_spe_evlwwsplat +#define __ev_lwhsplat __builtin_spe_evlwhsplat +#define __ev_lhhesplat __builtin_spe_evlhhesplat +#define __ev_lhhousplat __builtin_spe_evlhhousplat +#define __ev_lhhossplat __builtin_spe_evlhhossplat + +/* Stores. */ + +#define __ev_stddx __builtin_spe_evstddx +#define __ev_stdwx __builtin_spe_evstdwx +#define __ev_stdhx __builtin_spe_evstdhx +#define __ev_stwwex __builtin_spe_evstwwex +#define __ev_stwwox __builtin_spe_evstwwox +#define __ev_stwhex __builtin_spe_evstwhex +#define __ev_stwhox __builtin_spe_evstwhox +#define __ev_stdd __builtin_spe_evstdd +#define __ev_stdw __builtin_spe_evstdw +#define __ev_stdh __builtin_spe_evstdh +#define __ev_stwwe __builtin_spe_evstwwe +#define __ev_stwwo __builtin_spe_evstwwo +#define __ev_stwhe __builtin_spe_evstwhe +#define __ev_stwho __builtin_spe_evstwho + +/* Fixed point complex. */ + +#define __ev_mhossf __builtin_spe_evmhossf +#define __ev_mhosmf __builtin_spe_evmhosmf +#define __ev_mhosmi __builtin_spe_evmhosmi +#define __ev_mhoumi __builtin_spe_evmhoumi +#define __ev_mhessf __builtin_spe_evmhessf +#define __ev_mhesmf __builtin_spe_evmhesmf +#define __ev_mhesmi __builtin_spe_evmhesmi +#define __ev_mheumi __builtin_spe_evmheumi +#define __ev_mhossfa __builtin_spe_evmhossfa +#define __ev_mhosmfa __builtin_spe_evmhosmfa +#define __ev_mhosmia __builtin_spe_evmhosmia +#define __ev_mhoumia __builtin_spe_evmhoumia +#define __ev_mhessfa __builtin_spe_evmhessfa +#define __ev_mhesmfa __builtin_spe_evmhesmfa +#define __ev_mhesmia __builtin_spe_evmhesmia +#define __ev_mheumia __builtin_spe_evmheumia + +#define __ev_mhoumf __ev_mhoumi +#define __ev_mheumf __ev_mheumi +#define __ev_mhoumfa __ev_mhoumia +#define __ev_mheumfa __ev_mheumia + +#define __ev_mhossfaaw __builtin_spe_evmhossfaaw +#define __ev_mhossiaaw __builtin_spe_evmhossiaaw +#define __ev_mhosmfaaw __builtin_spe_evmhosmfaaw +#define __ev_mhosmiaaw __builtin_spe_evmhosmiaaw +#define __ev_mhousiaaw __builtin_spe_evmhousiaaw +#define __ev_mhoumiaaw __builtin_spe_evmhoumiaaw +#define __ev_mhessfaaw __builtin_spe_evmhessfaaw +#define __ev_mhessiaaw __builtin_spe_evmhessiaaw +#define __ev_mhesmfaaw __builtin_spe_evmhesmfaaw +#define __ev_mhesmiaaw __builtin_spe_evmhesmiaaw +#define __ev_mheusiaaw __builtin_spe_evmheusiaaw +#define __ev_mheumiaaw __builtin_spe_evmheumiaaw + +#define __ev_mhousfaaw __ev_mhousiaaw +#define __ev_mhoumfaaw __ev_mhoumiaaw +#define __ev_mheusfaaw __ev_mheusiaaw +#define __ev_mheumfaaw __ev_mheumiaaw + +#define __ev_mhossfanw __builtin_spe_evmhossfanw +#define __ev_mhossianw __builtin_spe_evmhossianw +#define __ev_mhosmfanw __builtin_spe_evmhosmfanw +#define __ev_mhosmianw __builtin_spe_evmhosmianw +#define __ev_mhousianw __builtin_spe_evmhousianw +#define __ev_mhoumianw __builtin_spe_evmhoumianw +#define __ev_mhessfanw __builtin_spe_evmhessfanw +#define __ev_mhessianw __builtin_spe_evmhessianw +#define __ev_mhesmfanw __builtin_spe_evmhesmfanw +#define __ev_mhesmianw __builtin_spe_evmhesmianw +#define __ev_mheusianw __builtin_spe_evmheusianw +#define __ev_mheumianw __builtin_spe_evmheumianw + +#define __ev_mhousfanw __ev_mhousianw +#define __ev_mhoumfanw __ev_mhoumianw +#define __ev_mheusfanw __ev_mheusianw +#define __ev_mheumfanw __ev_mheumianw + +#define __ev_mhogsmfaa __builtin_spe_evmhogsmfaa +#define __ev_mhogsmiaa __builtin_spe_evmhogsmiaa +#define __ev_mhogumiaa __builtin_spe_evmhogumiaa +#define __ev_mhegsmfaa __builtin_spe_evmhegsmfaa +#define __ev_mhegsmiaa __builtin_spe_evmhegsmiaa +#define __ev_mhegumiaa __builtin_spe_evmhegumiaa + +#define __ev_mhogumfaa __ev_mhogumiaa +#define __ev_mhegumfaa __ev_mhegumiaa + +#define __ev_mhogsmfan __builtin_spe_evmhogsmfan +#define __ev_mhogsmian __builtin_spe_evmhogsmian +#define __ev_mhogumian __builtin_spe_evmhogumian +#define __ev_mhegsmfan __builtin_spe_evmhegsmfan +#define __ev_mhegsmian __builtin_spe_evmhegsmian +#define __ev_mhegumian __builtin_spe_evmhegumian + +#define __ev_mhogumfan __ev_mhogumian +#define __ev_mhegumfan __ev_mhegumian + +#define __ev_mwhssf __builtin_spe_evmwhssf +#define __ev_mwhsmf __builtin_spe_evmwhsmf +#define __ev_mwhsmi __builtin_spe_evmwhsmi +#define __ev_mwhumi __builtin_spe_evmwhumi +#define __ev_mwhssfa __builtin_spe_evmwhssfa +#define __ev_mwhsmfa __builtin_spe_evmwhsmfa +#define __ev_mwhsmia __builtin_spe_evmwhsmia +#define __ev_mwhumia __builtin_spe_evmwhumia + +#define __ev_mwhumf __ev_mwhumi +#define __ev_mwhumfa __ev_mwhumia + +#define __ev_mwlumi __builtin_spe_evmwlumi +#define __ev_mwlumia __builtin_spe_evmwlumia +#define __ev_mwlumiaaw __builtin_spe_evmwlumiaaw + +#define __ev_mwlssiaaw __builtin_spe_evmwlssiaaw +#define __ev_mwlsmiaaw __builtin_spe_evmwlsmiaaw +#define __ev_mwlusiaaw __builtin_spe_evmwlusiaaw +#define __ev_mwlusiaaw __builtin_spe_evmwlusiaaw + +#define __ev_mwlssianw __builtin_spe_evmwlssianw +#define __ev_mwlsmianw __builtin_spe_evmwlsmianw +#define __ev_mwlusianw __builtin_spe_evmwlusianw +#define __ev_mwlumianw __builtin_spe_evmwlumianw + +#define __ev_mwssf __builtin_spe_evmwssf +#define __ev_mwsmf __builtin_spe_evmwsmf +#define __ev_mwsmi __builtin_spe_evmwsmi +#define __ev_mwumi __builtin_spe_evmwumi +#define __ev_mwssfa __builtin_spe_evmwssfa +#define __ev_mwsmfa __builtin_spe_evmwsmfa +#define __ev_mwsmia __builtin_spe_evmwsmia +#define __ev_mwumia __builtin_spe_evmwumia + +#define __ev_mwumf __ev_mwumi +#define __ev_mwumfa __ev_mwumia + +#define __ev_mwssfaa __builtin_spe_evmwssfaa +#define __ev_mwsmfaa __builtin_spe_evmwsmfaa +#define __ev_mwsmiaa __builtin_spe_evmwsmiaa +#define __ev_mwumiaa __builtin_spe_evmwumiaa + +#define __ev_mwumfaa __ev_mwumiaa + +#define __ev_mwssfan __builtin_spe_evmwssfan +#define __ev_mwsmfan __builtin_spe_evmwsmfan +#define __ev_mwsmian __builtin_spe_evmwsmian +#define __ev_mwumian __builtin_spe_evmwumian + +#define __ev_mwumfan __ev_mwumian + +#define __ev_addssiaaw __builtin_spe_evaddssiaaw +#define __ev_addsmiaaw __builtin_spe_evaddsmiaaw +#define __ev_addusiaaw __builtin_spe_evaddusiaaw +#define __ev_addumiaaw __builtin_spe_evaddumiaaw + +#define __ev_addusfaaw __ev_addusiaaw +#define __ev_addumfaaw __ev_addumiaaw +#define __ev_addsmfaaw __ev_addsmiaaw +#define __ev_addssfaaw __ev_addssiaaw + +#define __ev_subfssiaaw __builtin_spe_evsubfssiaaw +#define __ev_subfsmiaaw __builtin_spe_evsubfsmiaaw +#define __ev_subfusiaaw __builtin_spe_evsubfusiaaw +#define __ev_subfumiaaw __builtin_spe_evsubfumiaaw + +#define __ev_subfusfaaw __ev_subfusiaaw +#define __ev_subfumfaaw __ev_subfumiaaw +#define __ev_subfsmfaaw __ev_subfsmiaaw +#define __ev_subfssfaaw __ev_subfssiaaw + +/* Floating Point SIMD Instructions */ + +#define __ev_fsabs __builtin_spe_evfsabs +#define __ev_fsnabs __builtin_spe_evfsnabs +#define __ev_fsneg __builtin_spe_evfsneg +#define __ev_fsadd __builtin_spe_evfsadd +#define __ev_fssub __builtin_spe_evfssub +#define __ev_fsmul __builtin_spe_evfsmul +#define __ev_fsdiv __builtin_spe_evfsdiv +#define __ev_fscfui __builtin_spe_evfscfui +#define __ev_fscfsi __builtin_spe_evfscfsi +#define __ev_fscfuf __builtin_spe_evfscfuf +#define __ev_fscfsf __builtin_spe_evfscfsf +#define __ev_fsctui __builtin_spe_evfsctui +#define __ev_fsctsi __builtin_spe_evfsctsi +#define __ev_fsctuf __builtin_spe_evfsctuf +#define __ev_fsctsf __builtin_spe_evfsctsf +#define __ev_fsctuiz __builtin_spe_evfsctuiz +#define __ev_fsctsiz __builtin_spe_evfsctsiz + +/* NOT SUPPORTED IN FIRST e500, support via two instructions: */ + +#define __ev_mwhusfaaw __ev_mwhusiaaw +#define __ev_mwhumfaaw __ev_mwhumiaaw +#define __ev_mwhusfanw __ev_mwhusianw +#define __ev_mwhumfanw __ev_mwhumianw +#define __ev_mwhgumfaa __ev_mwhgumiaa +#define __ev_mwhgumfan __ev_mwhgumian + +#define __ev_mwhgssfaa __internal_ev_mwhgssfaa +#define __ev_mwhgsmfaa __internal_ev_mwhgsmfaa +#define __ev_mwhgsmiaa __internal_ev_mwhgsmiaa +#define __ev_mwhgumiaa __internal_ev_mwhgumiaa +#define __ev_mwhgssfan __internal_ev_mwhgssfan +#define __ev_mwhgsmfan __internal_ev_mwhgsmfan +#define __ev_mwhgsmian __internal_ev_mwhgsmian +#define __ev_mwhgumian __internal_ev_mwhgumian +#define __ev_mwhssiaaw __internal_ev_mwhssiaaw +#define __ev_mwhssfaaw __internal_ev_mwhssfaaw +#define __ev_mwhsmfaaw __internal_ev_mwhsmfaaw +#define __ev_mwhsmiaaw __internal_ev_mwhsmiaaw +#define __ev_mwhusiaaw __internal_ev_mwhusiaaw +#define __ev_mwhumiaaw __internal_ev_mwhumiaaw +#define __ev_mwhssfanw __internal_ev_mwhssfanw +#define __ev_mwhssianw __internal_ev_mwhssianw +#define __ev_mwhsmfanw __internal_ev_mwhsmfanw +#define __ev_mwhsmianw __internal_ev_mwhsmianw +#define __ev_mwhusianw __internal_ev_mwhusianw +#define __ev_mwhumianw __internal_ev_mwhumianw + +static inline __ev64_opaque__ +__internal_ev_mwhssfaaw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhssf (a, b); + return __ev_addssiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhssiaaw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmi (a, b); + return __ev_addssiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhsmfaaw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmf (a, b); + return __ev_addsmiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhsmiaaw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmi (a, b); + return __ev_addsmiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhusiaaw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhumi (a, b); + return __ev_addusiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhumiaaw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhumi (a, b); + return __ev_addumiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhssfanw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhssf (a, b); + return __ev_subfssiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhssianw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmi (a, b); + return __ev_subfssiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhsmfanw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmf (a, b); + return __ev_subfsmiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhsmianw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmi (a, b); + return __ev_subfsmiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhusianw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhumi (a, b); + return __ev_subfusiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhumianw (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhumi (a, b); + return __ev_subfumiaaw (t); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgssfaa (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhssf (a, b); + return __ev_mwsmiaa (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgsmfaa (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmf (a, b); + return __ev_mwsmiaa (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgsmiaa (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmi (a, b); + return __ev_mwsmiaa (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgumiaa (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhumi (a, b); + return __ev_mwumiaa (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgssfan (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhssf (a, b); + return __ev_mwsmian (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgsmfan (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmf (a, b); + return __ev_mwsmian (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgsmian (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhsmi (a, b); + return __ev_mwsmian (t, ((__ev64_s32__){1, 1})); +} + +static inline __ev64_opaque__ +__internal_ev_mwhgumian (__ev64_opaque__ a, __ev64_opaque__ b) +{ + __ev64_opaque__ t; + + t = __ev_mwhumi (a, b); + return __ev_mwumian (t, ((__ev64_s32__){1, 1})); +} + +/* END OF NOT SUPPORTED */ + +/* __ev_create* functions. */ + +#define __ev_create_ufix32_u32 __ev_create_u32 +#define __ev_create_sfix32_s32 __ev_create_s32 + +static inline __ev64_opaque__ +__ev_create_s16 (int16_t a, int16_t b, int16_t c, int16_t d) +{ + union + { + __ev64_opaque__ v; + int16_t i[4]; + } u; + + u.i[0] = a; + u.i[1] = b; + u.i[2] = c; + u.i[3] = d; + + return u.v; +} + +static inline __ev64_opaque__ +__ev_create_u16 (uint16_t a, uint16_t b, uint16_t c, uint16_t d) + +{ + union + { + __ev64_opaque__ v; + uint16_t i[4]; + } u; + + u.i[0] = a; + u.i[1] = b; + u.i[2] = c; + u.i[3] = d; + + return u.v; +} + +static inline __ev64_opaque__ +__ev_create_s32 (int32_t a, int32_t b) +{ + union + { + __ev64_opaque__ v; + int32_t i[2]; + } u; + + u.i[0] = a; + u.i[1] = b; + + return u.v; +} + +static inline __ev64_opaque__ +__ev_create_u32 (uint32_t a, uint32_t b) +{ + union + { + __ev64_opaque__ v; + uint32_t i[2]; + } u; + + u.i[0] = a; + u.i[1] = b; + + return u.v; +} + +static inline __ev64_opaque__ +__ev_create_fs (float a, float b) +{ + union + { + __ev64_opaque__ v; + float f[2]; + } u; + + u.f[0] = a; + u.f[1] = b; + + return u.v; +} + +static inline __ev64_opaque__ +__ev_create_sfix32_fs (float a, float b) +{ + __ev64_opaque__ ev; + + ev = (__ev64_opaque__) __ev_create_fs (a, b); + return (__ev64_opaque__) __builtin_spe_evfsctsf ((__v2sf) ev); +} + +static inline __ev64_opaque__ +__ev_create_ufix32_fs (float a, float b) +{ + __ev64_opaque__ ev; + + ev = (__ev64_opaque__) __ev_create_fs (a, b); + return (__ev64_opaque__) __builtin_spe_evfsctuf ((__v2sf) ev); +} + +static inline __ev64_opaque__ +__ev_create_s64 (int64_t a) +{ + union + { + __ev64_opaque__ v; + int64_t i; + } u; + + u.i = a; + return u.v; +} + +static inline __ev64_opaque__ +__ev_create_u64 (uint64_t a) +{ + union + { + __ev64_opaque__ v; + uint64_t i; + } u; + + u.i = a; + return u.v; +} + +static inline uint64_t +__ev_convert_u64 (__ev64_opaque__ a) +{ + return (uint64_t) a; +} + +static inline int64_t +__ev_convert_s64 (__ev64_opaque__ a) +{ + return (int64_t) a; +} + +/* __ev_get_* functions. */ + +#define __ev_get_upper_u32(a) __ev_get_u32_internal ((a), 0) +#define __ev_get_lower_u32(a) __ev_get_u32_internal ((a), 1) +#define __ev_get_upper_s32(a) __ev_get_s32_internal ((a), 0) +#define __ev_get_lower_s32(a) __ev_get_s32_internal ((a), 1) +#define __ev_get_upper_fs(a) __ev_get_fs_internal ((a), 0) +#define __ev_get_lower_fs(a) __ev_get_fs_internal ((a), 1) +#define __ev_get_upper_ufix32_u32 __ev_get_upper_u32 +#define __ev_get_lower_ufix32_u32 __ev_get_lower_u32 +#define __ev_get_upper_sfix32_s32 __ev_get_upper_s32 +#define __ev_get_lower_sfix32_s32 __ev_get_lower_s32 +#define __ev_get_upper_sfix32_fs(a) __ev_get_sfix32_fs ((a), 0) +#define __ev_get_lower_sfix32_fs(a) __ev_get_sfix32_fs ((a), 1) +#define __ev_get_upper_ufix32_fs(a) __ev_get_ufix32_fs ((a), 0) +#define __ev_get_lower_ufix32_fs(a) __ev_get_ufix32_fs ((a), 1) + +#define __ev_get_u32 __ev_get_u32_internal +#define __ev_get_s32 __ev_get_s32_internal +#define __ev_get_fs __ev_get_fs_internal +#define __ev_get_u16 __ev_get_u16_internal +#define __ev_get_s16 __ev_get_s16_internal + +#define __ev_get_ufix32_u32 __ev_get_u32 +#define __ev_get_sfix32_s32 __ev_get_s32 +#define __ev_get_ufix32_fs __ev_get_ufix32_fs_internal +#define __ev_get_sfix32_fs __ev_get_sfix32_fs_internal + +static inline uint32_t +__ev_get_u32_internal (__ev64_opaque__ a, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + uint32_t i[2]; + } u; + + u.v = a; + return u.i[pos]; +} + +static inline int32_t +__ev_get_s32_internal (__ev64_opaque__ a, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + int32_t i[2]; + } u; + + u.v = a; + return u.i[pos]; +} + +static inline float +__ev_get_fs_internal (__ev64_opaque__ a, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + float f[2]; + } u; + + u.v = a; + return u.f[pos]; +} + +static inline float +__ev_get_sfix32_fs_internal (__ev64_opaque__ a, uint32_t pos) +{ + __ev64_fs__ v; + + v = __builtin_spe_evfscfsf ((__v2sf) a); + return __ev_get_fs_internal ((__ev64_opaque__) v, pos); +} + +static inline float +__ev_get_ufix32_fs_internal (__ev64_opaque__ a, uint32_t pos) +{ + __ev64_fs__ v; + + v = __builtin_spe_evfscfuf ((__v2sf) a); + return __ev_get_fs_internal ((__ev64_opaque__) v, pos); +} + +static inline uint16_t +__ev_get_u16_internal (__ev64_opaque__ a, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + uint16_t i[4]; + } u; + + u.v = a; + return u.i[pos]; +} + +static inline int16_t +__ev_get_s16_internal (__ev64_opaque__ a, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + int16_t i[4]; + } u; + + u.v = a; + return u.i[pos]; +} + +/* __ev_set_* functions. */ + +#define __ev_set_u32 __ev_set_u32_internal +#define __ev_set_s32 __ev_set_s32_internal +#define __ev_set_fs __ev_set_fs_internal +#define __ev_set_u16 __ev_set_u16_internal +#define __ev_set_s16 __ev_set_s16_internal + +#define __ev_set_ufix32_u32 __ev_set_u32 +#define __ev_set_sfix32_s32 __ev_set_s32 + +#define __ev_set_sfix32_fs __ev_set_sfix32_fs_internal +#define __ev_set_ufix32_fs __ev_set_ufix32_fs_internal + +#define __ev_set_upper_u32(a, b) __ev_set_u32 (a, b, 0) +#define __ev_set_lower_u32(a, b) __ev_set_u32 (a, b, 1) +#define __ev_set_upper_s32(a, b) __ev_set_s32 (a, b, 0) +#define __ev_set_lower_s32(a, b) __ev_set_s32 (a, b, 1) +#define __ev_set_upper_fs(a, b) __ev_set_fs (a, b, 0) +#define __ev_set_lower_fs(a, b) __ev_set_fs (a, b, 1) +#define __ev_set_upper_ufix32_u32 __ev_set_upper_u32 +#define __ev_set_lower_ufix32_u32 __ev_set_lower_u32 +#define __ev_set_upper_sfix32_s32 __ev_set_upper_s32 +#define __ev_set_lower_sfix32_s32 __ev_set_lower_s32 +#define __ev_set_upper_sfix32_fs(a, b) __ev_set_sfix32_fs (a, b, 0) +#define __ev_set_lower_sfix32_fs(a, b) __ev_set_sfix32_fs (a, b, 1) +#define __ev_set_upper_ufix32_fs(a, b) __ev_set_ufix32_fs (a, b, 0) +#define __ev_set_lower_ufix32_fs(a, b) __ev_set_ufix32_fs (a, b, 1) + +#define __ev_set_acc_vec64 __builtin_spe_evmra + +static inline __ev64_opaque__ +__ev_set_acc_u64 (uint64_t a) +{ + __ev64_opaque__ ev32; + ev32 = __ev_create_u64 (a); + __ev_mra (ev32); + return ev32; +} + +static inline __ev64_opaque__ +__ev_set_acc_s64 (int64_t a) +{ + __ev64_opaque__ ev32; + ev32 = __ev_create_s64 (a); + __ev_mra (ev32); + return ev32; +} + +static inline __ev64_opaque__ +__ev_set_u32_internal (__ev64_opaque__ a, uint32_t b, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + uint32_t i[2]; + } u; + + u.v = a; + u.i[pos] = b; + return u.v; +} + +static inline __ev64_opaque__ +__ev_set_s32_internal (__ev64_opaque__ a, int32_t b, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + int32_t i[2]; + } u; + + u.v = a; + u.i[pos] = b; + return u.v; +} + +static inline __ev64_opaque__ +__ev_set_fs_internal (__ev64_opaque__ a, float b, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + float f[2]; + } u; + + u.v = a; + u.f[pos] = b; + return u.v; +} + +static inline __ev64_opaque__ +__ev_set_sfix32_fs_internal (__ev64_opaque__ a, float b, uint32_t pos) +{ + __ev64_opaque__ v; + float other; + + /* Get other half. */ + other = __ev_get_fs_internal (a, pos ^ 1); + + /* Make an sfix32 with 'b'. */ + v = __ev_create_sfix32_fs (b, b); + + /* Set other half to what it used to be. */ + return __ev_set_fs_internal (v, other, pos ^ 1); +} + +static inline __ev64_opaque__ +__ev_set_ufix32_fs_internal (__ev64_opaque__ a, float b, uint32_t pos) +{ + __ev64_opaque__ v; + float other; + + /* Get other half. */ + other = __ev_get_fs_internal (a, pos ^ 1); + + /* Make an ufix32 with 'b'. */ + v = __ev_create_ufix32_fs (b, b); + + /* Set other half to what it used to be. */ + return __ev_set_fs_internal (v, other, pos ^ 1); +} + +static inline __ev64_opaque__ +__ev_set_u16_internal (__ev64_opaque__ a, uint16_t b, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + uint16_t i[4]; + } u; + + u.v = a; + u.i[pos] = b; + return u.v; +} + +static inline __ev64_opaque__ +__ev_set_s16_internal (__ev64_opaque__ a, int16_t b, uint32_t pos) +{ + union + { + __ev64_opaque__ v; + int16_t i[4]; + } u; + + u.v = a; + u.i[pos] = b; + return u.v; +} + +/* Predicates. */ + +#define __pred_all 0 +#define __pred_any 1 +#define __pred_upper 2 +#define __pred_lower 3 + +#define __ev_any_gts(a, b) __builtin_spe_evcmpgts (__pred_any, (a), (b)) +#define __ev_all_gts(a, b) __builtin_spe_evcmpgts (__pred_all, (a), (b)) +#define __ev_upper_gts(a, b) __builtin_spe_evcmpgts (__pred_upper, (a), (b)) +#define __ev_lower_gts(a, b) __builtin_spe_evcmpgts (__pred_lower, (a), (b)) +#define __ev_select_gts __builtin_spe_evsel_gts + +#define __ev_any_gtu(a, b) __builtin_spe_evcmpgtu (__pred_any, (a), (b)) +#define __ev_all_gtu(a, b) __builtin_spe_evcmpgtu (__pred_all, (a), (b)) +#define __ev_upper_gtu(a, b) __builtin_spe_evcmpgtu (__pred_upper, (a), (b)) +#define __ev_lower_gtu(a, b) __builtin_spe_evcmpgtu (__pred_lower, (a), (b)) +#define __ev_select_gtu __builtin_spe_evsel_gtu + +#define __ev_any_lts(a, b) __builtin_spe_evcmplts (__pred_any, (a), (b)) +#define __ev_all_lts(a, b) __builtin_spe_evcmplts (__pred_all, (a), (b)) +#define __ev_upper_lts(a, b) __builtin_spe_evcmplts (__pred_upper, (a), (b)) +#define __ev_lower_lts(a, b) __builtin_spe_evcmplts (__pred_lower, (a), (b)) +#define __ev_select_lts(a, b, c, d) ((__v2si) __builtin_spe_evsel_lts ((a), (b), (c), (d))) + +#define __ev_any_ltu(a, b) __builtin_spe_evcmpltu (__pred_any, (a), (b)) +#define __ev_all_ltu(a, b) __builtin_spe_evcmpltu (__pred_all, (a), (b)) +#define __ev_upper_ltu(a, b) __builtin_spe_evcmpltu (__pred_upper, (a), (b)) +#define __ev_lower_ltu(a, b) __builtin_spe_evcmpltu (__pred_lower, (a), (b)) +#define __ev_select_ltu __builtin_spe_evsel_ltu +#define __ev_any_eq(a, b) __builtin_spe_evcmpeq (__pred_any, (a), (b)) +#define __ev_all_eq(a, b) __builtin_spe_evcmpeq (__pred_all, (a), (b)) +#define __ev_upper_eq(a, b) __builtin_spe_evcmpeq (__pred_upper, (a), (b)) +#define __ev_lower_eq(a, b) __builtin_spe_evcmpeq (__pred_lower, (a), (b)) +#define __ev_select_eq __builtin_spe_evsel_eq + +#define __ev_any_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_any, (a), (b)) +#define __ev_all_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_all, (a), (b)) +#define __ev_upper_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_upper, (a), (b)) +#define __ev_lower_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_lower, (a), (b)) +#define __ev_select_fs_gt __builtin_spe_evsel_fsgt + +#define __ev_any_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_any, (a), (b)) +#define __ev_all_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_all, (a), (b)) +#define __ev_upper_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_upper, (a), (b)) +#define __ev_lower_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_lower, (a), (b)) +#define __ev_select_fs_lt __builtin_spe_evsel_fslt + +#define __ev_any_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_any, (a), (b)) +#define __ev_all_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_all, (a), (b)) +#define __ev_upper_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_upper, (a), (b)) +#define __ev_lower_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_lower, (a), (b)) +#define __ev_select_fs_eq __builtin_spe_evsel_fseq + +#define __ev_any_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_any, (a), (b)) +#define __ev_all_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_all, (a), (b)) +#define __ev_upper_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_upper, (a), (b)) +#define __ev_lower_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_lower, (a), (b)) +#define __ev_select_fs_tst_gt __builtin_spe_evsel_fststgt + +#define __ev_any_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_any, (a), (b)) +#define __ev_all_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_all, (a), (b)) +#define __ev_upper_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_upper, (a), (b)) +#define __ev_lower_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_lower, (a), (b)) +#define __ev_select_fs_tst_lt __builtin_spe_evsel_fststlt + +#define __ev_any_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_any, (a), (b)) +#define __ev_all_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_all, (a), (b)) +#define __ev_upper_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_upper, (a), (b)) +#define __ev_lower_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_lower, (a), (b)) +#define __ev_select_fs_tst_eq __builtin_spe_evsel_fststeq + +/* SPEFSCR accessor functions. */ + +#define __SPEFSCR_SOVH 0x80000000 +#define __SPEFSCR_OVH 0x40000000 +#define __SPEFSCR_FGH 0x20000000 +#define __SPEFSCR_FXH 0x10000000 +#define __SPEFSCR_FINVH 0x08000000 +#define __SPEFSCR_FDBZH 0x04000000 +#define __SPEFSCR_FUNFH 0x02000000 +#define __SPEFSCR_FOVFH 0x01000000 +/* 2 unused bits. */ +#define __SPEFSCR_FINXS 0x00200000 +#define __SPEFSCR_FINVS 0x00100000 +#define __SPEFSCR_FDBZS 0x00080000 +#define __SPEFSCR_FUNFS 0x00040000 +#define __SPEFSCR_FOVFS 0x00020000 +#define __SPEFSCR_MODE 0x00010000 +#define __SPEFSCR_SOV 0x00008000 +#define __SPEFSCR_OV 0x00004000 +#define __SPEFSCR_FG 0x00002000 +#define __SPEFSCR_FX 0x00001000 +#define __SPEFSCR_FINV 0x00000800 +#define __SPEFSCR_FDBZ 0x00000400 +#define __SPEFSCR_FUNF 0x00000200 +#define __SPEFSCR_FOVF 0x00000100 +/* 1 unused bit. */ +#define __SPEFSCR_FINXE 0x00000040 +#define __SPEFSCR_FINVE 0x00000020 +#define __SPEFSCR_FDBZE 0x00000010 +#define __SPEFSCR_FUNFE 0x00000008 +#define __SPEFSCR_FOVFE 0x00000004 +#define __SPEFSCR_FRMC 0x00000003 + +#define __ev_get_spefscr_sovh() (__builtin_spe_mfspefscr () & __SPEFSCR_SOVH) +#define __ev_get_spefscr_ovh() (__builtin_spe_mfspefscr () & __SPEFSCR_OVH) +#define __ev_get_spefscr_fgh() (__builtin_spe_mfspefscr () & __SPEFSCR_FGH) +#define __ev_get_spefscr_fxh() (__builtin_spe_mfspefscr () & __SPEFSCR_FXH) +#define __ev_get_spefscr_finvh() (__builtin_spe_mfspefscr () & __SPEFSCR_FINVH) +#define __ev_get_spefscr_fdbzh() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZH) +#define __ev_get_spefscr_funfh() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNFH) +#define __ev_get_spefscr_fovfh() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVFH) +#define __ev_get_spefscr_finxs() (__builtin_spe_mfspefscr () & __SPEFSCR_FINXS) +#define __ev_get_spefscr_finvs() (__builtin_spe_mfspefscr () & __SPEFSCR_FINVS) +#define __ev_get_spefscr_fdbzs() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZS) +#define __ev_get_spefscr_funfs() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNFS) +#define __ev_get_spefscr_fovfs() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVFS) +#define __ev_get_spefscr_mode() (__builtin_spe_mfspefscr () & __SPEFSCR_MODE) +#define __ev_get_spefscr_sov() (__builtin_spe_mfspefscr () & __SPEFSCR_SOV) +#define __ev_get_spefscr_ov() (__builtin_spe_mfspefscr () & __SPEFSCR_OV) +#define __ev_get_spefscr_fg() (__builtin_spe_mfspefscr () & __SPEFSCR_FG) +#define __ev_get_spefscr_fx() (__builtin_spe_mfspefscr () & __SPEFSCR_FX) +#define __ev_get_spefscr_finv() (__builtin_spe_mfspefscr () & __SPEFSCR_FINV) +#define __ev_get_spefscr_fdbz() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZ) +#define __ev_get_spefscr_funf() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNF) +#define __ev_get_spefscr_fovf() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVF) +#define __ev_get_spefscr_finxe() (__builtin_spe_mfspefscr () & __SPEFSCR_FINXE) +#define __ev_get_spefscr_finve() (__builtin_spe_mfspefscr () & __SPEFSCR_FINVE) +#define __ev_get_spefscr_fdbze() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZE) +#define __ev_get_spefscr_funfe() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNFE) +#define __ev_get_spefscr_fovfe() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVFE) +#define __ev_get_spefscr_frmc() (__builtin_spe_mfspefscr () & __SPEFSCR_FRMC) + +static inline void +__ev_clr_spefscr_field (int mask) +{ + int i; + + i = __builtin_spe_mfspefscr (); + i &= ~mask; + __builtin_spe_mtspefscr (i); +} + +#define __ev_clr_spefscr_sovh() __ev_clr_spefscr_field (__SPEFSCR_SOVH) +#define __ev_clr_spefscr_sov() __ev_clr_spefscr_field (__SPEFSCR_SOV) +#define __ev_clr_spefscr_finxs() __ev_clr_spefscr_field (__SPEFSCR_FINXS) +#define __ev_clr_spefscr_finvs() __ev_clr_spefscr_field (__SPEFSCR_FINVS) +#define __ev_clr_spefscr_fdbzs() __ev_clr_spefscr_field (__SPEFSCR_FDBZS) +#define __ev_clr_spefscr_funfs() __ev_clr_spefscr_field (__SPEFSCR_FUNFS) +#define __ev_clr_spefscr_fovfs() __ev_clr_spefscr_field (__SPEFSCR_FOVFS) + +/* Set rounding mode: + rnd = 0 (nearest) + rnd = 1 (zero) + rnd = 2 (+inf) + rnd = 3 (-inf). */ + +static inline void +__ev_set_spefscr_frmc (int rnd) +{ + int i; + + i = __builtin_spe_mfspefscr (); + i &= ~__SPEFSCR_FRMC; + i |= rnd; + __builtin_spe_mtspefscr (i); +} + +/* The SPE PIM says these are declared in , although they are + not provided by GCC: they must be taken from a separate + library. */ +extern short int atosfix16 (const char *); +extern int atosfix32 (const char *); +extern long long atosfix64 (const char *); + +extern unsigned short atoufix16 (const char *); +extern unsigned int atoufix32 (const char *); +extern unsigned long long atoufix64 (const char *); + +extern short int strtosfix16 (const char *, char **); +extern int strtosfix32 (const char *, char **); +extern long long strtosfix64 (const char *, char **); + +extern unsigned short int strtoufix16 (const char *, char **); +extern unsigned int strtoufix32 (const char *, char **); +extern unsigned long long strtoufix64 (const char *, char **); + +#endif /* _SPE_H */ diff --git a/reactos/tools/ppc-build/core-headers/stdarg.h b/reactos/tools/ppc-build/core-headers/stdarg.h new file mode 100644 index 00000000000..f178505e892 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/stdarg.h @@ -0,0 +1,133 @@ +/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.15 Variable arguments + */ + +#ifndef _STDARG_H +#ifndef _ANSI_STDARG_H_ +#ifndef __need___va_list +#define _STDARG_H +#define _ANSI_STDARG_H_ +#endif /* not __need___va_list */ +#undef __need___va_list + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +typedef __builtin_va_list __gnuc_va_list; +#endif + +/* Define the standard macros for the user, + if this invocation was from the user program. */ +#ifdef _STDARG_H + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L +#define va_copy(d,s) __builtin_va_copy(d,s) +#endif +#define __va_copy(d,s) __builtin_va_copy(d,s) + +/* Define va_list, if desired, from __gnuc_va_list. */ +/* We deliberately do not define va_list when called from + stdio.h, because ANSI C says that stdio.h is not supposed to define + va_list. stdio.h needs to have access to that data type, + but must not use that name. It should use the name __gnuc_va_list, + which is safe because it is reserved for the implementation. */ + +#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */ +#undef _VA_LIST +#endif + +#ifdef _BSD_VA_LIST +#undef _BSD_VA_LIST +#endif + +#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST)) +/* SVR4.2 uses _VA_LIST for an internal alias for va_list, + so we must avoid testing it and setting it here. + SVR4 uses _VA_LIST as a flag in stdarg.h, but we should + have no conflict with that. */ +#ifndef _VA_LIST_ +#define _VA_LIST_ +#ifdef __i860__ +#ifndef _VA_LIST +#define _VA_LIST va_list +#endif +#endif /* __i860__ */ +typedef __gnuc_va_list va_list; +#ifdef _SCO_DS +#define __VA_LIST +#endif +#endif /* _VA_LIST_ */ +#else /* not __svr4__ || _SCO_DS */ + +/* The macro _VA_LIST_ is the same thing used by this file in Ultrix. + But on BSD NET2 we must not test or define or undef it. + (Note that the comments in NET 2's ansi.h + are incorrect for _VA_LIST_--see stdio.h!) */ +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ +#ifndef _VA_LIST_DEFINED +/* The macro _VA_LIST is used in SCO Unix 3.2. */ +#ifndef _VA_LIST +/* The macro _VA_LIST_T_H is used in the Bull dpx2 */ +#ifndef _VA_LIST_T_H +/* The macro __va_list__ is used by BeOS. */ +#ifndef __va_list__ +typedef __gnuc_va_list va_list; +#endif /* not __va_list__ */ +#endif /* not _VA_LIST_T_H */ +#endif /* not _VA_LIST */ +#endif /* not _VA_LIST_DEFINED */ +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#define _VA_LIST_ +#endif +#ifndef _VA_LIST +#define _VA_LIST +#endif +#ifndef _VA_LIST_DEFINED +#define _VA_LIST_DEFINED +#endif +#ifndef _VA_LIST_T_H +#define _VA_LIST_T_H +#endif +#ifndef __va_list__ +#define __va_list__ +#endif + +#endif /* not _VA_LIST_, except on certain systems */ + +#endif /* not __svr4__ */ + +#endif /* _STDARG_H */ + +#endif /* not _ANSI_STDARG_H_ */ +#endif /* not _STDARG_H */ diff --git a/reactos/tools/ppc-build/core-headers/stdbool.h b/reactos/tools/ppc-build/core-headers/stdbool.h new file mode 100644 index 00000000000..93003e2b346 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/stdbool.h @@ -0,0 +1,53 @@ +/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.16 Boolean type and values + */ + +#ifndef _STDBOOL_H +#define _STDBOOL_H + +#ifndef __cplusplus + +#define bool _Bool +#define true 1 +#define false 0 + +#else /* __cplusplus */ + +/* Supporting in C++ is a GCC extension. */ +#define _Bool bool +#define bool bool +#define false false +#define true true + +#endif /* __cplusplus */ + +/* Signal that all the definitions are present. */ +#define __bool_true_false_are_defined 1 + +#endif /* stdbool.h */ diff --git a/reactos/tools/ppc-build/core-headers/stddef.h b/reactos/tools/ppc-build/core-headers/stddef.h new file mode 100644 index 00000000000..03bfbf986e2 --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/stddef.h @@ -0,0 +1,426 @@ +/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.17 Common definitions + */ +#if (!defined(_STDDEF_H) && !defined(_STDDEF_H_) && !defined(_ANSI_STDDEF_H) \ + && !defined(__STDDEF_H__)) \ + || defined(__need_wchar_t) || defined(__need_size_t) \ + || defined(__need_ptrdiff_t) || defined(__need_NULL) \ + || defined(__need_wint_t) + +/* Any one of these symbols __need_* means that GNU libc + wants us just to define one data type. So don't define + the symbols that indicate this file's entire job has been done. */ +#if (!defined(__need_wchar_t) && !defined(__need_size_t) \ + && !defined(__need_ptrdiff_t) && !defined(__need_NULL) \ + && !defined(__need_wint_t)) +#define _STDDEF_H +#define _STDDEF_H_ +/* snaroff@next.com says the NeXT needs this. */ +#define _ANSI_STDDEF_H +/* Irix 5.1 needs this. */ +#define __STDDEF_H__ +#endif + +#ifndef __sys_stdtypes_h +/* This avoids lossage on SunOS but only if stdtypes.h comes first. + There's no way to win with the other order! Sun lossage. */ + +/* On 4.3bsd-net2, make sure ansi.h is included, so we have + one less case to deal with in the following. */ +#if defined (__BSD_NET2__) || defined (____386BSD____) || (defined (__FreeBSD__) && (__FreeBSD__ < 5)) || defined(__NetBSD__) +#include +#endif +/* On FreeBSD 5, machine/ansi.h does not exist anymore... */ +#if defined (__FreeBSD__) && (__FreeBSD__ >= 5) +#include +#endif + +/* In 4.3bsd-net2, machine/ansi.h defines these symbols, which are + defined if the corresponding type is *not* defined. + FreeBSD-2.1 defines _MACHINE_ANSI_H_ instead of _ANSI_H_ */ +#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) +#if !defined(_SIZE_T_) && !defined(_BSD_SIZE_T_) +#define _SIZE_T +#endif +#if !defined(_PTRDIFF_T_) && !defined(_BSD_PTRDIFF_T_) +#define _PTRDIFF_T +#endif +/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_ + instead of _WCHAR_T_. */ +#if !defined(_WCHAR_T_) && !defined(_BSD_WCHAR_T_) +#ifndef _BSD_WCHAR_T_ +#define _WCHAR_T +#endif +#endif +/* Undef _FOO_T_ if we are supposed to define foo_t. */ +#if defined (__need_ptrdiff_t) || defined (_STDDEF_H_) +#undef _PTRDIFF_T_ +#undef _BSD_PTRDIFF_T_ +#endif +#if defined (__need_size_t) || defined (_STDDEF_H_) +#undef _SIZE_T_ +#undef _BSD_SIZE_T_ +#endif +#if defined (__need_wchar_t) || defined (_STDDEF_H_) +#undef _WCHAR_T_ +#undef _BSD_WCHAR_T_ +#endif +#endif /* defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) */ + +/* Sequent's header files use _PTRDIFF_T_ in some conflicting way. + Just ignore it. */ +#if defined (__sequent__) && defined (_PTRDIFF_T_) +#undef _PTRDIFF_T_ +#endif + +/* On VxWorks, may have defined macros like + _TYPE_size_t which will typedef size_t. fixincludes patched the + vxTypesBase.h so that this macro is only defined if _GCC_SIZE_T is + not defined, and so that defining this macro defines _GCC_SIZE_T. + If we find that the macros are still defined at this point, we must + invoke them so that the type is defined as expected. */ +#if defined (_TYPE_ptrdiff_t) && (defined (__need_ptrdiff_t) || defined (_STDDEF_H_)) +_TYPE_ptrdiff_t; +#undef _TYPE_ptrdiff_t +#endif +#if defined (_TYPE_size_t) && (defined (__need_size_t) || defined (_STDDEF_H_)) +_TYPE_size_t; +#undef _TYPE_size_t +#endif +#if defined (_TYPE_wchar_t) && (defined (__need_wchar_t) || defined (_STDDEF_H_)) +_TYPE_wchar_t; +#undef _TYPE_wchar_t +#endif + +/* In case nobody has defined these types, but we aren't running under + GCC 2.00, make sure that __PTRDIFF_TYPE__, __SIZE_TYPE__, and + __WCHAR_TYPE__ have reasonable values. This can happen if the + parts of GCC is compiled by an older compiler, that actually + include gstddef.h, such as collect2. */ + +/* Signed type of difference of two pointers. */ + +/* Define this type if we are doing the whole job, + or if we want this type in particular. */ +#if defined (_STDDEF_H) || defined (__need_ptrdiff_t) +#ifndef _PTRDIFF_T /* in case has defined it. */ +#ifndef _T_PTRDIFF_ +#ifndef _T_PTRDIFF +#ifndef __PTRDIFF_T +#ifndef _PTRDIFF_T_ +#ifndef _BSD_PTRDIFF_T_ +#ifndef ___int_ptrdiff_t_h +#ifndef _GCC_PTRDIFF_T +#define _PTRDIFF_T +#define _T_PTRDIFF_ +#define _T_PTRDIFF +#define __PTRDIFF_T +#define _PTRDIFF_T_ +#define _BSD_PTRDIFF_T_ +#define ___int_ptrdiff_t_h +#define _GCC_PTRDIFF_T +#ifndef __PTRDIFF_TYPE__ +#define __PTRDIFF_TYPE__ long int +#endif +typedef __PTRDIFF_TYPE__ ptrdiff_t; +#endif /* _GCC_PTRDIFF_T */ +#endif /* ___int_ptrdiff_t_h */ +#endif /* _BSD_PTRDIFF_T_ */ +#endif /* _PTRDIFF_T_ */ +#endif /* __PTRDIFF_T */ +#endif /* _T_PTRDIFF */ +#endif /* _T_PTRDIFF_ */ +#endif /* _PTRDIFF_T */ + +/* If this symbol has done its job, get rid of it. */ +#undef __need_ptrdiff_t + +#endif /* _STDDEF_H or __need_ptrdiff_t. */ + +/* Unsigned type of `sizeof' something. */ + +/* Define this type if we are doing the whole job, + or if we want this type in particular. */ +#if defined (_STDDEF_H) || defined (__need_size_t) +#ifndef __size_t__ /* BeOS */ +#ifndef __SIZE_T__ /* Cray Unicos/Mk */ +#ifndef _SIZE_T /* in case has defined it. */ +#ifndef _SYS_SIZE_T_H +#ifndef _T_SIZE_ +#ifndef _T_SIZE +#ifndef __SIZE_T +#ifndef _SIZE_T_ +#ifndef _BSD_SIZE_T_ +#ifndef _SIZE_T_DEFINED_ +#ifndef _SIZE_T_DEFINED +#ifndef _BSD_SIZE_T_DEFINED_ /* Darwin */ +#ifndef _SIZE_T_DECLARED /* FreeBSD 5 */ +#ifndef ___int_size_t_h +#ifndef _GCC_SIZE_T +#ifndef _SIZET_ +#ifndef __size_t +#define __size_t__ /* BeOS */ +#define __SIZE_T__ /* Cray Unicos/Mk */ +#define _SIZE_T +#define _SYS_SIZE_T_H +#define _T_SIZE_ +#define _T_SIZE +#define __SIZE_T +#define _SIZE_T_ +#define _BSD_SIZE_T_ +#define _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED +#define _BSD_SIZE_T_DEFINED_ /* Darwin */ +#define _SIZE_T_DECLARED /* FreeBSD 5 */ +#define ___int_size_t_h +#define _GCC_SIZE_T +#define _SIZET_ +#if defined (__FreeBSD__) && (__FreeBSD__ >= 5) +/* __size_t is a typedef on FreeBSD 5!, must not trash it. */ +#else +#define __size_t +#endif +#ifndef __SIZE_TYPE__ +#define __SIZE_TYPE__ long unsigned int +#endif +#if !(defined (__GNUG__) && defined (size_t)) +typedef __SIZE_TYPE__ size_t; +#ifdef __BEOS__ +typedef long ssize_t; +#endif /* __BEOS__ */ +#endif /* !(defined (__GNUG__) && defined (size_t)) */ +#endif /* __size_t */ +#endif /* _SIZET_ */ +#endif /* _GCC_SIZE_T */ +#endif /* ___int_size_t_h */ +#endif /* _SIZE_T_DECLARED */ +#endif /* _BSD_SIZE_T_DEFINED_ */ +#endif /* _SIZE_T_DEFINED */ +#endif /* _SIZE_T_DEFINED_ */ +#endif /* _BSD_SIZE_T_ */ +#endif /* _SIZE_T_ */ +#endif /* __SIZE_T */ +#endif /* _T_SIZE */ +#endif /* _T_SIZE_ */ +#endif /* _SYS_SIZE_T_H */ +#endif /* _SIZE_T */ +#endif /* __SIZE_T__ */ +#endif /* __size_t__ */ +#undef __need_size_t +#endif /* _STDDEF_H or __need_size_t. */ + + +/* Wide character type. + Locale-writers should change this as necessary to + be big enough to hold unique values not between 0 and 127, + and not (wchar_t) -1, for each defined multibyte character. */ + +/* Define this type if we are doing the whole job, + or if we want this type in particular. */ +#if defined (_STDDEF_H) || defined (__need_wchar_t) +#ifndef __wchar_t__ /* BeOS */ +#ifndef __WCHAR_T__ /* Cray Unicos/Mk */ +#ifndef _WCHAR_T +#ifndef _T_WCHAR_ +#ifndef _T_WCHAR +#ifndef __WCHAR_T +#ifndef _WCHAR_T_ +#ifndef _BSD_WCHAR_T_ +#ifndef _BSD_WCHAR_T_DEFINED_ /* Darwin */ +#ifndef _BSD_RUNE_T_DEFINED_ /* Darwin */ +#ifndef _WCHAR_T_DECLARED /* FreeBSD 5 */ +#ifndef _WCHAR_T_DEFINED_ +#ifndef _WCHAR_T_DEFINED +#ifndef _WCHAR_T_H +#ifndef ___int_wchar_t_h +#ifndef __INT_WCHAR_T_H +#ifndef _GCC_WCHAR_T +#define __wchar_t__ /* BeOS */ +#define __WCHAR_T__ /* Cray Unicos/Mk */ +#define _WCHAR_T +#define _T_WCHAR_ +#define _T_WCHAR +#define __WCHAR_T +#define _WCHAR_T_ +#define _BSD_WCHAR_T_ +#define _WCHAR_T_DEFINED_ +#define _WCHAR_T_DEFINED +#define _WCHAR_T_H +#define ___int_wchar_t_h +#define __INT_WCHAR_T_H +#define _GCC_WCHAR_T +#define _WCHAR_T_DECLARED + +/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_ + instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other + symbols in the _FOO_T_ family, stays defined even after its + corresponding type is defined). If we define wchar_t, then we + must undef _WCHAR_T_; for BSD/386 1.1 (and perhaps others), if + we undef _WCHAR_T_, then we must also define rune_t, since + headers like runetype.h assume that if machine/ansi.h is included, + and _BSD_WCHAR_T_ is not defined, then rune_t is available. + machine/ansi.h says, "Note that _WCHAR_T_ and _RUNE_T_ must be of + the same type." */ +#ifdef _BSD_WCHAR_T_ +#undef _BSD_WCHAR_T_ +#ifdef _BSD_RUNE_T_ +#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE) +typedef _BSD_RUNE_T_ rune_t; +#define _BSD_WCHAR_T_DEFINED_ +#define _BSD_RUNE_T_DEFINED_ /* Darwin */ +#if defined (__FreeBSD__) && (__FreeBSD__ < 5) +/* Why is this file so hard to maintain properly? In constrast to + the comment above regarding BSD/386 1.1, on FreeBSD for as long + as the symbol has existed, _BSD_RUNE_T_ must not stay defined or + redundant typedefs will occur when stdlib.h is included after this file. */ +#undef _BSD_RUNE_T_ +#endif +#endif +#endif +#endif +/* FreeBSD 5 can't be handled well using "traditional" logic above + since it no longer defines _BSD_RUNE_T_ yet still desires to export + rune_t in some cases... */ +#if defined (__FreeBSD__) && (__FreeBSD__ >= 5) +#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE) +#if __BSD_VISIBLE +#ifndef _RUNE_T_DECLARED +typedef __rune_t rune_t; +#define _RUNE_T_DECLARED +#endif +#endif +#endif +#endif + +#ifndef __WCHAR_TYPE__ +#define __WCHAR_TYPE__ int +#endif +#ifndef __cplusplus +typedef __WCHAR_TYPE__ wchar_t; +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif /* _WCHAR_T_DECLARED */ +#endif /* _BSD_RUNE_T_DEFINED_ */ +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif /* __WCHAR_T__ */ +#endif /* __wchar_t__ */ +#undef __need_wchar_t +#endif /* _STDDEF_H or __need_wchar_t. */ + +#if defined (__need_wint_t) +#ifndef _WINT_T +#define _WINT_T + +#ifndef __WINT_TYPE__ +#define __WINT_TYPE__ unsigned int +#endif +typedef __WINT_TYPE__ wint_t; +#endif +#undef __need_wint_t +#endif + +/* In 4.3bsd-net2, leave these undefined to indicate that size_t, etc. + are already defined. */ +/* BSD/OS 3.1 and FreeBSD [23].x require the MACHINE_ANSI_H check here. */ +#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) +/* The references to _GCC_PTRDIFF_T_, _GCC_SIZE_T_, and _GCC_WCHAR_T_ + are probably typos and should be removed before 2.8 is released. */ +#ifdef _GCC_PTRDIFF_T_ +#undef _PTRDIFF_T_ +#undef _BSD_PTRDIFF_T_ +#endif +#ifdef _GCC_SIZE_T_ +#undef _SIZE_T_ +#undef _BSD_SIZE_T_ +#endif +#ifdef _GCC_WCHAR_T_ +#undef _WCHAR_T_ +#undef _BSD_WCHAR_T_ +#endif +/* The following ones are the real ones. */ +#ifdef _GCC_PTRDIFF_T +#undef _PTRDIFF_T_ +#undef _BSD_PTRDIFF_T_ +#endif +#ifdef _GCC_SIZE_T +#undef _SIZE_T_ +#undef _BSD_SIZE_T_ +#endif +#ifdef _GCC_WCHAR_T +#undef _WCHAR_T_ +#undef _BSD_WCHAR_T_ +#endif +#endif /* _ANSI_H_ || _MACHINE_ANSI_H_ */ + +#endif /* __sys_stdtypes_h */ + +/* A null pointer constant. */ + +#if defined (_STDDEF_H) || defined (__need_NULL) +#undef NULL /* in case has defined it. */ +#ifdef __GNUG__ +#define NULL __null +#else /* G++ */ +#ifndef __cplusplus +#define NULL ((void *)0) +#else /* C++ */ +#define NULL 0 +#endif /* C++ */ +#endif /* G++ */ +#endif /* NULL not defined and or need NULL. */ +#undef __need_NULL + +#ifdef _STDDEF_H + +/* Offset of member MEMBER in a struct of type TYPE. */ +#ifndef __cplusplus +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#else +/* The cast to "char &" below avoids problems with user-defined + "operator &", which can appear in a POD type. */ +#define offsetof(TYPE, MEMBER) \ + (__offsetof__ (reinterpret_cast \ + (&reinterpret_cast \ + (static_cast (0)->MEMBER)))) +#endif /* C++ */ +#endif /* _STDDEF_H was defined this time */ + +#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__ + || __need_XXX was not defined before */ diff --git a/reactos/tools/ppc-build/core-headers/syslimits.h b/reactos/tools/ppc-build/core-headers/syslimits.h new file mode 100644 index 00000000000..a3628025e8a --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/syslimits.h @@ -0,0 +1,8 @@ +/* syslimits.h stands for the system's own limits.h file. + If we can use it ok unmodified, then we install this text. + If fixincludes fixes it, then the fixed version is installed + instead of this text. */ + +#define _GCC_NEXT_LIMITS_H /* tell gcc's limits.h to recurse */ +#include_next +#undef _GCC_NEXT_LIMITS_H diff --git a/reactos/tools/ppc-build/core-headers/unwind.h b/reactos/tools/ppc-build/core-headers/unwind.h new file mode 100644 index 00000000000..21f3feb86bc --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/unwind.h @@ -0,0 +1,232 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* This is derived from the C++ ABI for IA-64. Where we diverge + for cross-architecture compatibility are noted with "@@@". */ + +#ifndef _UNWIND_H +#define _UNWIND_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Level 1: Base ABI */ + +/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is + inefficient for 32-bit and smaller machines. */ +typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); +typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); +#if defined(__ia64__) && defined(__hpux__) +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); +#else +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); +#endif +typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); + +/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and + consumer of an exception. We'll go along with this for now even on + 32-bit machines. We'll need to provide some other option for + 16-bit machines and for machines with > 8 bits per byte. */ +typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); + +/* The unwind interface uses reason codes in several contexts to + identify the reasons for failures or other actions. */ +typedef enum +{ + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 +} _Unwind_Reason_Code; + + +/* The unwind interface uses a pointer to an exception header object + as its representation of an exception being thrown. In general, the + full representation of an exception object is language- and + implementation-specific, but it will be prefixed by a header + understood by the unwind interface. */ + +struct _Unwind_Exception; + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +struct _Unwind_Exception +{ + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + + /* @@@ The IA-64 ABI says that this structure must be double-word aligned. + Taking that literally does not make much sense generically. Instead we + provide the maximum alignment required by any type for the machine. */ +} __attribute__((__aligned__)); + + +/* The ACTIONS argument to the personality routine is a bitwise OR of one + or more of the following constants. */ +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 +#define _UA_END_OF_STACK 16 + +/* This is an opaque type used to refer to a system-specific data + structure used by the system unwinder. This context is created and + destroyed by the system, and passed to the personality routine + during unwinding. */ +struct _Unwind_Context; + +/* Raise an exception, passing along the given exception object. */ +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); + +/* Raise an exception for forced unwinding. */ + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, + void *); + +/* Helper to invoke the exception_cleanup routine. */ +extern void _Unwind_DeleteException (struct _Unwind_Exception *); + +/* Resume propagation of an existing exception. This is used after + e.g. executing cleanup code, and not to implement rethrowing. */ +extern void _Unwind_Resume (struct _Unwind_Exception *); + +/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow + a normal exception that was handled. */ +extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* @@@ Use unwind data to perform a stack backtrace. The trace callback + is called for every stack frame in the call chain, but no cleanup + actions are performed. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) + (struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* These functions are used for communicating information about the unwind + context (i.e. the unwind descriptors and the user register state) between + the unwind library and the personality routine and landing pad. Only + selected registers maybe manipulated. */ + +extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); + +extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); + +/* @@@ Retrieve the CFA of the given context. */ +extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); + +extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); + +extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *); + + +/* The personality routine is the function in the C++ (or other language) + runtime library which serves as an interface between the system unwind + library and language-specific exception handling semantics. It is + specific to the code fragment described by an unwind info block, and + it is always referenced via the pointer in the unwind info block, and + hence it has no ABI-specified name. + + Note that this implies that two different C++ implementations can + use different names, and have different contents in the language + specific data area. Moreover, that the language specific data + area contains no version info because name of the function invoked + provides more effective versioning by detecting at link time the + lack of code to handle the different data format. */ + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +/* @@@ The following alternate entry points are for setjmp/longjmp + based unwinding. */ + +struct SjLj_Function_Context; +extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *); +extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *); + +extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException + (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind + (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); +extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* @@@ The following provide access to the base addresses for text + and data-relative addressing in the LDSA. In order to stay link + compatible with the standard ABI for IA-64, we inline these. */ + +#ifdef __ia64__ +#include + +static inline _Unwind_Ptr +_Unwind_GetDataRelBase (struct _Unwind_Context *_C) +{ + /* The GP is stored in R1. */ + return _Unwind_GetGR (_C, 1); +} + +static inline _Unwind_Ptr +_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__))) +{ + abort (); + return 0; +} + +/* @@@ Retrieve the Backing Store Pointer of the given context. */ +extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *); +#else +extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *); +extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *); +#endif + +/* @@@ Given an address, return the entry point of the function that + contains it. */ +extern void * _Unwind_FindEnclosingFunction (void *pc); + +#ifdef __cplusplus +} +#endif + +#endif /* unwind.h */ diff --git a/reactos/tools/ppc-build/core-headers/varargs.h b/reactos/tools/ppc-build/core-headers/varargs.h new file mode 100644 index 00000000000..4b9803e71ac --- /dev/null +++ b/reactos/tools/ppc-build/core-headers/varargs.h @@ -0,0 +1,7 @@ +#ifndef _VARARGS_H +#define _VARARGS_H + +#error "GCC no longer implements ." +#error "Revise your code to use ." + +#endif From 0c8a94de765243871c20845d555721fc3e516a02 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 6 Jan 2007 02:44:40 +0000 Subject: [PATCH 68/81] Allow PowerPC too. svn path=/branches/powerpc/; revision=25325 --- reactos/ntoskrnl/ldr/loader.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index f971608e0ed..ab58fd84b54 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -714,7 +714,11 @@ LdrPEProcessModule( CPRINT("Incorrect PE magic: %08x\n", PENtHeaders->Signature); return STATUS_UNSUCCESSFUL; } +#ifdef _M_IX86 if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) +#elif defined(_M_PPC) + if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_POWERPC) +#endif { CPRINT("Incorrect Architechture: %04x\n", PENtHeaders->FileHeader.Machine); return STATUS_UNSUCCESSFUL; From 40d233d8777e39429d2bae91268c75af293326ca Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 6 Jan 2007 20:01:20 +0000 Subject: [PATCH 69/81] Make this allow POWERPC as well. svn path=/branches/powerpc/; revision=25333 --- reactos/ntoskrnl/ldr/loader.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index ab58fd84b54..e65d7a1b699 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -952,7 +952,11 @@ LdrSafePEProcessModule ( { return NULL; } +#ifdef _M_IX86 if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) +#elif defined(_M_PPC) + if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_POWERPC) +#endif { return NULL; } From 9e8cec3b58c8017d0a0d0dc0d607c73f15b41455 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 6 Jan 2007 22:31:50 +0000 Subject: [PATCH 70/81] Hal stubs. Build halppc. svn path=/branches/powerpc/; revision=25335 --- reactos/hal/halppc/directory.rbuild | 6 + reactos/hal/halppc/generic/beep.c | 42 + reactos/hal/halppc/generic/bus.c | 529 ++++++ reactos/hal/halppc/generic/display.c | 796 +++++++++ reactos/hal/halppc/generic/dma.c | 1950 +++++++++++++++++++++ reactos/hal/halppc/generic/drive.c | 33 + reactos/hal/halppc/generic/enum.c | 23 + reactos/hal/halppc/generic/fmutex.c | 101 ++ reactos/hal/halppc/generic/generic.rbuild | 26 + reactos/hal/halppc/generic/halinit.c | 69 + reactos/hal/halppc/generic/ipi.c | 24 + reactos/hal/halppc/generic/irq.S | 631 +++++++ reactos/hal/halppc/generic/irql.c | 425 +++++ reactos/hal/halppc/generic/isa.c | 75 + reactos/hal/halppc/generic/kdbg.c | 547 ++++++ reactos/hal/halppc/generic/mca.c | 79 + reactos/hal/halppc/generic/misc.c | 72 + reactos/hal/halppc/generic/pci.c | 812 +++++++++ reactos/hal/halppc/generic/portio.c | 289 +++ reactos/hal/halppc/generic/processor.c | 50 + reactos/hal/halppc/generic/pwroff.c | 121 ++ reactos/hal/halppc/generic/reboot.c | 41 + reactos/hal/halppc/generic/resource.c | 31 + reactos/hal/halppc/generic/spinlock.c | 191 ++ reactos/hal/halppc/generic/sysbus.c | 66 + reactos/hal/halppc/generic/sysinfo.c | 74 + reactos/hal/halppc/generic/systimer.S | 48 + reactos/hal/halppc/generic/time.c | 102 ++ reactos/hal/halppc/generic/timer.c | 205 +++ reactos/hal/halppc/include/apic.h | 214 +++ reactos/hal/halppc/include/bus.h | 133 ++ reactos/hal/halppc/include/hal.h | 37 + reactos/hal/halppc/include/haldma.h | 383 ++++ reactos/hal/halppc/include/halirq.h | 35 + reactos/hal/halppc/include/halp.h | 97 + reactos/hal/halppc/include/ioapic.h | 103 ++ reactos/hal/halppc/include/mps.h | 204 +++ reactos/hal/halppc/up/halinit_up.c | 35 + reactos/hal/halppc/up/halup.rbuild | 12 + reactos/hal/halppc/up/halup.rc | 5 + 40 files changed, 8716 insertions(+) create mode 100644 reactos/hal/halppc/directory.rbuild create mode 100644 reactos/hal/halppc/generic/beep.c create mode 100644 reactos/hal/halppc/generic/bus.c create mode 100644 reactos/hal/halppc/generic/display.c create mode 100644 reactos/hal/halppc/generic/dma.c create mode 100644 reactos/hal/halppc/generic/drive.c create mode 100644 reactos/hal/halppc/generic/enum.c create mode 100644 reactos/hal/halppc/generic/fmutex.c create mode 100644 reactos/hal/halppc/generic/generic.rbuild create mode 100644 reactos/hal/halppc/generic/halinit.c create mode 100644 reactos/hal/halppc/generic/ipi.c create mode 100644 reactos/hal/halppc/generic/irq.S create mode 100644 reactos/hal/halppc/generic/irql.c create mode 100644 reactos/hal/halppc/generic/isa.c create mode 100644 reactos/hal/halppc/generic/kdbg.c create mode 100644 reactos/hal/halppc/generic/mca.c create mode 100644 reactos/hal/halppc/generic/misc.c create mode 100644 reactos/hal/halppc/generic/pci.c create mode 100644 reactos/hal/halppc/generic/portio.c create mode 100644 reactos/hal/halppc/generic/processor.c create mode 100644 reactos/hal/halppc/generic/pwroff.c create mode 100644 reactos/hal/halppc/generic/reboot.c create mode 100644 reactos/hal/halppc/generic/resource.c create mode 100644 reactos/hal/halppc/generic/spinlock.c create mode 100644 reactos/hal/halppc/generic/sysbus.c create mode 100644 reactos/hal/halppc/generic/sysinfo.c create mode 100644 reactos/hal/halppc/generic/systimer.S create mode 100644 reactos/hal/halppc/generic/time.c create mode 100644 reactos/hal/halppc/generic/timer.c create mode 100644 reactos/hal/halppc/include/apic.h create mode 100644 reactos/hal/halppc/include/bus.h create mode 100644 reactos/hal/halppc/include/hal.h create mode 100644 reactos/hal/halppc/include/haldma.h create mode 100644 reactos/hal/halppc/include/halirq.h create mode 100644 reactos/hal/halppc/include/halp.h create mode 100644 reactos/hal/halppc/include/ioapic.h create mode 100644 reactos/hal/halppc/include/mps.h create mode 100644 reactos/hal/halppc/up/halinit_up.c create mode 100644 reactos/hal/halppc/up/halup.rbuild create mode 100644 reactos/hal/halppc/up/halup.rc diff --git a/reactos/hal/halppc/directory.rbuild b/reactos/hal/halppc/directory.rbuild new file mode 100644 index 00000000000..d1338a727ab --- /dev/null +++ b/reactos/hal/halppc/directory.rbuild @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/reactos/hal/halppc/generic/beep.c b/reactos/hal/halppc/generic/beep.c new file mode 100644 index 00000000000..f4e9d3b07ea --- /dev/null +++ b/reactos/hal/halppc/generic/beep.c @@ -0,0 +1,42 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/beep.c + * PURPOSE: Speaker function (it's only one) + * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de) + * UPDATE HISTORY: + * Created 31/01/99 + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +/* CONSTANTS *****************************************************************/ + +#define TIMER2 0x42 +#define TIMER3 0x43 +#define PORT_B 0x61 +#define CLOCKFREQ 1193167 + + +/* FUNCTIONS *****************************************************************/ +/* + * FUNCTION: Beeps the speaker. + * ARGUMENTS: + * Frequency = If 0, the speaker will be switched off, otherwise + * the speaker beeps with the specified frequency. + */ + +BOOLEAN +STDCALL +HalMakeBeep ( + ULONG Frequency + ) +{ + return TRUE; +} + diff --git a/reactos/hal/halppc/generic/bus.c b/reactos/hal/halppc/generic/bus.c new file mode 100644 index 00000000000..35bac840f2c --- /dev/null +++ b/reactos/hal/halppc/generic/bus.c @@ -0,0 +1,529 @@ +/* $Id: bus.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/bus.c + * PURPOSE: Bus functions + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + * + * + * TODO: + * - Add bus handler functions for all busses + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +#define TAG_BUS TAG('B', 'U', 'S', 'H') + +KSPIN_LOCK HalpBusHandlerSpinLock = {0,}; +LIST_ENTRY HalpBusHandlerList; + + +/* FUNCTIONS *****************************************************************/ + +static NTSTATUS STDCALL +HalpNoAdjustResourceList(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PCM_RESOURCE_LIST Resources) +{ + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS STDCALL +HalpNoAssignSlotResources(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PUNICODE_STRING RegistryPath, + PUNICODE_STRING DriverClassName, + PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT DeviceObject, + ULONG SlotNumber, + PCM_RESOURCE_LIST *AllocatedResources) +{ + return STATUS_NOT_SUPPORTED; +} + + +static ULONG STDCALL +HalpNoBusData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + return 0; +} + + +static ULONG STDCALL +HalpNoGetInterruptVector(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity) +{ + return 0; +} + + +static ULONG STDCALL +HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress) +{ + return 0; +} + + +PBUS_HANDLER +HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType, + BUS_DATA_TYPE BusDataType, + ULONG BusNumber) +{ + PBUS_HANDLER BusHandler = NULL; + + DPRINT("HalpAllocateBusHandler()\n"); + + BusHandler = ExAllocatePoolWithTag(NonPagedPool, + sizeof(BUS_HANDLER), + TAG_BUS); + if (BusHandler == NULL) + return NULL; + + RtlZeroMemory(BusHandler, + sizeof(BUS_HANDLER)); + + InsertTailList(&HalpBusHandlerList, + &BusHandler->Entry); + + BusHandler->InterfaceType = InterfaceType; + BusHandler->BusDataType = BusDataType; + BusHandler->BusNumber = BusNumber; + + /* initialize default bus handler functions */ + BusHandler->GetBusData = HalpNoBusData; + BusHandler->SetBusData = HalpNoBusData; + BusHandler->AdjustResourceList = HalpNoAdjustResourceList; + BusHandler->AssignSlotResources = HalpNoAssignSlotResources; + BusHandler->GetInterruptVector = HalpNoGetInterruptVector; + BusHandler->TranslateBusAddress = HalpNoTranslateBusAddress; + + /* any more ?? */ + + DPRINT("HalpAllocateBusHandler() done\n"); + + return BusHandler; +} + + +VOID +HalpInitBusHandlers(VOID) +{ + PBUS_HANDLER BusHandler; + + /* General preparations */ + KeInitializeSpinLock(&HalpBusHandlerSpinLock); + InitializeListHead(&HalpBusHandlerList); + + /* Initialize hal dispatch tables */ + HalQuerySystemInformation = HalpQuerySystemInformation; + +#if 0 + HalSetSystemInformation = HalpSetSystemInformation; + + HalQueryBusSlots = HalpQueryBusSlots; +#endif + + /* Add system bus handler */ + BusHandler = HalpAllocateBusHandler(Internal, + ConfigurationSpaceUndefined, + 0); + if (BusHandler == NULL) + return; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetSystemInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslateSystemBusAddress; + + /* Add cmos bus handler */ + BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined, + Cmos, + 0); + if (BusHandler == NULL) + return; + BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData; + BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData; + + /* Add isa bus handler */ + BusHandler = HalpAllocateBusHandler(Isa, + ConfigurationSpaceUndefined, + 0); + if (BusHandler == NULL) + return; + + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetIsaInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslateIsaBusAddress; + + /* Add MicroChannel bus handler */ + BusHandler = HalpAllocateBusHandler(MicroChannel, + Pos, + 0); + if (BusHandler == NULL) + return; + + BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData; +} + + +PBUS_HANDLER FASTCALL +HaliHandlerForBus(INTERFACE_TYPE InterfaceType, + ULONG BusNumber) +{ + PBUS_HANDLER BusHandler; + PLIST_ENTRY CurrentEntry; + KIRQL OldIrql; + + KeAcquireSpinLock(&HalpBusHandlerSpinLock, + &OldIrql); + + CurrentEntry = HalpBusHandlerList.Flink; + while (CurrentEntry != &HalpBusHandlerList) + { + BusHandler = (PBUS_HANDLER)CurrentEntry; + if (BusHandler->InterfaceType == InterfaceType && + BusHandler->BusNumber == BusNumber) + { + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + return BusHandler; + } + CurrentEntry = CurrentEntry->Flink; + } + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + + return NULL; +} + + +PBUS_HANDLER FASTCALL +HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType, + ULONG BusNumber) +{ + PBUS_HANDLER BusHandler; + PLIST_ENTRY CurrentEntry; + KIRQL OldIrql; + + KeAcquireSpinLock(&HalpBusHandlerSpinLock, + &OldIrql); + + CurrentEntry = HalpBusHandlerList.Flink; + while (CurrentEntry != &HalpBusHandlerList) + { + BusHandler = (PBUS_HANDLER)CurrentEntry; + if (BusHandler->BusDataType == BusDataType && + BusHandler->BusNumber == BusNumber) + { + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + return BusHandler; + } + CurrentEntry = CurrentEntry->Flink; + } + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + + return NULL; +} + + +PBUS_HANDLER FASTCALL +HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType, + ULONG BusNumber) +{ + PBUS_HANDLER BusHandler; + PLIST_ENTRY CurrentEntry; + KIRQL OldIrql; + + KeAcquireSpinLock(&HalpBusHandlerSpinLock, + &OldIrql); + + CurrentEntry = HalpBusHandlerList.Flink; + while (CurrentEntry != &HalpBusHandlerList) + { + BusHandler = (PBUS_HANDLER)CurrentEntry; + if (BusHandler->InterfaceType == InterfaceType && + BusHandler->BusNumber == BusNumber) + { + BusHandler->RefCount++; + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + return BusHandler; + } + CurrentEntry = CurrentEntry->Flink; + } + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + + return NULL; +} + + +PBUS_HANDLER FASTCALL +HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType, + ULONG BusNumber) +{ + PBUS_HANDLER BusHandler; + PLIST_ENTRY CurrentEntry; + KIRQL OldIrql; + + KeAcquireSpinLock(&HalpBusHandlerSpinLock, + &OldIrql); + + CurrentEntry = HalpBusHandlerList.Flink; + while (CurrentEntry != &HalpBusHandlerList) + { + BusHandler = (PBUS_HANDLER)CurrentEntry; + if (BusHandler->BusDataType == BusDataType && + BusHandler->BusNumber == BusNumber) + { + BusHandler->RefCount++; + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + return BusHandler; + } + CurrentEntry = CurrentEntry->Flink; + } + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); + + return NULL; +} + + +VOID FASTCALL +HaliDereferenceBusHandler(PBUS_HANDLER BusHandler) +{ + KIRQL OldIrql; + + KeAcquireSpinLock(&HalpBusHandlerSpinLock, + &OldIrql); + BusHandler->RefCount--; + KeReleaseSpinLock(&HalpBusHandlerSpinLock, + OldIrql); +} + + +NTSTATUS STDCALL +HalAdjustResourceList(PCM_RESOURCE_LIST Resources) +{ + PBUS_HANDLER BusHandler; + NTSTATUS Status; + + BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType, + Resources->List[0].BusNumber); + if (BusHandler == NULL) + return STATUS_SUCCESS; + + Status = BusHandler->AdjustResourceList(BusHandler, + Resources->List[0].BusNumber, + Resources); + HaliDereferenceBusHandler (BusHandler); + + return Status; +} + + +NTSTATUS STDCALL +HalAssignSlotResources(PUNICODE_STRING RegistryPath, + PUNICODE_STRING DriverClassName, + PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT DeviceObject, + INTERFACE_TYPE BusType, + ULONG BusNumber, + ULONG SlotNumber, + PCM_RESOURCE_LIST *AllocatedResources) +{ + PBUS_HANDLER BusHandler; + NTSTATUS Status; + + BusHandler = HaliReferenceHandlerForBus(BusType, + BusNumber); + if (BusHandler == NULL) + return STATUS_NOT_FOUND; + + Status = BusHandler->AssignSlotResources(BusHandler, + BusNumber, + RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + SlotNumber, + AllocatedResources); + + HaliDereferenceBusHandler(BusHandler); + + return Status; +} + + +ULONG STDCALL +HalGetBusData(BUS_DATA_TYPE BusDataType, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Length) +{ + return (HalGetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + 0, + Length)); +} + + +ULONG STDCALL +HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + PBUS_HANDLER BusHandler; + ULONG Result; + + BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType, + BusNumber); + if (BusHandler == NULL) + return 0; + + Result = BusHandler->GetBusData(BusHandler, + BusNumber, + SlotNumber, + Buffer, + Offset, + Length); + + HaliDereferenceBusHandler (BusHandler); + + return Result; +} + + +ULONG STDCALL +HalGetInterruptVector(INTERFACE_TYPE InterfaceType, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity) +{ + PBUS_HANDLER BusHandler; + ULONG Result; + + BusHandler = HaliReferenceHandlerForBus(InterfaceType, + BusNumber); + if (BusHandler == NULL) + return 0; + + Result = BusHandler->GetInterruptVector(BusHandler, + BusNumber, + BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity); + + HaliDereferenceBusHandler(BusHandler); + + return Result; +} + + +ULONG STDCALL +HalSetBusData(BUS_DATA_TYPE BusDataType, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Length) +{ + return (HalSetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + 0, + Length)); +} + + +ULONG STDCALL +HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + PBUS_HANDLER BusHandler; + ULONG Result; + + BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType, + BusNumber); + if (BusHandler == NULL) + return 0; + + Result = BusHandler->SetBusData(BusHandler, + BusNumber, + SlotNumber, + Buffer, + Offset, + Length); + + HaliDereferenceBusHandler(BusHandler); + + return Result; +} + + +BOOLEAN STDCALL +HalTranslateBusAddress(INTERFACE_TYPE InterfaceType, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress) +{ + PBUS_HANDLER BusHandler; + BOOLEAN Result; + + BusHandler = HaliReferenceHandlerForBus(InterfaceType, + BusNumber); + if (BusHandler == NULL) + return FALSE; + + Result = (BOOLEAN)BusHandler->TranslateBusAddress(BusHandler, + BusNumber, + BusAddress, + AddressSpace, + TranslatedAddress); + + HaliDereferenceBusHandler(BusHandler); + + return Result; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/display.c b/reactos/hal/halppc/generic/display.c new file mode 100644 index 00000000000..1874de23331 --- /dev/null +++ b/reactos/hal/halppc/generic/display.c @@ -0,0 +1,796 @@ +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: display.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/display.c + * PURPOSE: Blue screen display + * PROGRAMMER: Eric Kohl (ekohl@rz-online.de) + * UPDATE HISTORY: + * Created 08/10/99 + */ + +/* + * Portions of this code are from the XFree86 Project and available from the + * following license: + * + * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. +*/ + +/* DISPLAY OWNERSHIP + * + * So, who owns the physical display and is allowed to write to it? + * + * In MS NT, upon boot HAL owns the display. Somewhere in the boot + * sequence (haven't figured out exactly where or by who), some + * component calls HalAcquireDisplayOwnership. From that moment on, + * the display is owned by that component and is switched to graphics + * mode. The display is not supposed to return to text mode, except + * in case of a bug check. The bug check will call HalDisplayString + * to output a string to the text screen. HAL will notice that it + * currently doesn't own the display and will re-take ownership, by + * calling the callback function passed to HalAcquireDisplayOwnership. + * After the bugcheck, execution is halted. So, under NT, the only + * possible sequence of display modes is text mode -> graphics mode -> + * text mode (the latter hopefully happening very infrequently). + * + * Things are a little bit different in the current state of ReactOS. + * We want to have a functional interactive text mode. We should be + * able to switch from text mode to graphics mode when a GUI app is + * started and switch back to text mode when it's finished. Then, when + * another GUI app is started, another switch to and from graphics mode + * is possible. Also, when the system bugchecks in graphics mode we want + * to switch back to text mode to show the registers and stack trace. + * Last but not least, HalDisplayString is used a lot more in ReactOS, + * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option + * is present. + * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS. + * As in NT, on boot HAL owns the display. When entering the text mode + * command interpreter, BLUE.SYS kicks in. It will write directly to the + * screen, more or less behind HALs back. + * When a GUI app is started, WIN32K.SYS will open the DISPLAY device. + * This open call will end up in VIDEOPRT.SYS. That component will then + * take ownership of the display by calling HalAcquireDisplayOwnership. + * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device), + * we want to give ownership of the display back to HAL. Using the + * standard exported HAL functions, that's a bit of a problem, because + * there is no function defined to do that. In NT, this is handled by + * HalDisplayString, but that solution isn't satisfactory in ReactOS, + * because HalDisplayString is (in some cases) also used to output debug + * messages. If we do it the NT way, the first debug message output while + * in graphics mode would switch the display back to text mode. + * So, instead, if HalDisplayString detects that HAL doesn't have ownership + * of the display, it doesn't do anything. + * To return ownership to HAL, a new function is exported, + * HalReleaseDisplayOwnership. This function is called by the DISPLAY + * device Close routine in VIDEOPRT.SYS. It is also called at the beginning + * of a bug check, so HalDisplayString is activated again. + * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS + * should also refrain from writing to the screen buffer. The text mode + * screen buffer might overlap the graphics mode screen buffer, so changing + * something in the text mode buffer might mess up the graphics screen. To + * allow BLUE.SYS to detect if HAL owns the display, another new function is + * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to + * check if it's allowed to touch the text mode buffer. + * + * In an ideal world, when HAL takes ownership of the display, it should set + * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10 + * calls. Unfortunately, this will require HAL to setup a real-mode interrupt + * table etc. So, we chickened out of that by having the loader set up the + * display before switching to protected mode. If HAL is given back ownership + * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS, + * since there is already support for them via the VideoPortInt10 routine. + */ + +#include +#define NDEBUG +#include + + +#define SCREEN_SYNCHRONIZATION + +#define VGA_GRAPH_MEM 0xa0000 +#define VGA_CHAR_MEM 0xb8000 +#define VGA_END_MEM 0xbffff + +#define VGA_AC_INDEX 0x3c0 +#define VGA_AC_READ 0x3c1 +#define VGA_AC_WRITE 0x3c0 + +#define VGA_MISC_WRITE 0x3c2 + +#define VGA_SEQ_INDEX 0x3c4 +#define VGA_SEQ_DATA 0x3c5 + +#define VGA_DAC_MASK 0x3c6 +#define VGA_DAC_READ_INDEX 0x3c7 +#define VGA_DAC_WRITE_INDEX 0x3c8 +#define VGA_DAC_DATA 0x3c9 +#define VGA_FEATURE_READ 0x3ca +#define VGA_MISC_READ 0x3cc + +#define VGA_GC_INDEX 0x3ce +#define VGA_GC_DATA 0x3cf + +#define VGA_CRTC_INDEX 0x3d4 +#define VGA_CRTC_DATA 0x3d5 + +#define VGA_INSTAT_READ 0x3da + +#define VGA_SEQ_NUM_REGISTERS 5 +#define VGA_CRTC_NUM_REGISTERS 25 +#define VGA_GC_NUM_REGISTERS 9 +#define VGA_AC_NUM_REGISTERS 21 + +#define CRTC_COLUMNS 0x01 +#define CRTC_OVERFLOW 0x07 +#define CRTC_ROWS 0x12 +#define CRTC_SCANLINES 0x09 + +#define CRTC_CURHI 0x0e +#define CRTC_CURLO 0x0f + + +#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */ +#define CHAR_ATTRIBUTE 0x17 /* grey on blue */ + +#define FONT_AMOUNT (8*8192) + +/* VARIABLES ****************************************************************/ + +static ULONG CursorX = 0; /* Cursor Position */ +static ULONG CursorY = 0; +static ULONG SizeX = 80; /* Display size */ +static ULONG SizeY = 25; + +static BOOLEAN DisplayInitialized = FALSE; +static BOOLEAN HalOwnsDisplay = TRUE; + +static PUSHORT VideoBuffer = NULL; +static PUCHAR GraphVideoBuffer = NULL; + +static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL; + +static UCHAR SavedTextPalette[768]; +static UCHAR SavedTextMiscOutReg; +static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS]; +static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS]; +static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS]; +static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS]; +static UCHAR SavedTextFont[2][FONT_AMOUNT]; +static BOOLEAN TextPaletteEnabled = FALSE; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID FASTCALL +HalClearDisplay (UCHAR CharAttribute) +{ + WORD *ptr = (WORD*)VideoBuffer; + ULONG i; + + for (i = 0; i < SizeX * SizeY; i++, ptr++) + *ptr = ((CharAttribute << 8) + ' '); + + CursorX = 0; + CursorY = 0; +} + + +/* STATIC FUNCTIONS *********************************************************/ + +VOID STATIC +HalScrollDisplay (VOID) +{ + PUSHORT ptr; + int i; + + ptr = VideoBuffer + SizeX; + RtlMoveMemory(VideoBuffer, + ptr, + SizeX * (SizeY - 1) * 2); + + ptr = VideoBuffer + (SizeX * (SizeY - 1)); + for (i = 0; i < (int)SizeX; i++, ptr++) + { + *ptr = (CHAR_ATTRIBUTE << 8) + ' '; + } +} + +VOID STATIC FASTCALL +HalPutCharacter (CHAR Character) +{ + PUSHORT ptr; + + ptr = VideoBuffer + ((CursorY * SizeX) + CursorX); + *ptr = (CHAR_ATTRIBUTE << 8) + Character; +} + +VOID STATIC +HalDisablePalette(VOID) +{ + (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); + WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20); + TextPaletteEnabled = FALSE; +} + +VOID STATIC +HalEnablePalette(VOID) +{ + (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); + WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00); + TextPaletteEnabled = TRUE; +} + +UCHAR STATIC FASTCALL +HalReadGc(ULONG Index) +{ + WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index); + return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA)); +} + +VOID STATIC FASTCALL +HalWriteGc(ULONG Index, UCHAR Value) +{ + WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index); + WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value); +} + +UCHAR STATIC FASTCALL +HalReadSeq(ULONG Index) +{ + WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index); + return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA)); +} + +VOID STATIC FASTCALL +HalWriteSeq(ULONG Index, UCHAR Value) +{ + WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index); + WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value); +} + +VOID STATIC FASTCALL +HalWriteAc(ULONG Index, UCHAR Value) +{ + if (TextPaletteEnabled) + { + Index &= ~0x20; + } + else + { + Index |= 0x20; + } + (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); + WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index); + WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value); +} + +UCHAR STATIC FASTCALL +HalReadAc(ULONG Index) +{ + if (TextPaletteEnabled) + { + Index &= ~0x20; + } + else + { + Index |= 0x20; + } + (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); + WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index); + return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ)); +} + +VOID STATIC FASTCALL +HalWriteCrtc(ULONG Index, UCHAR Value) +{ + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index); + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value); +} + +UCHAR STATIC FASTCALL +HalReadCrtc(ULONG Index) +{ + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index); + return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)); +} + +VOID STATIC FASTCALL +HalResetSeq(BOOLEAN Start) +{ + if (Start) + { + HalWriteSeq(0x00, 0x01); + } + else + { + HalWriteSeq(0x00, 0x03); + } +} + +VOID STATIC FASTCALL +HalBlankScreen(BOOLEAN On) +{ + UCHAR Scrn; + + Scrn = HalReadSeq(0x01); + + if (On) + { + Scrn &= ~0x20; + } + else + { + Scrn |= 0x20; + } + + HalResetSeq(TRUE); + HalWriteSeq(0x01, Scrn); + HalResetSeq(FALSE); +} + +VOID STATIC +HalSaveFont(VOID) +{ + UCHAR Attr10; + UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4; + ULONG i; + + /* Check if we are already in graphics mode. */ + Attr10 = HalReadAc(0x10); + if (Attr10 & 0x01) + { + return; + } + + /* Save registers. */ + MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ); + Gc4 = HalReadGc(0x04); + Gc5 = HalReadGc(0x05); + Gc6 = HalReadGc(0x06); + Seq2 = HalReadSeq(0x02); + Seq4 = HalReadSeq(0x04); + + /* Force colour mode. */ + WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01)); + + HalBlankScreen(FALSE); + + for (i = 0; i < 2; i++) + { + /* Save font 1 */ + HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */ + HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */ + HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */ + HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */ + HalWriteGc(0x06, 0x05); /* Set graphics. */ + memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT); + } + + /* Restore registers. */ + HalWriteAc(0x10, Attr10); + HalWriteSeq(0x02, Seq2); + HalWriteSeq(0x04, Seq4); + HalWriteGc(0x04, Gc4); + HalWriteGc(0x05, Gc5); + HalWriteGc(0x06, Gc6); + WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut); + + HalBlankScreen(TRUE); +} + +VOID STATIC +HalSaveMode(VOID) +{ + ULONG i; + + SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ); + + for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++) + { + SavedTextCrtcReg[i] = HalReadCrtc(i); + } + + HalEnablePalette(); + for (i = 0; i < VGA_AC_NUM_REGISTERS; i++) + { + SavedTextAcReg[i] = HalReadAc(i); + } + HalDisablePalette(); + + for (i = 0; i < VGA_GC_NUM_REGISTERS; i++) + { + SavedTextGcReg[i] = HalReadGc(i); + } + + for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++) + { + SavedTextSeqReg[i] = HalReadSeq(i); + } +} + +VOID STATIC +HalDacDelay(VOID) +{ + (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); + (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); +} + +VOID STATIC +HalSavePalette(VOID) +{ + ULONG i; + WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF); + WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00); + for (i = 0; i < 768; i++) + { + SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA); + HalDacDelay(); + } +} + +VOID STATIC +HalRestoreFont(VOID) +{ + UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8; + UCHAR Seq2, Seq4; + ULONG i; + + /* Save registers. */ + MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ); + Attr10 = HalReadAc(0x10); + Gc1 = HalReadGc(0x01); + Gc3 = HalReadGc(0x03); + Gc4 = HalReadGc(0x04); + Gc5 = HalReadGc(0x05); + Gc6 = HalReadGc(0x06); + Gc8 = HalReadGc(0x08); + Seq2 = HalReadSeq(0x02); + Seq4 = HalReadSeq(0x04); + + /* Force into colour mode. */ + WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10)); + + HalBlankScreen(FALSE); + + HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */ + HalWriteGc(0x08, 0xFF); /* Write all bits. */ + HalWriteGc(0x01, 0x00); /* All planes from CPU. */ + + for (i = 0; i < 2; i++) + { + HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */ + HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */ + HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */ + HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */ + HalWriteGc(0x06, 0x05); /* Set graphics. */ + memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT); + } + + HalBlankScreen(TRUE); + + /* Restore registers. */ + WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut); + HalWriteAc(0x10, Attr10); + HalWriteGc(0x01, Gc1); + HalWriteGc(0x03, Gc3); + HalWriteGc(0x04, Gc4); + HalWriteGc(0x05, Gc5); + HalWriteGc(0x06, Gc6); + HalWriteGc(0x08, Gc8); + HalWriteSeq(0x02, Seq2); + HalWriteSeq(0x04, Seq4); +} + +VOID STATIC +HalRestoreMode(VOID) +{ + ULONG i; + + WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg); + + for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++) + { + HalWriteSeq(i, SavedTextSeqReg[i]); + } + + /* Unlock CRTC registers 0-7 */ + HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80)); + + for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++) + { + HalWriteCrtc(i, SavedTextCrtcReg[i]); + } + + for (i = 0; i < VGA_GC_NUM_REGISTERS; i++) + { + HalWriteGc(i, SavedTextGcReg[i]); + } + + HalEnablePalette(); + for (i = 0; i < VGA_AC_NUM_REGISTERS; i++) + { + HalWriteAc(i, SavedTextAcReg[i]); + } + HalDisablePalette(); +} + +VOID STATIC +HalRestorePalette(VOID) +{ + ULONG i; + WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF); + WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00); + for (i = 0; i < 768; i++) + { + WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]); + HalDacDelay(); + } + HalDisablePalette(); +} + +/* PRIVATE FUNCTIONS ********************************************************/ + +VOID FASTCALL +HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock) +/* + * FUNCTION: Initalize the display + * ARGUMENTS: + * InitParameters = Parameters setup by the boot loader + */ +{ + PHYSICAL_ADDRESS PhysBuffer; + + if (! DisplayInitialized) + { + ULONG ScanLines; + ULONG Data; + + PhysBuffer.u.HighPart = 0; + PhysBuffer.u.LowPart = VGA_GRAPH_MEM; + GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached); + if (NULL == GraphVideoBuffer) + { + return; + } + VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM)); + + /* Set cursor position */ +// CursorX = LoaderBlock->cursorx; +// CursorY = LoaderBlock->cursory; + CursorX = 0; + CursorY = 0; + + /* read screen size from the crtc */ + /* FIXME: screen size should be read from the boot parameters */ + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS); + SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1; + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS); + SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA); + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW); + Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA); + SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3)); + SizeY++; + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES); + ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1; + SizeY = SizeY / ScanLines; + +#ifdef BOCHS_30ROWS + SizeY=30; +#endif + HalClearDisplay(CHAR_ATTRIBUTE_BLACK); + + DisplayInitialized = TRUE; + + /* + Save the VGA state at this point so we can restore it on a bugcheck. + */ + HalSavePalette(); + HalSaveMode(); + HalSaveFont(); + } +} + + +/* PUBLIC FUNCTIONS *********************************************************/ + +VOID STDCALL +HalReleaseDisplayOwnership(VOID) +/* + * FUNCTION: Release ownership of display back to HAL + */ +{ + if (HalResetDisplayParameters == NULL) + return; + + if (HalOwnsDisplay == TRUE) + return; + + if (!HalResetDisplayParameters(SizeX, SizeY)) + { + HalRestoreMode(); + HalRestoreFont(); + HalRestorePalette(); + } + HalOwnsDisplay = TRUE; + HalClearDisplay(CHAR_ATTRIBUTE); +} + + +VOID STDCALL +HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters) +/* + * FUNCTION: + * ARGUMENTS: + * ResetDisplayParameters = Pointer to a driver specific + * reset routine. + */ +{ + HalOwnsDisplay = FALSE; + HalResetDisplayParameters = ResetDisplayParameters; +} + +VOID STDCALL +HalDisplayString(IN PCH String) +/* + * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there + * already and displays a string + * ARGUMENT: + * string = ASCII string to display + * NOTE: Use with care because there is no support for returning from BSOD + * mode + */ +{ + PCH pch; +#ifdef SCREEN_SYNCHRONIZATION + int offset; +#endif + static KSPIN_LOCK Lock; + KIRQL OldIrql; + ULONG Flags; + + /* See comment at top of file */ + if (! HalOwnsDisplay || ! DisplayInitialized) + { + return; + } + + pch = String; + + OldIrql = KfRaiseIrql(HIGH_LEVEL); + KiAcquireSpinLock(&Lock); + + Ki386SaveFlags(Flags); + Ki386DisableInterrupts(); + +#ifdef SCREEN_SYNCHRONIZATION + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI); + offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8; + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO); + offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA); + + CursorY = offset / SizeX; + CursorX = offset % SizeX; +#endif + + while (*pch != 0) + { + if (*pch == '\n') + { + CursorY++; + CursorX = 0; + } + else if (*pch == '\b') + { + if (CursorX > 0) + { + CursorX--; + } + } + else if (*pch != '\r') + { + HalPutCharacter (*pch); + CursorX++; + + if (CursorX >= SizeX) + { + CursorY++; + CursorX = 0; + } + } + + if (CursorY >= SizeY) + { + HalScrollDisplay (); + CursorY = SizeY - 1; + } + + pch++; + } + +#ifdef SCREEN_SYNCHRONIZATION + offset = (CursorY * SizeX) + CursorX; + + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO); + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff)); + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI); + WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff)); +#endif + Ki386RestoreFlags(Flags); + + KiReleaseSpinLock(&Lock); + KfLowerIrql(OldIrql); +} + +VOID STDCALL +HalQueryDisplayParameters(OUT PULONG DispSizeX, + OUT PULONG DispSizeY, + OUT PULONG CursorPosX, + OUT PULONG CursorPosY) +{ + if (DispSizeX) + *DispSizeX = SizeX; + if (DispSizeY) + *DispSizeY = SizeY; + if (CursorPosX) + *CursorPosX = CursorX; + if (CursorPosY) + *CursorPosY = CursorY; +} + + +VOID STDCALL +HalSetDisplayParameters(IN ULONG CursorPosX, + IN ULONG CursorPosY) +{ + CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1; + CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1; +} + + +BOOLEAN STDCALL +HalQueryDisplayOwnership(VOID) +{ + return !HalOwnsDisplay; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/dma.c b/reactos/hal/halppc/generic/dma.c new file mode 100644 index 00000000000..a461d845004 --- /dev/null +++ b/reactos/hal/halppc/generic/dma.c @@ -0,0 +1,1950 @@ +/* $Id: dma.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/dma.c + * PURPOSE: DMA functions + * PROGRAMMERS: David Welch (welch@mcmail.com) + * Filip Navara (navaraf@reactos.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/** + * @page DMA Implementation Notes + * + * Concepts: + * + * - Map register + * + * Abstract encapsulation of physically contiguous buffer that resides + * in memory accessible by both the DMA device / controller and the system. + * The map registers are allocated and distributed on demand and are + * scarce resource. + * + * The actual use of map registers is to allow transfers from/to buffer + * located in physical memory at address inaccessible by the DMA device / + * controller directly. For such transfers the map register buffers + * are used as intermediate data storage. + * + * - Master adapter + * + * A container for map registers (typically corresponding to one physical + * bus connection type). There can be master adapters for 24-bit address + * ranges, 32-bit address ranges, etc. Every time a new DMA adapter is + * created it's associated with a corresponding master adapter that + * is used for any map register allocation requests. + * + * - Bus-master / Slave DMA + * + * Slave DMA is term used for DMA transfers done by the system (E)ISA + * controller as opposed to transfers mastered by the device itself + * (hence the name). + * + * For slave DMA special care is taken to actually access the system + * controller and handle the transfers. The relevant code is in + * HalpDmaInitializeEisaAdapter, HalReadDmaCounter, IoFlushAdapterBuffers + * and IoMapTransfer. + * + * Implementation: + * + * - Allocation of map registers + * + * Initial set of map registers is allocated on the system start to + * ensure that low memory won't get filled up later. Additional map + * registers are allocated as needed by HalpGrowMapBuffers. This + * routine is called on two places: + * + * - HalGetAdapter, since we're at PASSIVE_LEVEL and it's known that + * more map registers will probably be needed. + * - IoAllocateAdapterChannel (indirectly using HalpGrowMapBufferWorker + * since we're at DISPATCH_LEVEL and call HalpGrowMapBuffers directly) + * when no more map registers are free. + * + * Note that even if no more map registers can be allocated it's not + * the end of the world. The adapters waiting for free map registers + * are queued in the master adapter's queue and once one driver hands + * back it's map registers (using IoFreeMapRegisters or indirectly using + * the execution routine callback in IoAllocateAdapterChannel) the + * queue gets processed and the map registers are reassigned. + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +static KEVENT HalpDmaLock; +static LIST_ENTRY HalpDmaAdapterList; +static PADAPTER_OBJECT HalpEisaAdapter[8]; +static BOOLEAN HalpEisaDma; +static PADAPTER_OBJECT HalpMasterAdapter; + +static const ULONG_PTR HalpEisaPortPage[8] = { + FIELD_OFFSET(DMA_PAGE, Channel0), + FIELD_OFFSET(DMA_PAGE, Channel1), + FIELD_OFFSET(DMA_PAGE, Channel2), + FIELD_OFFSET(DMA_PAGE, Channel3), + 0, + FIELD_OFFSET(DMA_PAGE, Channel5), + FIELD_OFFSET(DMA_PAGE, Channel6), + FIELD_OFFSET(DMA_PAGE, Channel7) +}; + +static DMA_OPERATIONS HalpDmaOperations = { + sizeof(DMA_OPERATIONS), + (PPUT_DMA_ADAPTER)HalPutDmaAdapter, + (PALLOCATE_COMMON_BUFFER)HalAllocateCommonBuffer, + (PFREE_COMMON_BUFFER)HalFreeCommonBuffer, + NULL, /* Initialized in HalpInitDma() */ + NULL, /* Initialized in HalpInitDma() */ + NULL, /* Initialized in HalpInitDma() */ + NULL, /* Initialized in HalpInitDma() */ + NULL, /* Initialized in HalpInitDma() */ + (PGET_DMA_ALIGNMENT)HalpDmaGetDmaAlignment, + (PREAD_DMA_COUNTER)HalReadDmaCounter, + /* FIXME: Implement the S/G funtions. */ + NULL /*(PGET_SCATTER_GATHER_LIST)HalGetScatterGatherList*/, + NULL /*(PPUT_SCATTER_GATHER_LIST)HalPutScatterGatherList*/, + NULL /*(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize*/, + NULL /*(PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList*/, + NULL /*(PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList*/ +}; + +#define MAX_MAP_REGISTERS 64 + +#define TAG_DMA TAG('D','M','A',' ') + +/* FUNCTIONS *****************************************************************/ + +VOID +HalpInitDma(VOID) +{ + /* + * Initialize the DMA Operation table + */ + HalpDmaOperations.AllocateAdapterChannel = (PALLOCATE_ADAPTER_CHANNEL)IoAllocateAdapterChannel; + HalpDmaOperations.FlushAdapterBuffers = (PFLUSH_ADAPTER_BUFFERS)IoFlushAdapterBuffers; + HalpDmaOperations.FreeAdapterChannel = (PFREE_ADAPTER_CHANNEL)IoFreeAdapterChannel; + HalpDmaOperations.FreeMapRegisters = (PFREE_MAP_REGISTERS)IoFreeMapRegisters; + HalpDmaOperations.MapTransfer = (PMAP_TRANSFER)IoMapTransfer; + + /* + * Check if Extended DMA is available. We're just going to do a random + * read and write. + */ + + WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2), 0x2A); + if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)) == 0x2A) + HalpEisaDma = TRUE; + + /* + * Intialize all the global variables and allocate master adapter with + * first map buffers. + */ + + InitializeListHead(&HalpDmaAdapterList); + KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE); + + HalpMasterAdapter = HalpDmaAllocateMasterAdapter(); + + /* + * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's + * used by IoGetDmaAdapter in the kernel. + */ + + HalGetDmaAdapter = HalpGetDmaAdapter; +} + +/** + * @name HalpGetAdapterMaximumPhysicalAddress + * + * Get the maximum physical address acceptable by the device represented + * by the passed DMA adapter. + */ + +PHYSICAL_ADDRESS STDCALL +HalpGetAdapterMaximumPhysicalAddress( + IN PADAPTER_OBJECT AdapterObject) +{ + PHYSICAL_ADDRESS HighestAddress; + + if (AdapterObject->MasterDevice) + { + if (AdapterObject->Dma64BitAddresses) + { + HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL; + return HighestAddress; + } + else if (AdapterObject->Dma32BitAddresses) + { + HighestAddress.QuadPart = 0xFFFFFFFF; + return HighestAddress; + } + } + + HighestAddress.QuadPart = 0xFFFFFF; + return HighestAddress; +} + +/** + * @name HalpGrowMapBuffers + * + * Allocate initial, or additional, map buffers for DMA master adapter. + * + * @param MasterAdapter + * DMA master adapter to allocate buffers for. + * @param SizeOfMapBuffers + * Size of the map buffers to allocate (not including the size + * already allocated). + */ + +BOOLEAN STDCALL +HalpGrowMapBuffers( + IN PADAPTER_OBJECT AdapterObject, + IN ULONG SizeOfMapBuffers) +{ + PVOID VirtualAddress; + PHYSICAL_ADDRESS PhysicalAddress; + PHYSICAL_ADDRESS HighestAcceptableAddress; + PHYSICAL_ADDRESS LowestAcceptableAddress; + PHYSICAL_ADDRESS BoundryAddressMultiple; + KIRQL OldIrql; + ULONG MapRegisterCount; + + /* FIXME: Check if enough map register slots are available. */ + + MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers); + + /* + * Allocate memory for the new map registers. For 32-bit adapters we use + * two passes in order not to waste scare resource (low memory). + */ + + HighestAcceptableAddress = + HalpGetAdapterMaximumPhysicalAddress(AdapterObject); + LowestAcceptableAddress.HighPart = 0; + LowestAcceptableAddress.LowPart = + HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0; + BoundryAddressMultiple.QuadPart = 0; + + VirtualAddress = MmAllocateContiguousMemorySpecifyCache( + MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress, + HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached); + + if (VirtualAddress == NULL && LowestAcceptableAddress.LowPart != 0) + { + LowestAcceptableAddress.LowPart = 0; + VirtualAddress = MmAllocateContiguousMemorySpecifyCache( + MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress, + HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached); + } + + if (VirtualAddress == NULL) + return FALSE; + + PhysicalAddress = MmGetPhysicalAddress(VirtualAddress); + + /* + * All the following must be done with the master adapter lock held + * to prevent corruption. + */ + + OldIrql = KfAcquireSpinLock(&AdapterObject->SpinLock); + + /* + * Setup map register entries for the buffer allocated. Each entry has + * a virtual and physical address and corresponds to PAGE_SIZE large + * buffer. + */ + + if (MapRegisterCount > 0) + { + PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry; + + CurrentEntry = AdapterObject->MapRegisterBase + + AdapterObject->NumberOfMapRegisters; + do + { + /* + * Leave one entry free for every non-contiguous memory region + * in the map register bitmap. This ensures that we can search + * using RtlFindClearBits for contiguous map register regions. + * + * Also for non-EISA DMA leave one free entry for every 64Kb + * break, because the DMA controller can handle only coniguous + * 64Kb regions. + */ + + if (CurrentEntry != AdapterObject->MapRegisterBase) + { + PreviousEntry = CurrentEntry - 1; + if (PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE == + PhysicalAddress.LowPart) + { + if (!HalpEisaDma) + { + if ((PreviousEntry->PhysicalAddress.LowPart ^ + PhysicalAddress.LowPart) & 0xFFFF0000) + { + CurrentEntry++; + AdapterObject->NumberOfMapRegisters++; + } + } + } + else + { + CurrentEntry++; + AdapterObject->NumberOfMapRegisters++; + } + } + + RtlClearBit(AdapterObject->MapRegisters, + CurrentEntry - AdapterObject->MapRegisterBase); + CurrentEntry->VirtualAddress = VirtualAddress; + CurrentEntry->PhysicalAddress = PhysicalAddress; + + PhysicalAddress.LowPart += PAGE_SIZE; + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); + + CurrentEntry++; + AdapterObject->NumberOfMapRegisters++; + MapRegisterCount--; + } + while (MapRegisterCount != 0); + } + + KfReleaseSpinLock(&AdapterObject->SpinLock, OldIrql); + + return TRUE; +} + +/** + * @name HalpDmaAllocateMasterAdapter + * + * Helper routine to allocate and initialize master adapter object and it's + * associated map register buffers. + * + * @see HalpInitDma + */ + +PADAPTER_OBJECT STDCALL +HalpDmaAllocateMasterAdapter(VOID) +{ + PADAPTER_OBJECT MasterAdapter; + ULONG Size, SizeOfBitmap; + + SizeOfBitmap = MAX_MAP_REGISTERS; + Size = sizeof(ADAPTER_OBJECT); + Size += sizeof(RTL_BITMAP); + Size += (SizeOfBitmap + 7) >> 3; + + MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA); + if (MasterAdapter == NULL) + return NULL; + + RtlZeroMemory(MasterAdapter, Size); + + KeInitializeSpinLock(&MasterAdapter->SpinLock); + InitializeListHead(&MasterAdapter->AdapterQueue); + + MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1); + RtlInitializeBitMap( + MasterAdapter->MapRegisters, + (PULONG)(MasterAdapter->MapRegisters + 1), + SizeOfBitmap); + RtlSetAllBits(MasterAdapter->MapRegisters); + MasterAdapter->NumberOfMapRegisters = 0; + MasterAdapter->CommittedMapRegisters = 0; + + MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag( + NonPagedPool, + SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY), + TAG_DMA); + if (MasterAdapter->MapRegisterBase == NULL) + { + ExFreePool(MasterAdapter); + return NULL; + } + + RtlZeroMemory(MasterAdapter->MapRegisterBase, + SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY)); + if (!HalpGrowMapBuffers(MasterAdapter, 0x10000)) + { + ExFreePool(MasterAdapter); + return NULL; + } + + return MasterAdapter; +} + +/** + * @name HalpDmaAllocateChildAdapter + * + * Helper routine of HalGetAdapter. Allocate child adapter object and + * fill out some basic fields. + * + * @see HalGetAdapter + */ + +PADAPTER_OBJECT STDCALL +HalpDmaAllocateChildAdapter( + ULONG NumberOfMapRegisters, + PDEVICE_DESCRIPTION DeviceDescription) +{ + PADAPTER_OBJECT AdapterObject; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + HANDLE Handle; + + InitializeObjectAttributes( + &ObjectAttributes, + NULL, + OBJ_KERNEL_HANDLE | OBJ_PERMANENT, + NULL, + NULL); + + Status = ObCreateObject( + KernelMode, + IoAdapterObjectType, + &ObjectAttributes, + KernelMode, + NULL, + sizeof(ADAPTER_OBJECT), + 0, + 0, + (PVOID)&AdapterObject); + if (!NT_SUCCESS(Status)) + return NULL; + + Status = ObReferenceObjectByPointer( + AdapterObject, + FILE_READ_DATA | FILE_WRITE_DATA, + IoAdapterObjectType, + KernelMode); + if (!NT_SUCCESS(Status)) + return NULL; + + RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT)); + + Status = ObInsertObject( + AdapterObject, + NULL, + FILE_READ_DATA | FILE_WRITE_DATA, + 0, + NULL, + &Handle); + if (!NT_SUCCESS(Status)) + return NULL; + + ZwClose(Handle); + + AdapterObject->DmaHeader.Version = DeviceDescription->Version; + AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT); + AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations; + AdapterObject->MapRegistersPerChannel = 1; + AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses; + AdapterObject->ChannelNumber = 0xFF; + AdapterObject->MasterAdapter = HalpMasterAdapter; + KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue); + + return AdapterObject; +} + +/** + * @name HalpDmaInitializeEisaAdapter + * + * Setup DMA modes and extended modes for (E)ISA DMA adapter object. + */ + +BOOLEAN STDCALL +HalpDmaInitializeEisaAdapter( + PADAPTER_OBJECT AdapterObject, + PDEVICE_DESCRIPTION DeviceDescription) +{ + UCHAR Controller; + DMA_MODE DmaMode = {{0 }}; + DMA_EXTENDED_MODE ExtendedMode = {{ 0 }}; + PVOID AdapterBaseVa; + + Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1; + + if (Controller == 1) + AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1); + else + AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2); + + AdapterObject->AdapterNumber = Controller; + AdapterObject->ChannelNumber = DeviceDescription->DmaChannel & 3; + AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel]; + AdapterObject->Width16Bits = FALSE; + AdapterObject->AdapterBaseVa = AdapterBaseVa; + + if (HalpEisaDma) + { + ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber; + + switch (DeviceDescription->DmaSpeed) + { + case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break; + case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break; + case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break; + case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break; + default: + return FALSE; + } + + switch (DeviceDescription->DmaWidth) + { + case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break; + case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break; + case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break; + default: + return FALSE; + } + + if (Controller == 1) + WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1), + ExtendedMode.Byte); + else + WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2), + ExtendedMode.Byte); + } + else + { + /* + * Validate setup for non-busmaster DMA adapter. Secondary controller + * supports only 16-bit transfers and main controller supports only + * 8-bit transfers. Anything else is invalid. + */ + + if (!DeviceDescription->Master) + { + if (Controller == 2 && DeviceDescription->DmaWidth == Width16Bits) + AdapterObject->Width16Bits = TRUE; + else if (Controller != 1 || DeviceDescription->DmaWidth != Width8Bits) + return FALSE; + } + } + + DmaMode.Channel = AdapterObject->ChannelNumber; + DmaMode.AutoInitialize = DeviceDescription->AutoInitialize; + + /* + * Set the DMA request mode. + * + * For (E)ISA bus master devices just unmask (enable) the DMA channel + * and set it to cascade mode. Otherwise just select the right one + * bases on the passed device description. + */ + + if (DeviceDescription->Master) + { + DmaMode.RequestMode = CASCADE_REQUEST_MODE; + if (Controller == 1) + { + /* Set the Request Data */ + WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode, + DmaMode.Byte); + /* Unmask DMA Channel */ + WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask, + AdapterObject->ChannelNumber | DMA_CLEARMASK); + } else { + /* Set the Request Data */ + WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode, + DmaMode.Byte); + /* Unmask DMA Channel */ + WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask, + AdapterObject->ChannelNumber | DMA_CLEARMASK); + } + } + else + { + if (DeviceDescription->DemandMode) + DmaMode.RequestMode = DEMAND_REQUEST_MODE; + else + DmaMode.RequestMode = SINGLE_REQUEST_MODE; + } + + AdapterObject->AdapterMode = DmaMode; + + return TRUE; +} + +/** + * @name HalGetAdapter + * + * Allocate an adapter object for DMA device. + * + * @param DeviceDescription + * Structure describing the attributes of the device. + * @param NumberOfMapRegisters + * On return filled with the maximum number of map registers the + * device driver can allocate for DMA transfer operations. + * + * @return The DMA adapter on success, NULL otherwise. + * + * @implemented + */ + +PADAPTER_OBJECT STDCALL +HalGetAdapter( + PDEVICE_DESCRIPTION DeviceDescription, + PULONG NumberOfMapRegisters) +{ + PADAPTER_OBJECT AdapterObject = NULL; + PADAPTER_OBJECT MasterAdapter; + BOOLEAN EisaAdapter; + ULONG MapRegisters; + ULONG MaximumLength; + + /* Validate parameters in device description */ + if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION2) + return NULL; + + /* + * See if we're going to use ISA/EISA DMA adapter. These adapters are + * special since they're reused. + * + * Also note that we check for channel number since there are only 8 DMA + * channels on ISA, so any request above this requires new adapter. + */ + + if (DeviceDescription->InterfaceType == Isa || !DeviceDescription->Master) + { + if (DeviceDescription->InterfaceType == Isa && + DeviceDescription->DmaChannel >= 8) + EisaAdapter = FALSE; + else + EisaAdapter = TRUE; + } + else + { + EisaAdapter = FALSE; + } + + /* + * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used + * for cascading the controllers and it's not available for software use. + */ + + if (EisaAdapter && DeviceDescription->DmaChannel == 4) + return NULL; + + /* + * Calculate the number of map registers. + * + * - For EISA and PCI scatter/gather no map registers are needed. + * - For ISA slave scatter/gather one map register is needed. + * - For all other cases the number of map registers depends on + * DeviceDescription->MaximumLength. + */ + + MaximumLength = DeviceDescription->MaximumLength & MAXLONG; + if (DeviceDescription->ScatterGather && + (DeviceDescription->InterfaceType == Eisa || + DeviceDescription->InterfaceType == PCIBus)) + { + MapRegisters = 0; + } + else if (DeviceDescription->ScatterGather && + !DeviceDescription->Master) + { + MapRegisters = 1; + } + else + { + /* + * In the equation below the additional map register added by + * the "+1" accounts for the case when a transfer does not start + * at a page-aligned address. + */ + MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1; + if (MapRegisters > 16) + MapRegisters = 16; + } + + /* + * Acquire the DMA lock that is used to protect adapter lists and + * EISA adapter array. + */ + + KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode, + FALSE, NULL); + + /* + * Now we must get ahold of the adapter object. For first eight ISA/EISA + * channels there are static adapter objects that are reused and updated + * on succesive HalGetAdapter calls. In other cases a new adapter object + * is always created and it's to the DMA adapter list (HalpDmaAdapterList). + */ + + if (EisaAdapter) + { + AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel]; + if (AdapterObject != NULL) + { + if (AdapterObject->NeedsMapRegisters && + MapRegisters > AdapterObject->MapRegistersPerChannel) + AdapterObject->MapRegistersPerChannel = MapRegisters; + } + } + + if (AdapterObject == NULL) + { + AdapterObject = HalpDmaAllocateChildAdapter( + MapRegisters, DeviceDescription); + if (AdapterObject == NULL) + { + KeSetEvent(&HalpDmaLock, 0, 0); + return NULL; + } + + if (EisaAdapter) + { + HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject; + } + + if (MapRegisters > 0) + { + AdapterObject->NeedsMapRegisters = TRUE; + MasterAdapter = HalpMasterAdapter; + AdapterObject->MapRegistersPerChannel = MapRegisters; + + /* + * FIXME: Verify that the following makes sense. Actually + * MasterAdapter->NumberOfMapRegisters contains even the number + * of gaps, so this will not work correctly all the time. It + * doesn't matter much since it's only optimization to avoid + * queuing work items in HalAllocateAdapterChannel. + */ + + MasterAdapter->CommittedMapRegisters += MapRegisters; + if (MasterAdapter->CommittedMapRegisters > MasterAdapter->NumberOfMapRegisters) + HalpGrowMapBuffers(MasterAdapter, 0x10000); + } + else + { + AdapterObject->NeedsMapRegisters = FALSE; + if (DeviceDescription->Master) + AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1; + else + AdapterObject->MapRegistersPerChannel = 1; + } + } + + if (!EisaAdapter) + InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList); + + /* + * Release the DMA lock. HalpDmaAdapterList and HalpEisaAdapter will + * no longer be touched, so we don't need it. + */ + + KeSetEvent(&HalpDmaLock, 0, 0); + + /* + * Setup the values in the adapter object that are common for all + * types of buses. + */ + + if (DeviceDescription->Version >= DEVICE_DESCRIPTION_VERSION1) + AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount; + else + AdapterObject->IgnoreCount = 0; + + AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses; + AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses; + AdapterObject->ScatterGather = DeviceDescription->ScatterGather; + AdapterObject->MasterDevice = DeviceDescription->Master; + *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel; + + /* + * For non-(E)ISA adapters we have already done all the work. On the + * other hand for (E)ISA adapters we must still setup the DMA modes + * and prepare the controller. + */ + + if (EisaAdapter) + { + if (!HalpDmaInitializeEisaAdapter(AdapterObject, DeviceDescription)) + { + ObfDereferenceObject(AdapterObject); + return NULL; + } + } + + return AdapterObject; +} + +/** + * @name HalpGetDmaAdapter + * + * Internal routine to allocate PnP DMA adapter object. It's exported through + * HalDispatchTable and used by IoGetDmaAdapter. + * + * @see HalGetAdapter + */ + +PDMA_ADAPTER STDCALL +HalpGetDmaAdapter( + IN PVOID Context, + IN PDEVICE_DESCRIPTION DeviceDescription, + OUT PULONG NumberOfMapRegisters) +{ + return &HalGetAdapter(DeviceDescription, NumberOfMapRegisters)->DmaHeader; +} + +/** + * @name HalPutDmaAdapter + * + * Internal routine to free DMA adapter and resources for reuse. It's exported + * using the DMA_OPERATIONS interface by HalGetAdapter. + * + * @see HalGetAdapter + */ + +VOID STDCALL +HalPutDmaAdapter( + PADAPTER_OBJECT AdapterObject) +{ + if (AdapterObject->ChannelNumber == 0xFF) + { + KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode, + FALSE, NULL); + RemoveEntryList(&AdapterObject->AdapterList); + KeSetEvent(&HalpDmaLock, 0, 0); + } + + ObfDereferenceObject(AdapterObject); +} + +/** + * @name HalAllocateCommonBuffer + * + * Allocates memory that is visible to both the processor(s) and the DMA + * device. + * + * @param AdapterObject + * Adapter object representing the bus master or system dma controller. + * @param Length + * Number of bytes to allocate. + * @param LogicalAddress + * Logical address the driver can use to access the buffer. + * @param CacheEnabled + * Specifies if the memory can be cached. + * + * @return The base virtual address of the memory allocated or NULL on failure. + * + * @remarks + * On real NT x86 systems the CacheEnabled parameter is ignored, we honour + * it. If it proves to cause problems change it. + * + * @see HalFreeCommonBuffer + * + * @implemented + */ + +PVOID STDCALL +HalAllocateCommonBuffer( + PADAPTER_OBJECT AdapterObject, + ULONG Length, + PPHYSICAL_ADDRESS LogicalAddress, + BOOLEAN CacheEnabled) +{ + PHYSICAL_ADDRESS LowestAcceptableAddress; + PHYSICAL_ADDRESS HighestAcceptableAddress; + PHYSICAL_ADDRESS BoundryAddressMultiple; + PVOID VirtualAddress; + + LowestAcceptableAddress.QuadPart = 0; + HighestAcceptableAddress = + HalpGetAdapterMaximumPhysicalAddress(AdapterObject); + BoundryAddressMultiple.QuadPart = 0; + + /* + * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For + * slave DMA devices the 64Kb boundary mustn't be crossed since the + * controller wouldn't be able to handle it. + */ + + if (AdapterObject->MasterDevice) + BoundryAddressMultiple.HighPart = 1; + else + BoundryAddressMultiple.LowPart = 0x10000; + + VirtualAddress = MmAllocateContiguousMemorySpecifyCache( + Length, LowestAcceptableAddress, HighestAcceptableAddress, + BoundryAddressMultiple, CacheEnabled ? MmCached : MmNonCached); + if (VirtualAddress == NULL) + return NULL; + + *LogicalAddress = MmGetPhysicalAddress(VirtualAddress); + + return VirtualAddress; +} + +/** + * @name HalFreeCommonBuffer + * + * Free common buffer allocated with HalAllocateCommonBuffer. + * + * @see HalAllocateCommonBuffer + * + * @implemented + */ + +VOID STDCALL +HalFreeCommonBuffer( + PADAPTER_OBJECT AdapterObject, + ULONG Length, + PHYSICAL_ADDRESS LogicalAddress, + PVOID VirtualAddress, + BOOLEAN CacheEnabled) +{ + MmFreeContiguousMemory(VirtualAddress); +} + +/** + * @name HalpDmaGetDmaAlignment + * + * Internal routine to return the DMA alignment requirement. It's exported + * using the DMA_OPERATIONS interface by HalGetAdapter. + * + * @see HalGetAdapter + */ + +ULONG STDCALL +HalpDmaGetDmaAlignment( + PADAPTER_OBJECT AdapterObject) +{ + return 1; +} + +/* + * @name HalReadDmaCounter + * + * Read DMA operation progress counter. + * + * @implemented + */ + +ULONG STDCALL +HalReadDmaCounter( + PADAPTER_OBJECT AdapterObject) +{ + KIRQL OldIrql; + ULONG Count, OldCount; + + ASSERT(!AdapterObject->MasterDevice); + + /* + * Acquire the master adapter lock since we're going to mess with the + * system DMA controller registers and we really don't want anyone + * to do the same at the same time. + */ + + KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql); + + /* Send the request to the specific controller. */ + if (AdapterObject->AdapterNumber == 1) + { + PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; + + Count = 0xffff00; + do + { + OldCount = Count; + /* Send Reset */ + WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0); + /* Read Count */ + Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount + [AdapterObject->ChannelNumber].DmaBaseCount); + Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount + [AdapterObject->ChannelNumber].DmaBaseCount) << 8; + } + while (0xffff00 & (OldCount ^ Count)); + } + else + { + PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; + + Count = 0xffff00; + do + { + OldCount = Count; + /* Send Reset */ + WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0); + /* Read Count */ + Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount + [AdapterObject->ChannelNumber].DmaBaseCount); + Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount + [AdapterObject->ChannelNumber].DmaBaseCount) << 8; + } + while (0xffff00 & (OldCount ^ Count)); + } + + KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql); + + Count++; + Count &= 0xffff; + if (AdapterObject->Width16Bits) + Count *= 2; + + return Count; +} + +/** + * @name HalpGrowMapBufferWorker + * + * Helper routine of HalAllocateAdapterChannel for allocating map registers + * at PASSIVE_LEVEL in work item. + */ + +VOID STDCALL +HalpGrowMapBufferWorker(PVOID DeferredContext) +{ + PGROW_WORK_ITEM WorkItem = (PGROW_WORK_ITEM)DeferredContext; + KIRQL OldIrql; + BOOLEAN Succeeded; + + /* + * Try to allocate new map registers for the adapter. + * + * NOTE: The NT implementation actually tries to allocate more map + * registers than needed as an optimization. + */ + + KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode, + FALSE, NULL); + Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter, + WorkItem->NumberOfMapRegisters); + KeSetEvent(&HalpDmaLock, 0, 0); + + if (Succeeded) + { + /* + * Flush the adapter queue now that new map registers are ready. The + * easiest way to do that is to call IoFreeMapRegisters to not free + * any registers. Note that we use the magic (PVOID)2 map register + * base to bypass the parameter checking. + */ + + OldIrql = KfRaiseIrql(DISPATCH_LEVEL); + IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0); + KfLowerIrql(OldIrql); + } + + ExFreePool(WorkItem); +} + +/** + * @name HalAllocateAdapterChannel + * + * Setup map registers for an adapter object. + * + * @param AdapterObject + * Pointer to an ADAPTER_OBJECT to set up. + * @param WaitContextBlock + * Context block to be used with ExecutionRoutine. + * @param NumberOfMapRegisters + * Number of map registers requested. + * @param ExecutionRoutine + * Callback to call when map registers are allocated. + * + * @return + * If not enough map registers can be allocated then + * STATUS_INSUFFICIENT_RESOURCES is returned. If the function + * succeeds or the callback is queued for later delivering then + * STATUS_SUCCESS is returned. + * + * @see IoFreeAdapterChannel + * + * @implemented + */ + +NTSTATUS STDCALL +HalAllocateAdapterChannel( + PADAPTER_OBJECT AdapterObject, + PWAIT_CONTEXT_BLOCK WaitContextBlock, + ULONG NumberOfMapRegisters, + PDRIVER_CONTROL ExecutionRoutine) +{ + PADAPTER_OBJECT MasterAdapter; + PGROW_WORK_ITEM WorkItem; + ULONG Index = ~0; + ULONG Result; + KIRQL OldIrql; + + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + /* Set up the wait context block in case we can't run right away. */ + WaitContextBlock->DeviceRoutine = ExecutionRoutine; + WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters; + + /* Returns true if queued, else returns false and sets the queue to busy */ + if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry)) + return STATUS_SUCCESS; + + MasterAdapter = AdapterObject->MasterAdapter; + + AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters; + AdapterObject->CurrentWcb = WaitContextBlock; + + if (NumberOfMapRegisters && AdapterObject->NeedsMapRegisters) + { + if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) + { + AdapterObject->NumberOfMapRegisters = 0; + IoFreeAdapterChannel(AdapterObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* + * Get the map registers. This is partly complicated by the fact + * that new map registers can only be allocated at PASSIVE_LEVEL + * and we're currently at DISPATCH_LEVEL. The following code has + * two code paths: + * + * - If there is no adapter queued for map register allocation, + * try to see if enough contiguous map registers are present. + * In case they're we can just get them and proceed further. + * + * - If some adapter is already present in the queue we must + * respect the order of adapters asking for map registers and + * so the fast case described above can't take place. + * This case is also entered if not enough coniguous map + * registers are present. + * + * A work queue item is allocated and queued, the adapter is + * also queued into the master adapter queue. The worker + * routine does the job of allocating the map registers at + * PASSIVE_LEVEL and calling the ExecutionRoutine. + */ + + OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock); + + if (IsListEmpty(&MasterAdapter->AdapterQueue)) + { + Index = RtlFindClearBitsAndSet( + MasterAdapter->MapRegisters, NumberOfMapRegisters, 0); + if (Index != ~0) + { + AdapterObject->MapRegisterBase = + MasterAdapter->MapRegisterBase + Index; + if (!AdapterObject->ScatterGather) + { + AdapterObject->MapRegisterBase = + (PROS_MAP_REGISTER_ENTRY)( + (ULONG_PTR)AdapterObject->MapRegisterBase | + MAP_BASE_SW_SG); + } + } + } + + if (Index == ~0) + { + WorkItem = ExAllocatePoolWithTag( + NonPagedPool, sizeof(GROW_WORK_ITEM), TAG_DMA); + if (WorkItem == NULL) + { + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + AdapterObject->NumberOfMapRegisters = 0; + IoFreeAdapterChannel(AdapterObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue); + + ExInitializeWorkItem( + &WorkItem->WorkQueueItem, HalpGrowMapBufferWorker, WorkItem); + WorkItem->AdapterObject = AdapterObject; + WorkItem->NumberOfMapRegisters = NumberOfMapRegisters; + + ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue); + + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + + return STATUS_SUCCESS; + } + + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + } + else + { + AdapterObject->MapRegisterBase = NULL; + AdapterObject->NumberOfMapRegisters = 0; + } + + AdapterObject->CurrentWcb = WaitContextBlock; + + Result = ExecutionRoutine( + WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp, + AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext); + + /* + * Possible return values: + * + * - KeepObject + * Don't free any resources, the ADAPTER_OBJECT is still in use and + * the caller will call IoFreeAdapterChannel later. + * + * - DeallocateObject + * Deallocate the map registers and release the ADAPTER_OBJECT, so + * someone else can use it. + * + * - DeallocateObjectKeepRegisters + * Release the ADAPTER_OBJECT, but hang on to the map registers. The + * client will later call IoFreeMapRegisters. + * + * NOTE: + * IoFreeAdapterChannel runs the queue, so it must be called unless + * the adapter object is not to be freed. + */ + + if (Result == DeallocateObject) + { + IoFreeAdapterChannel(AdapterObject); + } + else if (Result == DeallocateObjectKeepRegisters) + { + AdapterObject->NumberOfMapRegisters = 0; + IoFreeAdapterChannel(AdapterObject); + } + + return STATUS_SUCCESS; +} + +/** + * @name IoFreeAdapterChannel + * + * Free DMA resources allocated by IoAllocateAdapterChannel. + * + * @param AdapterObject + * Adapter object with resources to free. + * + * @remarks + * This function releases map registers registers assigned to the DMA + * adapter. After releasing the adapter, it checks the adapter's queue + * and runs each queued device object in series until the queue is + * empty. This is the only way the device queue is emptied. + * + * @see IoAllocateAdapterChannel + * + * @implemented + */ + +VOID STDCALL +IoFreeAdapterChannel( + PADAPTER_OBJECT AdapterObject) +{ + PADAPTER_OBJECT MasterAdapter; + PKDEVICE_QUEUE_ENTRY DeviceQueueEntry; + PWAIT_CONTEXT_BLOCK WaitContextBlock; + ULONG Index = ~0; + ULONG Result; + KIRQL OldIrql; + + MasterAdapter = AdapterObject->MasterAdapter; + + for (;;) + { + /* + * To keep map registers, call here with AdapterObject-> + * NumberOfMapRegisters set to zero. This trick is used in + * HalAllocateAdapterChannel for example. + */ + if (AdapterObject->NumberOfMapRegisters) + { + IoFreeMapRegisters( + AdapterObject, + AdapterObject->MapRegisterBase, + AdapterObject->NumberOfMapRegisters); + } + + DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue); + if (DeviceQueueEntry == NULL) + { + break; + } + + WaitContextBlock = CONTAINING_RECORD( + DeviceQueueEntry, + WAIT_CONTEXT_BLOCK, + WaitQueueEntry); + + AdapterObject->CurrentWcb = WaitContextBlock; + AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters; + + if (WaitContextBlock->NumberOfMapRegisters && + AdapterObject->MasterAdapter) + { + OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock); + + if (IsListEmpty(&MasterAdapter->AdapterQueue)) + { + Index = RtlFindClearBitsAndSet( + MasterAdapter->MapRegisters, + WaitContextBlock->NumberOfMapRegisters, 0); + if (Index != ~0) + { + AdapterObject->MapRegisterBase = + MasterAdapter->MapRegisterBase + Index; + if (!AdapterObject->ScatterGather) + { + AdapterObject->MapRegisterBase = + (PROS_MAP_REGISTER_ENTRY)( + (ULONG_PTR)AdapterObject->MapRegisterBase | + MAP_BASE_SW_SG); + } + } + } + + if (Index == ~0) + { + InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue); + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + break; + } + + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + } + else + { + AdapterObject->MapRegisterBase = NULL; + AdapterObject->NumberOfMapRegisters = 0; + } + + /* Call the adapter control routine. */ + Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)( + WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp, + AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext); + + switch (Result) + { + case KeepObject: + /* + * We're done until the caller manually calls IoFreeAdapterChannel + * or IoFreeMapRegisters. + */ + return; + + case DeallocateObjectKeepRegisters: + /* + * Hide the map registers so they aren't deallocated next time + * around. + */ + AdapterObject->NumberOfMapRegisters = 0; + break; + + default: + break; + } + } +} + +/** + * @name IoFreeMapRegisters + * + * Free map registers reserved by the system for a DMA. + * + * @param AdapterObject + * DMA adapter to free map registers on. + * @param MapRegisterBase + * Handle to map registers to free. + * @param NumberOfRegisters + * Number of map registers to be freed. + * + * @implemented + */ + +VOID STDCALL +IoFreeMapRegisters( + IN PADAPTER_OBJECT AdapterObject, + IN PVOID MapRegisterBase, + IN ULONG NumberOfMapRegisters) +{ + PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter; + PLIST_ENTRY ListEntry; + KIRQL OldIrql; + ULONG Index; + ULONG Result; + + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + if (MasterAdapter == NULL || MapRegisterBase == NULL) + return; + + OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock); + + if (NumberOfMapRegisters != 0) + { + PROS_MAP_REGISTER_ENTRY RealMapRegisterBase; + + RealMapRegisterBase = + (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG); + RtlClearBits(MasterAdapter->MapRegisters, + RealMapRegisterBase - MasterAdapter->MapRegisterBase, + NumberOfMapRegisters); + } + + /* + * Now that we freed few map registers it's time to look at the master + * adapter queue and see if there is someone waiting for map registers. + */ + + while (!IsListEmpty(&MasterAdapter->AdapterQueue)) + { + ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue); + AdapterObject = CONTAINING_RECORD( + ListEntry, struct _ADAPTER_OBJECT, AdapterQueue); + + Index = RtlFindClearBitsAndSet( + MasterAdapter->MapRegisters, + AdapterObject->NumberOfMapRegisters, + MasterAdapter->NumberOfMapRegisters); + if (Index == ~0) + { + InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry); + break; + } + + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + + AdapterObject->MapRegisterBase = + MasterAdapter->MapRegisterBase + Index; + if (!AdapterObject->ScatterGather) + { + AdapterObject->MapRegisterBase = + (PROS_MAP_REGISTER_ENTRY)( + (ULONG_PTR)AdapterObject->MapRegisterBase | + MAP_BASE_SW_SG); + } + + Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)( + AdapterObject->CurrentWcb->DeviceObject, + AdapterObject->CurrentWcb->CurrentIrp, + AdapterObject->MapRegisterBase, + AdapterObject->CurrentWcb->DeviceContext); + + switch (Result) + { + case DeallocateObjectKeepRegisters: + AdapterObject->NumberOfMapRegisters = 0; + /* fall through */ + + case DeallocateObject: + if (AdapterObject->NumberOfMapRegisters) + { + OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock); + RtlClearBits(MasterAdapter->MapRegisters, + AdapterObject->MapRegisterBase - + MasterAdapter->MapRegisterBase, + AdapterObject->NumberOfMapRegisters); + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); + } + IoFreeAdapterChannel(AdapterObject); + break; + + default: + break; + } + + OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock); + } + + KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql); +} + +/** + * @name HalpCopyBufferMap + * + * Helper function for copying data from/to map register buffers. + * + * @see IoFlushAdapterBuffers, IoMapTransfer + */ + +VOID STDCALL +HalpCopyBufferMap( + PMDL Mdl, + PROS_MAP_REGISTER_ENTRY MapRegisterBase, + PVOID CurrentVa, + ULONG Length, + BOOLEAN WriteToDevice) +{ + ULONG CurrentLength; + ULONG_PTR CurrentAddress; + ULONG ByteOffset; + PVOID VirtualAddress; + + VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority); + if (VirtualAddress == NULL) + { + /* + * NOTE: On real NT a mechanism with reserved pages is implemented + * to handle this case in a slow, but graceful non-fatal way. + */ + /* FIXME: The correct bug check code isn't defined. */ + /* KEBUGCHECKEX(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0); */ + KEBUGCHECK(0); + } + + CurrentAddress = (ULONG_PTR)VirtualAddress + + (ULONG_PTR)CurrentVa - + (ULONG_PTR)MmGetMdlVirtualAddress(Mdl); + + while (Length > 0) + { + ByteOffset = BYTE_OFFSET(CurrentAddress); + CurrentLength = PAGE_SIZE - ByteOffset; + if (CurrentLength > Length) + CurrentLength = Length; + + if (WriteToDevice) + { + RtlCopyMemory( + (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset), + (PVOID)CurrentAddress, + CurrentLength); + } + else + { + RtlCopyMemory( + (PVOID)CurrentAddress, + (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset), + CurrentLength); + } + + Length -= CurrentLength; + CurrentAddress += CurrentLength; + MapRegisterBase++; + } +} + +/** + * @name IoFlushAdapterBuffers + * + * Flush any data remaining in the DMA controller's memory into the host + * memory. + * + * @param AdapterObject + * The adapter object to flush. + * @param Mdl + * Original MDL to flush data into. + * @param MapRegisterBase + * Map register base that was just used by IoMapTransfer, etc. + * @param CurrentVa + * Offset into Mdl to be flushed into, same as was passed to + * IoMapTransfer. + * @param Length + * Length of the buffer to be flushed into. + * @param WriteToDevice + * TRUE if it's a write, FALSE if it's a read. + * + * @return TRUE in all cases. + * + * @remarks + * This copies data from the map register-backed buffer to the user's + * target buffer. Data are not in the user buffer until this function + * is called. + * For slave DMA transfers the controller channel is masked effectively + * stopping the current transfer. + * + * @unimplemented. + */ + +BOOLEAN STDCALL +IoFlushAdapterBuffers( + PADAPTER_OBJECT AdapterObject, + PMDL Mdl, + PVOID MapRegisterBase, + PVOID CurrentVa, + ULONG Length, + BOOLEAN WriteToDevice) +{ + BOOLEAN SlaveDma = FALSE; + PROS_MAP_REGISTER_ENTRY RealMapRegisterBase; + + ASSERT_IRQL(DISPATCH_LEVEL); + + if (AdapterObject != NULL && !AdapterObject->MasterDevice) + { + /* Mask out (disable) the DMA channel. */ + if (AdapterObject->AdapterNumber == 1) + { + PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; + WRITE_PORT_UCHAR(&DmaControl1->SingleMask, + AdapterObject->ChannelNumber | DMA_SETMASK); + } + else + { + PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; + WRITE_PORT_UCHAR(&DmaControl2->SingleMask, + AdapterObject->ChannelNumber | DMA_SETMASK); + } + SlaveDma = TRUE; + } + + /* This can happen if the device supports hardware scatter/gather. */ + if (MapRegisterBase == NULL) + return TRUE; + + RealMapRegisterBase = + (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG); + + if (!WriteToDevice) + { + if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) + { + if (RealMapRegisterBase->Counter != ~0) + { + if (SlaveDma && !AdapterObject->IgnoreCount) + Length -= HalReadDmaCounter(AdapterObject); + } + + HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE); + } + else + { + /* FIXME: Unimplemented case */ + ASSERT(FALSE); + } + } + + RealMapRegisterBase->Counter = 0; + + return TRUE; +} + +/** + * @name IoMapTransfer + * + * Map a DMA for transfer and do the DMA if it's a slave. + * + * @param AdapterObject + * Adapter object to do the DMA on. Bus-master may pass NULL. + * @param Mdl + * Locked-down user buffer to DMA in to or out of. + * @param MapRegisterBase + * Handle to map registers to use for this dma. + * @param CurrentVa + * Index into Mdl to transfer into/out of. + * @param Length + * Length of transfer. Number of bytes actually transferred on + * output. + * @param WriteToDevice + * TRUE if it's an output DMA, FALSE otherwise. + * + * @return + * A logical address that can be used to program a DMA controller, it's + * not meaningful for slave DMA device. + * + * @remarks + * This function does a copyover to contiguous memory <16MB represented + * by the map registers if needed. If the buffer described by MDL can be + * used as is no copyover is done. + * If it's a slave transfer, this function actually performs it. + * + * @implemented + */ + +PHYSICAL_ADDRESS STDCALL +IoMapTransfer( + IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl, + IN PVOID MapRegisterBase, + IN PVOID CurrentVa, + IN OUT PULONG Length, + IN BOOLEAN WriteToDevice) +{ + PPFN_NUMBER MdlPagesPtr; + PFN_NUMBER MdlPage1, MdlPage2; + ULONG ByteOffset; + ULONG TransferOffset; + ULONG TransferLength; + BOOLEAN UseMapRegisters; + PROS_MAP_REGISTER_ENTRY RealMapRegisterBase; + PHYSICAL_ADDRESS PhysicalAddress; + PHYSICAL_ADDRESS HighestAcceptableAddress; + ULONG Counter; + DMA_MODE AdapterMode; + KIRQL OldIrql; + + /* + * Precalculate some values that are used in all cases. + * + * ByteOffset is offset inside the page at which the transfer starts. + * MdlPagesPtr is pointer inside the MDL page chain at the page where the + * transfer start. + * PhysicalAddress is physical address corresponding to the transfer + * start page and offset. + * TransferLength is the inital length of the transfer, which is reminder + * of the first page. The actual value is calculated below. + * + * Note that all the variables can change during the processing which + * takes place below. These are just initial values. + */ + + ByteOffset = BYTE_OFFSET(CurrentVa); + + MdlPagesPtr = MmGetMdlPfnArray(Mdl); + MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT; + + PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT; + PhysicalAddress.QuadPart += ByteOffset; + + TransferLength = PAGE_SIZE - ByteOffset; + + /* + * Special case for bus master adapters with S/G support. We can directly + * use the buffer specified by the MDL, so not much work has to be done. + * + * Just return the passed VA's corresponding physical address and update + * length to the number of physically contiguous bytes found. Also + * pages crossing the 4Gb boundary aren't considered physically contiguous. + */ + + if (MapRegisterBase == NULL) + { + while (TransferLength < *Length) + { + MdlPage1 = *MdlPagesPtr; + MdlPage2 = *(MdlPagesPtr + 1); + if (MdlPage1 + 1 != MdlPage2) + break; + if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF) + break; + TransferLength += PAGE_SIZE; + MdlPagesPtr++; + } + + if (TransferLength < *Length) + *Length = TransferLength; + + return PhysicalAddress; + } + + /* + * The code below applies to slave DMA adapters and bus master adapters + * without hardward S/G support. + */ + + RealMapRegisterBase = + (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG); + + /* + * Try to calculate the size of the transfer. We can only transfer + * pages that are physically contiguous and that don't cross the + * 64Kb boundary (this limitation applies only for ISA controllers). + */ + + while (TransferLength < *Length) + { + MdlPage1 = *MdlPagesPtr; + MdlPage2 = *(MdlPagesPtr + 1); + if (MdlPage1 + 1 != MdlPage2) + break; + if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF)) + break; + TransferLength += PAGE_SIZE; + MdlPagesPtr++; + } + + if (TransferLength > *Length) + TransferLength = *Length; + + /* + * If we're about to simulate software S/G and not all the pages are + * physically contiguous then we must use the map registers to store + * the data and allow the whole transfer to proceed at once. + */ + + if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG && + TransferLength < *Length) + { + UseMapRegisters = TRUE; + PhysicalAddress = RealMapRegisterBase->PhysicalAddress; + PhysicalAddress.QuadPart += ByteOffset; + TransferLength = *Length; + RealMapRegisterBase->Counter = ~0; + Counter = 0; + } + else + { + /* + * This is ordinary DMA transfer, so just update the progress + * counters. These are used by IoFlushAdapterBuffers to track + * the transfer progress. + */ + + UseMapRegisters = FALSE; + Counter = RealMapRegisterBase->Counter; + RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength); + + /* + * Check if the buffer doesn't exceed the highest physical address + * limit of the device. In that case we must use the map registers to + * store the data. + */ + + HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject); + if (PhysicalAddress.QuadPart + TransferLength > + HighestAcceptableAddress.QuadPart) + { + UseMapRegisters = TRUE; + PhysicalAddress = RealMapRegisterBase->PhysicalAddress; + PhysicalAddress.QuadPart += ByteOffset; + if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) + { + RealMapRegisterBase->Counter = ~0; + } + } + } + + /* + * If we decided to use the map registers (see above) and we're about + * to transfer data to the device then copy the buffers into the map + * register memory. + */ + + if (UseMapRegisters && WriteToDevice) + { + HalpCopyBufferMap(Mdl, RealMapRegisterBase + Counter, + CurrentVa, TransferLength, WriteToDevice); + } + + /* + * Return the length of transfer that actually takes place. + */ + + *Length = TransferLength; + + /* + * If we're doing slave (system) DMA then program the (E)ISA controller + * to actually start the transfer. + */ + + if (AdapterObject != NULL && !AdapterObject->MasterDevice) + { + AdapterMode = AdapterObject->AdapterMode; + + if (WriteToDevice) + { + AdapterMode.TransferType = WRITE_TRANSFER; + } + else + { + AdapterMode.TransferType = READ_TRANSFER; + if (AdapterObject->IgnoreCount) + { + RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress + + ByteOffset, TransferLength); + } + } + + TransferOffset = PhysicalAddress.LowPart & 0xFFFF; + if (AdapterObject->Width16Bits) + { + TransferLength >>= 1; + TransferOffset >>= 1; + } + + OldIrql = KfAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock); + + if (AdapterObject->AdapterNumber == 1) + { + PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; + + /* Reset Register */ + WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0); + /* Set the Mode */ + WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte); + /* Set the Offset Register */ + WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, + (UCHAR)(TransferOffset)); + WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, + (UCHAR)(TransferOffset >> 8)); + /* Set the Page Register */ + WRITE_PORT_UCHAR(AdapterObject->PagePort + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages), + (UCHAR)(PhysicalAddress.LowPart >> 16)); + if (HalpEisaDma) + { + WRITE_PORT_UCHAR(AdapterObject->PagePort + + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages), + 0); + } + /* Set the Length */ + WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, + (UCHAR)(TransferLength - 1)); + WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, + (UCHAR)((TransferLength - 1) >> 8)); + /* Unmask the Channel */ + WRITE_PORT_UCHAR(&DmaControl1->SingleMask, + AdapterObject->ChannelNumber | DMA_CLEARMASK); + } + else + { + PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; + + /* Reset Register */ + WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0); + /* Set the Mode */ + WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte); + /* Set the Offset Register */ + WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, + (UCHAR)(TransferOffset)); + WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, + (UCHAR)(TransferOffset >> 8)); + /* Set the Page Register */ + WRITE_PORT_UCHAR(AdapterObject->PagePort + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages), + (UCHAR)(PhysicalAddress.u.LowPart >> 16)); + if (HalpEisaDma) + { + WRITE_PORT_UCHAR(AdapterObject->PagePort + + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages), + 0); + } + /* Set the Length */ + WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, + (UCHAR)(TransferLength - 1)); + WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, + (UCHAR)((TransferLength - 1) >> 8)); + /* Unmask the Channel */ + WRITE_PORT_UCHAR(&DmaControl2->SingleMask, + AdapterObject->ChannelNumber | DMA_CLEARMASK); + } + + KfReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql); + } + + /* + * Return physical address of the buffer with data that is used for the + * transfer. It can either point inside the Mdl that was passed by the + * caller or into the map registers if the Mdl buffer can't be used + * directly. + */ + + return PhysicalAddress; +} + +/** + * @name HalFlushCommonBuffer + * + * @implemented + */ + +BOOLEAN STDCALL +HalFlushCommonBuffer( + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4, + ULONG Unknown5) +{ + return TRUE; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/drive.c b/reactos/hal/halppc/generic/drive.c new file mode 100644 index 00000000000..281e0e121c3 --- /dev/null +++ b/reactos/hal/halppc/generic/drive.c @@ -0,0 +1,33 @@ +/* $Id: drive.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: hal/x86/drive.c + * PURPOSE: Drive letter assignment + * PROGRAMMER: + * UPDATE HISTORY: + * 2000-03-25 + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +VOID STDCALL +IoAssignDriveLetters(IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, + IN PSTRING NtDeviceName, + OUT PUCHAR NtSystemPath, + OUT PSTRING NtSystemPathString) +{ + /* FIXME FIXME FIXME FUCK SOMEONE FIXME*/ + HalIoAssignDriveLetters(NULL, + NtDeviceName, + NtSystemPath, + NtSystemPathString); +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/enum.c b/reactos/hal/halppc/generic/enum.c new file mode 100644 index 00000000000..af8b06d4a87 --- /dev/null +++ b/reactos/hal/halppc/generic/enum.c @@ -0,0 +1,23 @@ +/* $Id: enum.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/enum.c + * PURPOSE: Motherboard device enumerator + * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * UPDATE HISTORY: + * Created 01/05/2001 + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +VOID +HalpStartEnumerator (VOID) +{ +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/fmutex.c b/reactos/hal/halppc/generic/fmutex.c new file mode 100644 index 00000000000..a7624edb748 --- /dev/null +++ b/reactos/hal/halppc/generic/fmutex.c @@ -0,0 +1,101 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS HAL + * FILE: ntoskrnl/hal/x86/fmutex.c + * PURPOSE: Deprecated HAL Fast Mutex + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + */ + +/* + * NOTE: Even HAL itself has #defines to use the Exi* APIs inside NTOSKRNL. + * These are only exported here for compatibility with really old + * drivers. Also note that in theory, these can be made much faster + * by using assembly and inlining all the operations, including + * raising and lowering irql. + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +#undef ExAcquireFastMutex +#undef ExReleaseFastMutex +#undef ExTryToAcquireFastMutex + +/* FUNCTIONS *****************************************************************/ + +VOID +FASTCALL +ExAcquireFastMutex(PFAST_MUTEX FastMutex) +{ + KIRQL OldIrql; + + /* Raise IRQL to APC */ + OldIrql = KfRaiseIrql(APC_LEVEL); + + /* Decrease the count */ + if (InterlockedDecrement(&FastMutex->Count)) + { + /* Someone is still holding it, use slow path */ + FastMutex->Contention++; + KeWaitForSingleObject(&FastMutex->Gate, + WrExecutive, + KernelMode, + FALSE, + NULL); + } + + /* Set the owner and IRQL */ + FastMutex->Owner = KeGetCurrentThread(); + FastMutex->OldIrql = OldIrql; +} + +VOID +FASTCALL +ExReleaseFastMutex(PFAST_MUTEX FastMutex) +{ + KIRQL OldIrql; + + /* Erase the owner */ + FastMutex->Owner = (PVOID)1; + OldIrql = FastMutex->OldIrql; + + /* Increase the count */ + if (InterlockedIncrement(&FastMutex->Count) <= 0) + { + /* Someone was waiting for it, signal the waiter */ + KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT); + } + + /* Lower IRQL back */ + KfLowerIrql(OldIrql); +} + +BOOLEAN +FASTCALL +ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex) +{ + KIRQL OldIrql; + + /* Raise to APC_LEVEL */ + OldIrql = KfRaiseIrql(APC_LEVEL); + + /* Check if we can quickly acquire it */ + if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1) + { + /* We have, set us as owners */ + FastMutex->Owner = KeGetCurrentThread(); + FastMutex->OldIrql = OldIrql; + return TRUE; + } + else + { + /* Acquire attempt failed */ + KfLowerIrql(OldIrql); + return FALSE; + } +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/generic.rbuild b/reactos/hal/halppc/generic/generic.rbuild new file mode 100644 index 00000000000..ab14f754594 --- /dev/null +++ b/reactos/hal/halppc/generic/generic.rbuild @@ -0,0 +1,26 @@ + + ../include + include + + + + beep.c + bus.c + dma.c + drive.c + enum.c + fmutex.c + halinit.c + isa.c + kdbg.c + mca.c + misc.c + pci.c + portio.c + reboot.c + sysbus.c + sysinfo.c + time.c + timer.c + ../include/hal.h + diff --git a/reactos/hal/halppc/generic/halinit.c b/reactos/hal/halppc/generic/halinit.c new file mode 100644 index 00000000000..fe78f9bc438 --- /dev/null +++ b/reactos/hal/halppc/generic/halinit.c @@ -0,0 +1,69 @@ +/* $Id: halinit.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/halinit.c + * PURPOSE: Initalize the x86 hal + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + * 11/06/98: Created + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *****************************************************************/ + +PVOID HalpZeroPageMapping = NULL; +HALP_HOOKS HalpHooks; + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +STDCALL +DriverEntry( + PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) +{ + return STATUS_SUCCESS; +} + +BOOLEAN STDCALL +HalInitSystem (ULONG BootPhase, + PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + if (BootPhase == 0) + { + RtlZeroMemory(&HalpHooks, sizeof(HALP_HOOKS)); + HalpInitPhase0((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock); + } + else if (BootPhase == 1) + { + /* Initialize the clock interrupt */ + //HalpInitPhase1(); + + /* Initialize display and make the screen black */ + HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock); + HalpInitBusHandlers(); + HalpInitDma(); + + /* Enumerate the devices on the motherboard */ + HalpStartEnumerator(); + } + else if (BootPhase == 2) + { + PHYSICAL_ADDRESS Null = {{0}}; + + /* Go to blue screen */ + HalClearDisplay (0x17); /* grey on blue */ + + HalpZeroPageMapping = MmMapIoSpace(Null, PAGE_SIZE, MmNonCached); + } + + return TRUE; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/ipi.c b/reactos/hal/halppc/generic/ipi.c new file mode 100644 index 00000000000..739de8d716c --- /dev/null +++ b/reactos/hal/halppc/generic/ipi.c @@ -0,0 +1,24 @@ +/* $Id: ipi.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: hal/halx86/generic/ipi.c + * PURPOSE: Miscellaneous hardware functions + * PROGRAMMER: Eric Kohl (ekohl@rz-online.de) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +VOID STDCALL +HalRequestIpi(ULONG ProcessorNo) +{ + DPRINT("HalRequestIpi(ProcessorNo %lu)\n", ProcessorNo); +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/irq.S b/reactos/hal/halppc/generic/irq.S new file mode 100644 index 00000000000..585bb4c83b8 --- /dev/null +++ b/reactos/hal/halppc/generic/irq.S @@ -0,0 +1,631 @@ +/* + * FILE: hal/halx86/generic/irql.S + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: Software, System and Hardware IRQ Management + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +.intel_syntax noprefix + +/* GLOBALS *******************************************************************/ + +PICInitTable: + + /* Master PIC */ + .short 0x20 /* Port */ + .byte 0x11 /* Edge,, cascade, CAI 8, ICW4 */ + .byte PRIMARY_VECTOR_BASE /* Base */ + .byte 4 /* IRQ 4 connected to slave */ + .byte 1 /* Non buffered, not nested, 8086 */ + + /* Slave PIC */ + .short 0xA0 /* Port */ + .byte 0x11 /* Edge, cascade, CAI 8, ICW4 */ + .byte PRIMARY_VECTOR_BASE + 8 /* Base */ + .byte 2 /* Slave ID: Slave 2 */ + .byte 1 /* Non buffered, not nested, 8086 */ + + /* End of initialization table */ + .short 0 + +KiI8259MaskTable: + .long 0 /* IRQL 0 */ + .long 0 /* IRQL 1 */ + .long 0 /* IRQL 2 */ + .long 0 /* IRQL 3 */ + .long 0xFF800000 /* IRQL 4 */ + .long 0xFFC00000 /* IRQL 5 */ + .long 0xFFE00000 /* IRQL 6 */ + .long 0xFFF00000 /* IRQL 7 */ + .long 0xFFF80000 /* IRQL 8 */ + .long 0xFFFC0000 /* IRQL 9 */ + .long 0xFFFE0000 /* IRQL 10 */ + .long 0xFFFF0000 /* IRQL 11 */ + .long 0xFFFF8000 /* IRQL 12 */ + .long 0xFFFFC000 /* IRQL 13 */ + .long 0xFFFFE000 /* IRQL 14 */ + .long 0xFFFFF000 /* IRQL 15 */ + .long 0xFFFFF800 /* IRQL 16 */ + .long 0xFFFFFC00 /* IRQL 17 */ + .long 0xFFFFFE00 /* IRQL 18 */ + .long 0xFFFFFE00 /* IRQL 19 */ + .long 0xFFFFFE80 /* IRQL 20 */ + .long 0xFFFFFEC0 /* IRQL 21 */ + .long 0xFFFFFEE0 /* IRQL 22 */ + .long 0xFFFFFEF0 /* IRQL 23 */ + .long 0xFFFFFEF8 /* IRQL 24 */ + .long 0xFFFFFEF8 /* IRQL 25 */ + .long 0xFFFFFEFA /* IRQL 26 */ + .long 0xFFFFFFFA /* IRQL 27 */ + .long 0xFFFFFFFB /* IRQL 28 */ + .long 0xFFFFFFFB /* IRQL 29 */ + .long 0xFFFFFFFB /* IRQL 30 */ + .long 0xFFFFFFFB /* IRQL 31 */ + +HalpSysIntHandler: +.rept 8 + .long GenericIRQ /* IRQ 0-7 */ +.endr + .long IRQ7 /* IRQ 7 */ +.rept 8 + .long GenericIRQ /* IRQ 8-15 */ +.endr + .long IRQ15 /* IRQ 15 */ +.rept 20 + .long GenericIRQ /* IRQ 16-35 */ +.endr + +SoftIntByteTable: + .byte PASSIVE_LEVEL /* IRR 0 */ + .byte PASSIVE_LEVEL /* IRR 1 */ + .byte APC_LEVEL /* IRR 2 */ + .byte APC_LEVEL /* IRR 3 */ + .byte DISPATCH_LEVEL /* IRR 4 */ + .byte DISPATCH_LEVEL /* IRR 5 */ + .byte DISPATCH_LEVEL /* IRR 6 */ + .byte DISPATCH_LEVEL /* IRR 7 */ + +SoftIntHandlerTable: + .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ + .long _HalpApcInterrupt /* APC_LEVEL */ + .long _HalpDispatchInterrupt /* DISPATCH_LEVEL */ + +SoftIntHandlerTable2: + .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ + .long _HalpApcInterrupt2ndEntry /* APC_LEVEL */ + .long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */ + +/* FUNCTIONS *****************************************************************/ + +.globl _HalpInitPICs@0 +.func HalpInitPICs@0 +_HalpInitPICs@0: + + /* Save ESI and disable interrupts */ + push esi + pushf + cli + + /* Read the init table */ + lea esi, PICInitTable + lodsw + +InitLoop: + + /* Put the port in EDX */ + movzx edx, ax + + /* Initialize the PIC, using a delay for each command */ + outsb + jmp $+2 + inc edx + outsb + jmp $+2 + outsb + jmp $+2 + outsb + jmp $+2 + + /* Mask all interrupts */ + mov al, 0xFF + out dx, al + + /* Check if we're done, otherwise initialize next PIC */ + lodsw + cmp ax, 0 + jnz InitLoop + + /* Restore interrupts and return */ + or dword ptr [esp], EFLAGS_INTERRUPT_MASK + popf + pop esi + ret +.endfunc + +.globl @HalRequestSoftwareInterrupt@4 +.func @HalRequestSoftwareInterrupt@4 +_@HalRequestSoftwareInterrupt@4: +@HalRequestSoftwareInterrupt@4: + + /* Get IRR mask */ + mov eax, 1 + shl eax, cl + + /* Disable interrupts */ + pushf + cli + + /* Set IRR and get IRQL */ + or [fs:KPCR_IRR], eax + mov cl, [fs:KPCR_IRQL] + + /* Get software IRR mask */ + mov eax, [fs:KPCR_IRR] + and eax, 3 + + /* Get highest pending software interrupt and check if it's higher */ + xor edx, edx + mov dl, SoftIntByteTable[eax] + cmp dl, cl + jbe AfterCall + + /* Call the pending interrupt */ + call SoftIntHandlerTable[edx*4] + +AfterCall: + + /* Retore interrupts and return */ + popf + ret +.endfunc + +.globl _HalDisableSystemInterrupt@8 +.func HalDisableSystemInterrupt@8 +_HalDisableSystemInterrupt@8: + + /* Convert to vector */ + movzx ecx, byte ptr [esp+4] + sub ecx, PRIMARY_VECTOR_BASE + + /* Disable interrupts and set the new IDR */ + mov edx, 1 + shl edx, cl + cli + or [fs:KPCR_IDR], edx + + /* Get the current mask */ + xor eax, eax + in al, 0xA1 + shl eax, 8 + in al, 0x21 + + /* Mask off the interrupt and write the new mask */ + or eax, edx + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Return with interrupts enabled */ + in al, 0xA1 + sti + ret 8 +.endfunc + +.globl _HalEnableSystemInterrupt@12 +.func HalEnableSystemInterrupt@12 +_HalEnableSystemInterrupt@12: + + /* Get the vector and validate it */ + movzx ecx, byte ptr [esp+4] + sub ecx, PRIMARY_VECTOR_BASE + jb Invalid + cmp ecx, CLOCK2_LEVEL + jnb Invalid + + /* Get the current PCI Edge/Level control registers */ + mov edx, 0x4D1 + in al, dx + shl ax, 8 + mov eax, 0x4D0 + in al, dx + mov dx, 1 + shl dx, cl + + /* Check if this is a latched interrupt */ + cmp dword ptr [esp+12], 0 + jnz Latched + + /* Use OR for edge interrupt */ + or ax, dx + jmp AfterMask +Latched: + + /* Mask it out for level interrupt */ + not dx + and ax, dx + +AfterMask: + + /* Set the PCI Edge/Level control registers */ + mov edx, 0x4D0 + out dx, al + shr ax, 8 + mov edx, 0x4D1 + out dx, al + + /* Calculate the new IDR */ + mov eax, 1 + shl eax, cl + not eax + cli + and [fs:KPCR_IDR], eax + + /* Get the current IRQL and mask the IRQs in the PIC */ + movzx eax, byte ptr [fs:KPCR_IRQL] + mov eax, KiI8259MaskTable[eax*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Enable interrupts and return TRUE */ + sti + mov eax, 1 + ret 12 + +Invalid: + + /* Fail, invalid IRQ */ + xor eax, eax + ret 12 +.endfunc + +.globl _HalBeginSystemInterrupt@12 +.func HalBeginSystemInterrupt@12 +_HalBeginSystemInterrupt@12: + + /* Convert to IRQ and call the handler */ + mov edx, [esp+8] + sub edx, PRIMARY_VECTOR_BASE + jmp HalpSysIntHandler[edx*4] + +IRQ15: + /* This is IRQ 15, check if it's spurious */ + mov al, 0xB + out 0xA0, al + in al, 0xA0 + test al, 0x80 + jnz GenericIRQ + + /* Cascaded interrupt... dismiss it and return FALSE */ + mov al, 0x62 + out 0x20, al + mov eax, 0 + ret 12 + +IRQ7: + /* This is IRQ 7, check if it's spurious */ + mov al, 0xB + out 0x20, al + in al, 0x20 + test al, 0x80 + jnz GenericIRQ + + /* It is, return FALSE */ + mov eax, 0 + ret 12 + +GenericIRQ: + /* Return the current IRQL */ + mov eax, [esp+12] + movzx ecx, byte ptr [fs:KPCR_IRQL] + mov [eax], cl + + /* Set the new IRQL */ + movzx eax, byte ptr [esp+4] + mov [fs:KPCR_IRQL], al + + /* Set IRQ mask in the PIC */ + mov eax, KiI8259MaskTable[eax*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Check to which PIC the EOI was sent */ + mov eax, edx + cmp eax, 8 + jnb Pic1 + + /* Write mask to master PIC */ + or al, 0x60 + out 0x20, al + jmp DoneBegin + +Pic1: + /* Write mask to slave PIC */ + mov al, 0x20 + out 0xA0, al + mov al, 0x62 + out 0x20, al + +DoneBegin: + /* Enable interrupts and return TRUE */ + in al, 0x21 + sti + mov eax, 1 + ret 12 +.endfunc + +.globl _HalEndSystemInterrupt@8 +.func HalEndSystemInterrupt@8 +_HalEndSystemInterrupt@8: + + /* Get the IRQL and check if it's a software interrupt */ + movzx ecx, byte ptr [esp+4] + cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + jbe SkipMask2 + + /* Hardware interrupt, mask the appropriate IRQs in the PIC */ + mov eax, KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + +SkipMask2: + + /* Set IRQL and check if there are pending software interrupts */ + mov [fs:KPCR_IRQL], cl + mov eax, [fs:KPCR_IRR] + mov al, SoftIntByteTable[eax] + cmp al, cl + ja DoCall + ret 8 + +DoCall: + + /* There are pending software interrupts, call their handlers */ + add esp, 12 + jmp SoftIntHandlerTable2[eax*4] +.endfunc + +.globl @KfLowerIrql@4 +.func @KfLowerIrql@4 +_@KfLowerIrql@4: +@KfLowerIrql@4: + + /* Save flags since we'll disable interrupts */ + pushf + + /* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */ + movzx ecx, cl + cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + cli + jbe SkipMask + + /* Clear interrupt masks since there's a pending hardware interrupt */ + mov eax, KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + +SkipMask: + + /* Set the new IRQL and check if there's a pending software interrupt */ + mov [fs:KPCR_IRQL], cl + mov eax, [fs:KPCR_IRR] + mov al, SoftIntByteTable[eax] + cmp al, cl + jbe DoCall3 + + /* There is, call it */ + call SoftIntHandlerTable[eax*4] + +DoCall3: + + /* Restore interrupts and return */ + popf + ret +.endfunc + +.globl @KfRaiseIrql@4 +.func @KfRaiseIrql@4 +_@KfRaiseIrql@4: +@KfRaiseIrql@4: + + /* Get the IRQL and check if it's Software level only */ + xor eax, eax + mov al, [fs:KPCR_IRQL] + movzx ecx, cl + cmp cl, DISPATCH_LEVEL + jbe SetIrql + + /* Save the current IRQL */ + mov edx, eax + + /* It's a hardware IRQL, so disable interrupts */ + pushf + cli + + /* Set the new IRQL */ + mov [fs:KPCR_IRQL], cl + + /* Mask the interrupts in the PIC */ + mov eax, KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Restore interrupts and return old IRQL */ + popf + mov eax, edx + ret + +SetIrql: + + /* Set the IRQL and return */ + mov [fs:KPCR_IRQL], cl + ret +.endfunc + +.globl _KeGetCurrentIrql@0 +.func KeGetCurrentIrql@0 +_KeGetCurrentIrql@0: + + /* Return the IRQL */ + movzx eax, word ptr [fs:KPCR_IRQL] + ret +.endfunc + +.globl _KeRaiseIrqlToDpcLevel@0 +.func KeRaiseIrqlToDpcLevel@0 +_KeRaiseIrqlToDpcLevel@0: + + /* Get the current IRQL */ + xor eax, eax + mov al, [fs:KPCR_IRQL] + + /* Set DISPATCH_LEVEL */ + mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + ret +.endfunc + +.globl _KeRaiseIrqlToSynchLevel@0 +.func KeRaiseIrqlToSynchLevel@0 +_KeRaiseIrqlToSynchLevel@0: + + /* Disable interrupts */ + pushf + cli + + /* Mask out interrupts */ + mov eax, KiI8259MaskTable[DISPATCH_LEVEL*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Return the old IRQL, enable interrupts and set to DISPATCH */ + mov al, [fs:KPCR_IRQL] + mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + popf + ret +.endfunc + +.globl _HalpApcInterrupt +.func HalpApcInterrupt +_HalpApcInterrupt: + + /* Create fake interrupt stack */ + pop eax + pushf + push cs + push eax + + /* Enter interrupt */ + INT_PROLOG hapc, DoPushFakeErrorCode +.endfunc + +.globl _HalpApcInterrupt2ndEntry +.func HalpApcInterrupt2ndEntry +_HalpApcInterrupt2ndEntry: + + /* Save current IRQL and set to APC level */ + push [fs:KPCR_IRQL] + mov byte ptr [fs:KPCR_IRQL], APC_LEVEL + and dword ptr [fs:KPCR_IRR], ~(1 << APC_LEVEL) + + /* Enable interrupts and check if we came from User/V86 mode */ + sti + mov eax, [ebp+KTRAP_FRAME_CS] + and eax, MODE_MASK + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jz DeliverApc + + /* Set user mode delivery */ + or eax, UserMode + +DeliverApc: + + /* Deliver the APCs */ + push ebp + push 0 + push eax + call _KiDeliverApc@12 + + /* Disable interrupts and end it */ + cli + call _HalpEndSoftwareInterrupt@4 + jmp _Kei386EoiHelper@0 +.endfunc + +.globl _HalpDispatchInterrupt +.func HalpDispatchInterrupt +_HalpDispatchInterrupt: + + /* Create fake interrupt stack */ + pop eax + pushf + push cs + push eax + + /* Enter interrupt */ + INT_PROLOG hapc, DoPushFakeErrorCode +.endfunc + +.globl _HalpDispatchInterrupt2ndEntry +.func HalpDispatchInterrupt2ndEntry +_HalpDispatchInterrupt2ndEntry: + + /* Save current IRQL and set to DPC level */ + push [fs:KPCR_IRQL] + mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + and dword ptr [fs:KPCR_IRR], ~(1 << DISPATCH_LEVEL) + + /* Enable interrupts and let the kernel handle this */ + sti + call _KiDispatchInterrupt@0 + + /* Disable interrupts and end it */ + cli + call _HalpEndSoftwareInterrupt@4 + jmp _Kei386EoiHelper@0 +.endfunc + +.globl _HalpEndSoftwareInterrupt@4 +.func HalpEndSoftwareInterrupt@4 +_HalpEndSoftwareInterrupt@4: + + /* Get the IRQL and check if we're in the software region */ + movzx ecx, byte ptr [esp+4] + cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL + jbe SoftwareInt + + /* Set the right mask in the PIC for the hardware IRQ */ + mov eax, KiI8259MaskTable[ecx*4] + or eax, [fs:KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + +SoftwareInt: + /* Check if there are pending software interrupts */ + mov [fs:KPCR_IRQL], cl + mov eax, [fs:KPCR_IRR] + mov al, SoftIntByteTable[eax] + cmp al, cl + ja DoCall2 + ret 4 + +DoCall2: + /* There are pending softwate interrupts, call their handlers */ + add esp, 8 + jmp SoftIntHandlerTable2[eax*4] +.endfunc diff --git a/reactos/hal/halppc/generic/irql.c b/reactos/hal/halppc/generic/irql.c new file mode 100644 index 00000000000..fd55e42c1f7 --- /dev/null +++ b/reactos/hal/halppc/generic/irql.c @@ -0,0 +1,425 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/irql.c + * PURPOSE: Implements IRQLs + * PROGRAMMER: David Welch (welch@cwcom.net) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +/* + * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS +*/ + +typedef union +{ + USHORT both; + struct + { + BYTE master; + BYTE slave; + }; +} +PIC_MASK; + +/* + * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt + * - At startup enable timer and cascade + */ +#if defined(__GNUC__) +static PIC_MASK pic_mask = {.both = 0xFFFA}; +#else +static PIC_MASK pic_mask = { 0xFFFA }; +#endif + + +/* + * PURPOSE: Mask for disabling of acknowledged interrupts + */ +#if defined(__GNUC__) +static PIC_MASK pic_mask_intr = {.both = 0x0000}; +#else +static PIC_MASK pic_mask_intr = { 0 }; +#endif + +static ULONG HalpPendingInterruptCount[NR_IRQS]; + +#define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x) +#define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x) + +VOID STDCALL +KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); + +/* FUNCTIONS ****************************************************************/ + +#undef KeGetCurrentIrql +KIRQL STDCALL KeGetCurrentIrql (VOID) +/* + * PURPOSE: Returns the current irq level + * RETURNS: The current irq level + */ +{ + return(KeGetPcr()->Irql); +} + +VOID NTAPI HalpInitPICs(VOID) +{ + memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount)); + + /* Initialization sequence */ + WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11); + WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11); + /* Start of hardware irqs (0x24) */ + WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE); + WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8); + /* 8259-1 is master */ + WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4); + /* 8259-2 is slave */ + WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2); + /* 8086 mode */ + WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); + WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); + /* Enable interrupts */ + WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master); + WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave); + + /* We can now enable interrupts */ + Ki386EnableInterrupts(); +} + +VOID HalpEndSystemInterrupt(KIRQL Irql) +/* + * FUNCTION: Enable all irqs with higher priority. + */ +{ + ULONG flags; + const USHORT mask[] = + { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, + 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, + 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + }; + + /* Interrupts should be disable while enabling irqs of both pics */ + Ki386SaveFlags(flags); + Ki386DisableInterrupts(); + + pic_mask_intr.both &= mask[Irql]; + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); + + /* restore flags */ + Ki386RestoreFlags(flags); +} + +VOID STATIC +HalpExecuteIrqs(KIRQL NewIrql) +{ + ULONG IrqLimit, i; + + IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS); + + /* + * For each irq if there have been any deferred interrupts then now + * dispatch them. + */ + for (i = 0; i < IrqLimit; i++) + { + if (HalpPendingInterruptCount[i] > 0) + { + KeGetPcr()->Irql = (KIRQL)IRQ_TO_DIRQL(i); + + while (HalpPendingInterruptCount[i] > 0) + { + /* + * For each deferred interrupt execute all the handlers at DIRQL. + */ + HalpPendingInterruptCount[i]--; + KiInterruptDispatch2(i + IRQ_BASE, NewIrql); + } + KeGetPcr()->Irql--; + HalpEndSystemInterrupt(KeGetPcr()->Irql); + } + } + +} + +VOID STATIC +HalpLowerIrql(KIRQL NewIrql) +{ + if (NewIrql >= PROFILE_LEVEL) + { + KeGetPcr()->Irql = NewIrql; + return; + } + HalpExecuteIrqs(NewIrql); + if (NewIrql >= DISPATCH_LEVEL) + { + KeGetPcr()->Irql = NewIrql; + return; + } + KeGetPcr()->Irql = DISPATCH_LEVEL; + if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST]) + { + ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE; + KiDispatchInterrupt(); + } + KeGetPcr()->Irql = APC_LEVEL; + if (NewIrql == APC_LEVEL) + { + return; + } + if (KeGetCurrentThread() != NULL && + KeGetCurrentThread()->ApcState.KernelApcPending) + { + KiDeliverApc(KernelMode, NULL, NULL); + } + KeGetPcr()->Irql = PASSIVE_LEVEL; +} + +/********************************************************************** + * NAME EXPORTED + * KfLowerIrql + * + * DESCRIPTION + * Restores the irq level on the current processor + * + * ARGUMENTS + * NewIrql = Irql to lower to + * + * RETURN VALUE + * None + * + * NOTES + * Uses fastcall convention + */ +VOID FASTCALL +KfLowerIrql (KIRQL NewIrql) +{ + DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql); + + if (NewIrql > KeGetPcr()->Irql) + { + DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n", + __FILE__, __LINE__, NewIrql, KeGetPcr()->Irql); + KEBUGCHECK(0); + for(;;); + } + + HalpLowerIrql(NewIrql); +} + +/********************************************************************** + * NAME EXPORTED + * KfRaiseIrql + * + * DESCRIPTION + * Raises the hardware priority (irql) + * + * ARGUMENTS + * NewIrql = Irql to raise to + * + * RETURN VALUE + * previous irq level + * + * NOTES + * Uses fastcall convention + */ + +KIRQL FASTCALL +KfRaiseIrql (KIRQL NewIrql) +{ + KIRQL OldIrql; + + DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql); + + if (NewIrql < KeGetPcr()->Irql) + { + DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n", + __FILE__,__LINE__,KeGetPcr()->Irql,NewIrql); + KEBUGCHECK (0); + for(;;); + } + + OldIrql = KeGetPcr()->Irql; + KeGetPcr()->Irql = NewIrql; + return OldIrql; +} + +/********************************************************************** + * NAME EXPORTED + * KeRaiseIrqlToDpcLevel + * + * DESCRIPTION + * Raises the hardware priority (irql) to DISPATCH level + * + * ARGUMENTS + * None + * + * RETURN VALUE + * Previous irq level + * + * NOTES + * Calls KfRaiseIrql + */ + +KIRQL STDCALL +KeRaiseIrqlToDpcLevel (VOID) +{ + return KfRaiseIrql (DISPATCH_LEVEL); +} + + +/********************************************************************** + * NAME EXPORTED + * KeRaiseIrqlToSynchLevel + * + * DESCRIPTION + * Raises the hardware priority (irql) to CLOCK2 level + * + * ARGUMENTS + * None + * + * RETURN VALUE + * Previous irq level + * + * NOTES + * Calls KfRaiseIrql + */ + +KIRQL STDCALL +KeRaiseIrqlToSynchLevel (VOID) +{ + return KfRaiseIrql (CLOCK2_LEVEL); +} + + +BOOLEAN STDCALL +HalBeginSystemInterrupt (KIRQL Irql, + ULONG Vector, + PKIRQL OldIrql) +{ + ULONG irq; + if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) + { + return(FALSE); + } + irq = Vector - IRQ_BASE; + pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt + + if (irq < 8) + { + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); + WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20); + } + else + { + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); + /* Send EOI to the PICs */ + WRITE_PORT_UCHAR((PUCHAR)0x20,0x20); + WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20); + } + + if (KeGetPcr()->Irql >= Irql) + { + HalpPendingInterruptCount[irq]++; + return(FALSE); + } + *OldIrql = KeGetPcr()->Irql; + KeGetPcr()->Irql = Irql; + + return(TRUE); +} + + +VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2) +/* + * FUNCTION: Finish a system interrupt and restore the specified irq level. + */ +{ + HalpLowerIrql(Irql); + HalpEndSystemInterrupt(Irql); +} + +BOOLEAN +STDCALL +HalDisableSystemInterrupt( + ULONG Vector, + KIRQL Irql) +{ + ULONG irq; + + if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) + return FALSE; + + irq = Vector - IRQ_BASE; + pic_mask.both |= (1 << irq); + if (irq < 8) + { + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave)); + } + else + { + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); + } + + return TRUE; +} + + +BOOLEAN +STDCALL +HalEnableSystemInterrupt( + ULONG Vector, + KIRQL Irql, + KINTERRUPT_MODE InterruptMode) +{ + ULONG irq; + + if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) + return FALSE; + + irq = Vector - IRQ_BASE; + pic_mask.both &= ~(1 << irq); + if (irq < 8) + { + WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); + } + else + { + WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); + } + + return TRUE; +} + + +VOID FASTCALL +HalRequestSoftwareInterrupt( + IN KIRQL Request) +{ + switch (Request) + { + case APC_LEVEL: + ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE; + break; + + case DISPATCH_LEVEL: + ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE; + break; + + default: + KEBUGCHECK(0); + } +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/isa.c b/reactos/hal/halppc/generic/isa.c new file mode 100644 index 00000000000..665bb1edd45 --- /dev/null +++ b/reactos/hal/halppc/generic/isa.c @@ -0,0 +1,75 @@ +/* $Id: isa.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/isa.c + * PURPOSE: Interfaces to the ISA bus + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * 05/06/98: Created + */ + +/* INCLUDES ***************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN HalIsaProbe(VOID) +/* + * FUNCTION: Probes for an ISA bus + * RETURNS: True if detected + * NOTE: Since ISA is the default we are called last and always return + * true + */ +{ + DbgPrint("Assuming ISA bus\n"); + + /* + * Probe for plug and play support + */ + return(TRUE); +} + + +BOOLEAN STDCALL +HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress) +{ + BOOLEAN Result; + + Result = HalTranslateBusAddress(PCIBus, + BusNumber, + BusAddress, + AddressSpace, + TranslatedAddress); + if (Result != FALSE) + return Result; + + Result = HalTranslateBusAddress(Internal, + BusNumber, + BusAddress, + AddressSpace, + TranslatedAddress); + return Result; +} + +ULONG STDCALL +HalpGetIsaInterruptVector(PVOID BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity) +{ + ULONG Vector = IRQ2VECTOR(BusInterruptVector); + *Irql = VECTOR2IRQL(Vector); + *Affinity = 0xFFFFFFFF; + return Vector; +} +/* EOF */ diff --git a/reactos/hal/halppc/generic/kdbg.c b/reactos/hal/halppc/generic/kdbg.c new file mode 100644 index 00000000000..fdc0e223ae4 --- /dev/null +++ b/reactos/hal/halppc/generic/kdbg.c @@ -0,0 +1,547 @@ +/* $Id: kdbg.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/kdbg.c + * PURPOSE: Serial i/o functions for the kernel debugger. + * PROGRAMMER: Emanuele Aliberti + * Eric Kohl + * UPDATE HISTORY: + * Created 05/09/99 + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +#define DEFAULT_BAUD_RATE 19200 + + +/* MACROS *******************************************************************/ + +#define SER_RBR(x) ((x)+0) +#define SER_THR(x) ((x)+0) +#define SER_DLL(x) ((x)+0) +#define SER_IER(x) ((x)+1) +#define SR_IER_ERDA 0x01 +#define SR_IER_ETHRE 0x02 +#define SR_IER_ERLSI 0x04 +#define SR_IER_EMS 0x08 +#define SR_IER_ALL 0x0F +#define SER_DLM(x) ((x)+1) +#define SER_IIR(x) ((x)+2) +#define SER_FCR(x) ((x)+2) +#define SR_FCR_ENABLE_FIFO 0x01 +#define SR_FCR_CLEAR_RCVR 0x02 +#define SR_FCR_CLEAR_XMIT 0x04 +#define SER_LCR(x) ((x)+3) +#define SR_LCR_CS5 0x00 +#define SR_LCR_CS6 0x01 +#define SR_LCR_CS7 0x02 +#define SR_LCR_CS8 0x03 +#define SR_LCR_ST1 0x00 +#define SR_LCR_ST2 0x04 +#define SR_LCR_PNO 0x00 +#define SR_LCR_POD 0x08 +#define SR_LCR_PEV 0x18 +#define SR_LCR_PMK 0x28 +#define SR_LCR_PSP 0x38 +#define SR_LCR_BRK 0x40 +#define SR_LCR_DLAB 0x80 +#define SER_MCR(x) ((x)+4) +#define SR_MCR_DTR 0x01 +#define SR_MCR_RTS 0x02 +#define SR_MCR_OUT1 0x04 +#define SR_MCR_OUT2 0x08 +#define SR_MCR_LOOP 0x10 +#define SER_LSR(x) ((x)+5) +#define SR_LSR_DR 0x01 +#define SR_LSR_TBE 0x20 +#define SER_MSR(x) ((x)+6) +#define SR_MSR_CTS 0x10 +#define SR_MSR_DSR 0x20 +#define SER_SCR(x) ((x)+7) + + +/* GLOBAL VARIABLES *********************************************************/ + +ULONG KdComPortInUse = 0; + + +/* STATIC VARIABLES *********************************************************/ + +static ULONG ComPort = 0; +static ULONG BaudRate = 0; +static PUCHAR PortBase = (PUCHAR)0; + +/* The com port must only be initialized once! */ +static BOOLEAN PortInitialized = FALSE; + + +/* STATIC FUNCTIONS *********************************************************/ + +static BOOLEAN +KdpDoesComPortExist (PUCHAR BaseAddress) +{ + BOOLEAN found; + UCHAR mcr; + UCHAR msr; + + found = FALSE; + + /* save Modem Control Register (MCR) */ + mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress)); + + /* enable loop mode (set Bit 4 of the MCR) */ + WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10); + + /* clear all modem output bits */ + WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10); + + /* read the Modem Status Register */ + msr = READ_PORT_UCHAR (SER_MSR(BaseAddress)); + + /* + * the upper nibble of the MSR (modem output bits) must be + * equal to the lower nibble of the MCR (modem input bits) + */ + if ((msr & 0xF0) == 0x00) + { + /* set all modem output bits */ + WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F); + + /* read the Modem Status Register */ + msr = READ_PORT_UCHAR (SER_MSR(BaseAddress)); + + /* + * the upper nibble of the MSR (modem output bits) must be + * equal to the lower nibble of the MCR (modem input bits) + */ + if ((msr & 0xF0) == 0xF0) + { + /* + * setup a resonable state for the port: + * enable fifo and clear recieve/transmit buffers + */ + WRITE_PORT_UCHAR (SER_FCR(BaseAddress), + (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT)); + WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0); + READ_PORT_UCHAR (SER_RBR(BaseAddress)); + WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0); + found = TRUE; + } + } + + /* restore MCR */ + WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr); + + return (found); +} + + +/* FUNCTIONS ****************************************************************/ + +/* HAL.KdPortInitialize */ +BOOLEAN +STDCALL +KdPortInitialize ( + PKD_PORT_INFORMATION PortInformation, + ULONG Unknown1, + ULONG Unknown2 + ) +{ + ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8}; + char buffer[80]; + ULONG divisor; + UCHAR lcr; + + if (PortInitialized == FALSE) + { + if (PortInformation->BaudRate != 0) + { + BaudRate = PortInformation->BaudRate; + } + else + { + BaudRate = DEFAULT_BAUD_RATE; + } + + if (PortInformation->ComPort == 0) + { + if (KdpDoesComPortExist ((PUCHAR)BaseArray[2])) + { + PortBase = (PUCHAR)BaseArray[2]; + ComPort = 2; + PortInformation->BaseAddress = (ULONG)PortBase; + PortInformation->ComPort = ComPort; +#ifndef NDEBUG + sprintf (buffer, + "\nSerial port COM%ld found at 0x%lx\n", + ComPort, + (ULONG)PortBase); + HalDisplayString (buffer); +#endif /* NDEBUG */ + } + else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1])) + { + PortBase = (PUCHAR)BaseArray[1]; + ComPort = 1; + PortInformation->BaseAddress = (ULONG)PortBase; + PortInformation->ComPort = ComPort; +#ifndef NDEBUG + sprintf (buffer, + "\nSerial port COM%ld found at 0x%lx\n", + ComPort, + (ULONG)PortBase); + HalDisplayString (buffer); +#endif /* NDEBUG */ + } + else + { + sprintf (buffer, + "\nKernel Debugger: No COM port found!!!\n\n"); + HalDisplayString (buffer); + return FALSE; + } + } + else + { + if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort])) + { + PortBase = (PUCHAR)BaseArray[PortInformation->ComPort]; + ComPort = PortInformation->ComPort; + PortInformation->BaseAddress = (ULONG)PortBase; +#ifndef NDEBUG + sprintf (buffer, + "\nSerial port COM%ld found at 0x%lx\n", + ComPort, + (ULONG)PortBase); + HalDisplayString (buffer); +#endif /* NDEBUG */ + } + else + { + sprintf (buffer, + "\nKernel Debugger: No serial port found!!!\n\n"); + HalDisplayString (buffer); + return FALSE; + } + } + + PortInitialized = TRUE; + } + + /* + * set baud rate and data format (8N1) + */ + + /* turn on DTR and RTS */ + WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS); + + /* set DLAB */ + lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB; + WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr); + + /* set baud rate */ + divisor = 115200 / BaudRate; + WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff)); + WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff)); + + /* reset DLAB and set 8N1 format */ + WRITE_PORT_UCHAR (SER_LCR(PortBase), + SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO); + + /* read junk out of the RBR */ + lcr = READ_PORT_UCHAR (SER_RBR(PortBase)); + + /* + * set global info + */ + KdComPortInUse = (ULONG)PortBase; + + /* + * print message to blue screen + */ + sprintf (buffer, + "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n", + ComPort, + (ULONG)PortBase, + BaudRate); + + HalDisplayString (buffer); + + return TRUE; +} + + +/* HAL.KdPortInitializeEx */ +BOOLEAN +STDCALL +KdPortInitializeEx ( + PKD_PORT_INFORMATION PortInformation, + ULONG Unknown1, + ULONG Unknown2 + ) +{ + ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8}; + PUCHAR ComPortBase; + char buffer[80]; + ULONG divisor; + UCHAR lcr; + + if (PortInformation->BaudRate == 0) + { + PortInformation->BaudRate = DEFAULT_BAUD_RATE; + } + + if (PortInformation->ComPort == 0) + { + return FALSE; + } + else + { + if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort])) + { + ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort]; + PortInformation->BaseAddress = (ULONG)ComPortBase; +#ifndef NDEBUG + sprintf (buffer, + "\nSerial port COM%ld found at 0x%lx\n", + PortInformation->ComPort, + (ULONG)ComPortBase]; + HalDisplayString (buffer); +#endif /* NDEBUG */ + } + else + { + sprintf (buffer, + "\nKernel Debugger: Serial port not found!!!\n\n"); + HalDisplayString (buffer); + return FALSE; + } + } + + /* + * set baud rate and data format (8N1) + */ + + /* turn on DTR and RTS */ + WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS); + + /* set DLAB */ + lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB; + WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr); + + /* set baud rate */ + divisor = 115200 / PortInformation->BaudRate; + WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff)); + WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff)); + + /* reset DLAB and set 8N1 format */ + WRITE_PORT_UCHAR (SER_LCR(ComPortBase), + SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO); + + /* read junk out of the RBR */ + lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase)); + +#ifndef NDEBUG + + /* + * print message to blue screen + */ + sprintf (buffer, + "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n", + PortInformation->ComPort, + (ULONG)ComPortBase, + PortInformation->BaudRate); + + HalDisplayString (buffer); + +#endif /* NDEBUG */ + + return TRUE; +} + + +/* HAL.KdPortGetByte */ +BOOLEAN +STDCALL +KdPortGetByte ( + PUCHAR ByteRecieved + ) +{ + if (PortInitialized == FALSE) + return FALSE; + + if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR)) + { + *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase)); + return TRUE; + } + + return FALSE; +} + + +/* HAL.KdPortGetByteEx */ +BOOLEAN +STDCALL +KdPortGetByteEx ( + PKD_PORT_INFORMATION PortInformation, + PUCHAR ByteRecieved + ) +{ + PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress; + + if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR)) + { + *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase)); + return TRUE; + } + + return FALSE; +} + + +/* HAL.KdPortPollByte */ +BOOLEAN +STDCALL +KdPortPollByte ( + PUCHAR ByteRecieved + ) +{ + if (PortInitialized == FALSE) + return FALSE; + + while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0) + ; + + *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase)); + + return TRUE; +} + + +/* HAL.KdPortPollByteEx */ +BOOLEAN +STDCALL +KdPortPollByteEx ( + PKD_PORT_INFORMATION PortInformation, + PUCHAR ByteRecieved + ) +{ + PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress; + + while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0) + ; + + *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase)); + + return TRUE; +} + + + + +/* HAL.KdPortPutByte */ +VOID +STDCALL +KdPortPutByte ( + UCHAR ByteToSend + ) +{ + if (PortInitialized == FALSE) + return; + + while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0) + ; + + WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend); +} + +/* HAL.KdPortPutByteEx */ +VOID +STDCALL +KdPortPutByteEx ( + PKD_PORT_INFORMATION PortInformation, + UCHAR ByteToSend + ) +{ + PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress; + + while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0) + ; + + WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend); +} + + +/* HAL.KdPortRestore */ +VOID +STDCALL +KdPortRestore ( + VOID + ) +{ +} + + +/* HAL.KdPortSave */ +VOID +STDCALL +KdPortSave ( + VOID + ) +{ +} + + +/* HAL.KdPortDisableInterrupts */ +BOOLEAN +STDCALL +KdPortDisableInterrupts() +{ + UCHAR ch; + + if (PortInitialized == FALSE) + return FALSE; + + ch = READ_PORT_UCHAR (SER_MCR (PortBase)); + ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2)); + WRITE_PORT_UCHAR (SER_MCR (PortBase), ch); + + ch = READ_PORT_UCHAR (SER_IER (PortBase)); + ch &= (~SR_IER_ALL); + WRITE_PORT_UCHAR (SER_IER (PortBase), ch); + + return TRUE; +} + + +/* HAL.KdPortEnableInterrupts */ +BOOLEAN +STDCALL +KdPortEnableInterrupts() +{ + UCHAR ch; + + if (PortInitialized == FALSE) + return FALSE; + + ch = READ_PORT_UCHAR (SER_IER (PortBase)); + ch &= (~SR_IER_ALL); + ch |= SR_IER_ERDA; + WRITE_PORT_UCHAR (SER_IER (PortBase), ch); + + ch = READ_PORT_UCHAR (SER_MCR (PortBase)); + ch &= (~SR_MCR_LOOP); + ch |= (SR_MCR_OUT1 | SR_MCR_OUT2); + WRITE_PORT_UCHAR (SER_MCR (PortBase), ch); + + return TRUE; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/mca.c b/reactos/hal/halppc/generic/mca.c new file mode 100644 index 00000000000..8343c8a8f70 --- /dev/null +++ b/reactos/hal/halppc/generic/mca.c @@ -0,0 +1,79 @@ +/* + * ReactOS kernel + * Copyright (C) 2002 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: mca.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: hal/halx86/mca.c + * PURPOSE: Interfaces to the MicroChannel bus + * PROGRAMMER: Eric Kohl (ekohl@rz-online.de) + */ + +/* + * TODO: + * What Adapter ID is read from an empty slot? + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +ULONG STDCALL +HalpGetMicroChannelData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + PCM_MCA_POS_DATA PosData = (PCM_MCA_POS_DATA)Buffer; + + DPRINT("HalpGetMicroChannelData() called.\n"); + DPRINT(" BusNumber %lu\n", BusNumber); + DPRINT(" SlotNumber %lu\n", SlotNumber); + DPRINT(" Offset 0x%lx\n", Offset); + DPRINT(" Length 0x%lx\n", Length); + + if ((BusNumber != 0) || + (SlotNumber == 0) || (SlotNumber > 8) || + (Length < sizeof(CM_MCA_POS_DATA))) + return(0); + + /* Enter Setup-Mode for given slot */ + WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)(((UCHAR)(SlotNumber - 1) & 0x07) | 0x08)); + + /* Read POS data */ + PosData->AdapterId = (READ_PORT_UCHAR((PUCHAR)0x101) << 8) + + READ_PORT_UCHAR((PUCHAR)0x100); + PosData->PosData1 = READ_PORT_UCHAR((PUCHAR)0x102); + PosData->PosData2 = READ_PORT_UCHAR((PUCHAR)0x103); + PosData->PosData3 = READ_PORT_UCHAR((PUCHAR)0x104); + PosData->PosData4 = READ_PORT_UCHAR((PUCHAR)0x105); + + /* Leave Setup-Mode for given slot */ + WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)((UCHAR)(SlotNumber - 1) & 0x07)); + + return(sizeof(CM_MCA_POS_DATA)); +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/misc.c b/reactos/hal/halppc/generic/misc.c new file mode 100644 index 00000000000..14410083d2f --- /dev/null +++ b/reactos/hal/halppc/generic/misc.c @@ -0,0 +1,72 @@ +/* $Id: misc.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/misc.c + * PURPOSE: Miscellaneous hardware functions + * PROGRAMMER: Eric Kohl (ekohl@rz-online.de) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +/* FUNCTIONS ****************************************************************/ + +PVOID STDCALL +HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject, + IN OUT PULONG NumberOfMapRegisters) +{ + UNIMPLEMENTED; + return NULL; +} + + +VOID STDCALL +HalHandleNMI(PVOID NmiInfo) +{ + UCHAR ucStatus; + + ucStatus = READ_PORT_UCHAR((PUCHAR) 0x61); + + HalDisplayString ("\n*** Hardware Malfunction\n\n"); + HalDisplayString ("Call your hardware vendor for support\n\n"); + + if (ucStatus & 0x80) + HalDisplayString ("NMI: Parity Check / Memory Parity Error\n"); + + if (ucStatus & 0x40) + HalDisplayString ("NMI: Channel Check / IOCHK\n"); + + HalDisplayString ("\n*** The system has halted ***\n"); + KeEnterKernelDebugger (); +} + + +VOID STDCALL +HalProcessorIdle(VOID) +{ + // XXX Learn to use PSL_POW for this. +} + +ULONG FASTCALL +HalSystemVectorDispatchEntry ( + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3 + ) +{ + return 0; +} + + +VOID STDCALL +KeFlushWriteBuffer(VOID) +{ + return; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/pci.c b/reactos/hal/halppc/generic/pci.c new file mode 100644 index 00000000000..f2fd74888f9 --- /dev/null +++ b/reactos/hal/halppc/generic/pci.c @@ -0,0 +1,812 @@ +/* $Id: pci.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/pci.c + * PURPOSE: Interfaces to the PCI bus + * PROGRAMMER: David Welch (welch@mcmail.com) + * Eric Kohl (ekohl@rz-online.de) + * UPDATE HISTORY: + * 05/06/1998: Created + * 17/08/2000: Added preliminary pci bus scanner + * 13/06/2001: Implemented access to pci configuration space + */ + +/* + * NOTES: Sections copied from the Linux pci support + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +/* MACROS ******************************************************************/ + +/* FIXME These are also defined in drivers/bus/pci/pcidef.h. + Maybe put PCI definitions in a central include file??? */ + +/* access type 1 macros */ +#define CONFIG_CMD(bus, dev_fn, where) \ + (0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3)) + +/* access type 2 macros */ +#define IOADDR(dev_fn, where) \ + (0xC000 | (((dev_fn) & 0x1F) << 8) | (where)) +#define FUNC(dev_fn) \ + ((((dev_fn) & 0xE0) >> 4) | 0xf0) + +#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ +#define PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +/* bit 1 is reserved if address_space = 1 */ + + +/* GLOBALS ******************************************************************/ + +#define TAG_PCI TAG('P', 'C', 'I', 'H') + +static ULONG BusConfigType = 0; /* undetermined config type */ +static KSPIN_LOCK PciLock; + +/* FUNCTIONS ****************************************************************/ + +static NTSTATUS +ReadPciConfigUchar(UCHAR Bus, + UCHAR Slot, + UCHAR Offset, + PUCHAR Value) +{ + KIRQL oldIrql; + + switch (BusConfigType) + { + case 1: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); + *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3)); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + + case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot)); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); + *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset))); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS +ReadPciConfigUshort(UCHAR Bus, + UCHAR Slot, + UCHAR Offset, + PUSHORT Value) +{ + KIRQL oldIrql; + + if ((Offset & 1) != 0) + { + return STATUS_INVALID_PARAMETER; + } + + switch (BusConfigType) + { + case 1: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); + *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2)); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + + case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot)); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); + *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset))); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS +ReadPciConfigUlong(UCHAR Bus, + UCHAR Slot, + UCHAR Offset, + PULONG Value) +{ + KIRQL oldIrql; + + if ((Offset & 3) != 0) + { + return STATUS_INVALID_PARAMETER; + } + + switch (BusConfigType) + { + case 1: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); + *Value = READ_PORT_ULONG((PULONG)0xCFC); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + + case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot)); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); + *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset))); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS +WritePciConfigUchar(UCHAR Bus, + UCHAR Slot, + UCHAR Offset, + UCHAR Value) +{ + KIRQL oldIrql; + + switch (BusConfigType) + { + case 1: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); + WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + + case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot)); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); + WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS +WritePciConfigUshort(UCHAR Bus, + UCHAR Slot, + UCHAR Offset, + USHORT Value) +{ + KIRQL oldIrql; + + if ((Offset & 1) != 0) + { + return STATUS_INVALID_PARAMETER; + } + + switch (BusConfigType) + { + case 1: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); + WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + + case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot)); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); + WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + + +static NTSTATUS +WritePciConfigUlong(UCHAR Bus, + UCHAR Slot, + UCHAR Offset, + ULONG Value) +{ + KIRQL oldIrql; + + if ((Offset & 3) != 0) + { + return STATUS_INVALID_PARAMETER; + } + + switch (BusConfigType) + { + case 1: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); + WRITE_PORT_ULONG((PULONG)0xCFC, Value); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + + case 2: + KeAcquireSpinLock(&PciLock, &oldIrql); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot)); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus); + WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0); + KeReleaseSpinLock(&PciLock, oldIrql); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + + +static ULONG STDCALL +HalpGetPciData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + PVOID Ptr = Buffer; + ULONG Address = Offset; + ULONG Len = Length; + ULONG Vendor; + UCHAR HeaderType; + + DPRINT("HalpGetPciData() called.\n"); + DPRINT(" BusNumber %lu\n", BusNumber); + DPRINT(" SlotNumber %lu\n", SlotNumber); + DPRINT(" Offset 0x%lx\n", Offset); + DPRINT(" Length 0x%lx\n", Length); + + if ((Length == 0) || (BusConfigType == 0)) + return 0; + + ReadPciConfigUlong((UCHAR)BusNumber, + (UCHAR)(SlotNumber & 0x1F), + 0x00, + &Vendor); + /* some broken boards return 0 if a slot is empty: */ + if (Vendor == 0xFFFFFFFF || Vendor == 0) + { + if (BusNumber == 0 && Offset == 0 && Length >= 2) + { + *(PUSHORT)Buffer = PCI_INVALID_VENDORID; + return 2; + } + return 0; + } + + /* 0E=PCI_HEADER_TYPE */ + ReadPciConfigUchar((UCHAR)BusNumber, + (UCHAR)(SlotNumber & 0x1F), + 0x0E, + &HeaderType); + if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0)) + { + if (Offset == 0 && Length >= 2) + { + *(PUSHORT)Buffer = PCI_INVALID_VENDORID; + return 2; + } + return 0; + } + ReadPciConfigUlong((UCHAR)BusNumber, + (UCHAR)SlotNumber, + 0x00, + &Vendor); + /* some broken boards return 0 if a slot is empty: */ + if (Vendor == 0xFFFFFFFF || Vendor == 0) + { + if (BusNumber == 0 && Offset == 0 && Length >= 2) + { + *(PUSHORT)Buffer = PCI_INVALID_VENDORID; + return 2; + } + return 0; + } + + if ((Address & 1) && (Len >= 1)) + { + ReadPciConfigUchar((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + Ptr); + Ptr = (char*)Ptr + 1; + Address++; + Len--; + } + + if ((Address & 2) && (Len >= 2)) + { + ReadPciConfigUshort((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + Ptr); + Ptr = (char*)Ptr + 2; + Address += 2; + Len -= 2; + } + + while (Len >= 4) + { + ReadPciConfigUlong((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + Ptr); + Ptr = (char*)Ptr + 4; + Address += 4; + Len -= 4; + } + + if (Len >= 2) + { + ReadPciConfigUshort((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + Ptr); + Ptr = (char*)Ptr + 2; + Address += 2; + Len -= 2; + } + + if (Len >= 1) + { + ReadPciConfigUchar((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + Ptr); + Ptr = (char*)Ptr + 1; + Address++; + Len--; + } + + return Length - Len; +} + + +static ULONG STDCALL +HalpSetPciData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + PVOID Ptr = Buffer; + ULONG Address = Offset; + ULONG Len = Length; + ULONG Vendor; + UCHAR HeaderType; + + DPRINT("HalpSetPciData() called.\n"); + DPRINT(" BusNumber %lu\n", BusNumber); + DPRINT(" SlotNumber %lu\n", SlotNumber); + DPRINT(" Offset 0x%lx\n", Offset); + DPRINT(" Length 0x%lx\n", Length); + + if ((Length == 0) || (BusConfigType == 0)) + return 0; + + ReadPciConfigUlong((UCHAR)BusNumber, + (UCHAR)(SlotNumber & 0x1F), + 0x00, + &Vendor); + /* some broken boards return 0 if a slot is empty: */ + if (Vendor == 0xFFFFFFFF || Vendor == 0) + return 0; + + + /* 0E=PCI_HEADER_TYPE */ + ReadPciConfigUchar((UCHAR)BusNumber, + (UCHAR)(SlotNumber & 0x1F), + 0x0E, + &HeaderType); + if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0)) + return 0; + + ReadPciConfigUlong((UCHAR)BusNumber, + (UCHAR)SlotNumber, + 0x00, + &Vendor); + /* some broken boards return 0 if a slot is empty: */ + if (Vendor == 0xFFFFFFFF || Vendor == 0) + return 0; + + if ((Address & 1) && (Len >= 1)) + { + WritePciConfigUchar((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + *(PUCHAR)Ptr); + Ptr = (char*)Ptr + 1; + Address++; + Len--; + } + + if ((Address & 2) && (Len >= 2)) + { + WritePciConfigUshort((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + *(PUSHORT)Ptr); + Ptr = (char*)Ptr + 2; + Address += 2; + Len -= 2; + } + + while (Len >= 4) + { + WritePciConfigUlong((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + *(PULONG)Ptr); + Ptr = (char*)Ptr + 4; + Address += 4; + Len -= 4; + } + + if (Len >= 2) + { + WritePciConfigUshort((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + *(PUSHORT)Ptr); + Ptr = (char*)Ptr + 2; + Address += 2; + Len -= 2; + } + + if (Len >= 1) + { + WritePciConfigUchar((UCHAR)BusNumber, + (UCHAR)SlotNumber, + (UCHAR)Address, + *(PUCHAR)Ptr); + Ptr = (char*)Ptr + 1; + Address++; + Len--; + } + + return Length - Len; +} + + +static ULONG +GetBusConfigType(VOID) +{ + ULONG Value; + KIRQL oldIrql; + + DPRINT("GetBusConfigType() called\n"); + + KeAcquireSpinLock(&PciLock, &oldIrql); + + DPRINT("Checking configuration type 1:"); + WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01); + Value = READ_PORT_ULONG((PULONG)0xCF8); + WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000); + if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000) + { + WRITE_PORT_ULONG((PULONG)0xCF8, Value); + KeReleaseSpinLock(&PciLock, oldIrql); + DPRINT(" Success!\n"); + return 1; + } + WRITE_PORT_ULONG((PULONG)0xCF8, Value); + DPRINT(" Unsuccessful!\n"); + + DPRINT("Checking configuration type 2:"); + WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00); + WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00); + WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00); + if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 && + READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00) + { + KeReleaseSpinLock(&PciLock, oldIrql); + DPRINT(" Success!\n"); + return 2; + } + KeReleaseSpinLock(&PciLock, oldIrql); + DPRINT(" Unsuccessful!\n"); + + DPRINT("No pci bus found!\n"); + return 0; +} + + +static ULONG STDCALL +HalpGetPciInterruptVector(PVOID BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity) +{ + ULONG Vector = IRQ2VECTOR(BusInterruptVector); + *Irql = VECTOR2IRQL(Vector); + *Affinity = 0xFFFFFFFF; + return Vector; +} + +static BOOLEAN STDCALL +HalpTranslatePciAddress(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress) +{ + if (*AddressSpace == 0) + { + /* memory space */ + + } + else if (*AddressSpace == 1) + { + /* io space */ + + } + else + { + /* other */ + return FALSE; + } + + TranslatedAddress->QuadPart = BusAddress.QuadPart; + + return TRUE; +} + +/* + * Find the extent of a PCI decode.. + */ +static ULONG STDCALL +PciSize(ULONG Base, ULONG Mask) +{ + ULONG Size = Mask & Base; /* Find the significant bits */ + Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */ + return Size; +} + +static NTSTATUS STDCALL +HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + ULONG DataSize; + PCI_COMMON_CONFIG PciConfig; + SIZE_T Address; + SIZE_T ResourceCount; + ULONG Size[PCI_TYPE0_ADDRESSES]; + NTSTATUS Status = STATUS_SUCCESS; + UCHAR Offset; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + + /* FIXME: Should handle 64-bit addresses */ + + DataSize = HalpGetPciData(BusHandler, + BusNumber, + SlotNumber, + &PciConfig, + 0, + PCI_COMMON_HDR_LENGTH); + if (PCI_COMMON_HDR_LENGTH != DataSize) + { + return STATUS_UNSUCCESSFUL; + } + + /* Read the PCI configuration space for the device and store base address and + size information in temporary storage. Count the number of valid base addresses */ + ResourceCount = 0; + for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++) + { + if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address]) + { + PciConfig.u.type0.BaseAddresses[Address] = 0; + } + if (0 != PciConfig.u.type0.BaseAddresses[Address]) + { + ResourceCount++; + Offset = FIELD_OFFSET(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]); + Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, 0xffffffff); + if (! NT_SUCCESS(Status)) + { + WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, + PciConfig.u.type0.BaseAddresses[Address]); + return Status; + } + Status = ReadPciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, + Offset, Size + Address); + if (! NT_SUCCESS(Status)) + { + WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, + PciConfig.u.type0.BaseAddresses[Address]); + return Status; + } + Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, + PciConfig.u.type0.BaseAddresses[Address]); + if (! NT_SUCCESS(Status)) + { + return Status; + } + } + } + + if (0 != PciConfig.u.type0.InterruptLine) + { + ResourceCount++; + } + + /* Allocate output buffer and initialize */ + *AllocatedResources = ExAllocatePoolWithTag(PagedPool, + sizeof(CM_RESOURCE_LIST) + + (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), + TAG_PCI); + if (NULL == *AllocatedResources) + { + return STATUS_NO_MEMORY; + } + (*AllocatedResources)->Count = 1; + (*AllocatedResources)->List[0].InterfaceType = PCIBus; + (*AllocatedResources)->List[0].BusNumber = BusNumber; + (*AllocatedResources)->List[0].PartialResourceList.Version = 1; + (*AllocatedResources)->List[0].PartialResourceList.Revision = 1; + (*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount; + Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors; + + /* Store configuration information */ + for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++) + { + if (0 != PciConfig.u.type0.BaseAddresses[Address]) + { + if (PCI_BASE_ADDRESS_SPACE_MEMORY == + (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE)) + { + Descriptor->Type = CmResourceTypeMemory; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */ + Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE; /* FIXME Just a guess */ + Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK); + Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK); + } + else if (PCI_BASE_ADDRESS_SPACE_IO == + (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE)) + { + Descriptor->Type = CmResourceTypePort; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */ + Descriptor->Flags = CM_RESOURCE_PORT_IO; /* FIXME Just a guess */ + Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK; + Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff); + } + else + { + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; + } + Descriptor++; + } + } + + if (0 != PciConfig.u.type0.InterruptLine) + { + Descriptor->Type = CmResourceTypeInterrupt; + Descriptor->ShareDisposition = CmResourceShareShared; /* FIXME Just a guess */ + Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; /* FIXME Just a guess */ + Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine; + Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine; + Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF; + + Descriptor++; + } + + ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount); + + /* FIXME: Should store the resources in the registry resource map */ + + return Status; +} + + +VOID +HalpInitPciBus(VOID) +{ + PBUS_HANDLER BusHandler; + + DPRINT("HalpInitPciBus() called.\n"); + + KeInitializeSpinLock (&PciLock); + + BusConfigType = GetBusConfigType(); + if (BusConfigType == 0) + return; + + DPRINT("Bus configuration %lu used\n", BusConfigType); + + /* pci bus (bus 0) handler */ + BusHandler = HalpAllocateBusHandler(PCIBus, + PCIConfiguration, + 0); + BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData; + BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetPciInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslatePciAddress; +// BusHandler->AdjustResourceList = +// (pGetSetBusData)HalpAdjustPciResourceList; + BusHandler->AssignSlotResources = + (pAssignSlotResources)HalpAssignPciSlotResources; + if (NULL != HalpHooks.InitPciBus) + { + HalpHooks.InitPciBus(0, BusHandler); + } + + + /* agp bus (bus 1) handler */ + BusHandler = HalpAllocateBusHandler(PCIBus, + PCIConfiguration, + 1); + BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData; + BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetPciInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslatePciAddress; +// BusHandler->AdjustResourceList = +// (pGetSetBusData)HalpAdjustPciResourceList; + BusHandler->AssignSlotResources = + (pAssignSlotResources)HalpAssignPciSlotResources; + if (NULL != HalpHooks.InitPciBus) + { + HalpHooks.InitPciBus(1, BusHandler); + } + + + /* PCI bus (bus 2) handler */ + BusHandler = HalpAllocateBusHandler(PCIBus, + PCIConfiguration, + 2); + BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData; + BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetPciInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslatePciAddress; +// BusHandler->AdjustResourceList = +// (pGetSetBusData)HalpAdjustPciResourceList; + BusHandler->AssignSlotResources = + (pAssignSlotResources)HalpAssignPciSlotResources; + if (NULL != HalpHooks.InitPciBus) + { + HalpHooks.InitPciBus(2, BusHandler); + } + + DPRINT("HalpInitPciBus() finished.\n"); +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/portio.c b/reactos/hal/halppc/generic/portio.c new file mode 100644 index 00000000000..c665beb1836 --- /dev/null +++ b/reactos/hal/halppc/generic/portio.c @@ -0,0 +1,289 @@ +/* $Id: portio.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/portio.c + * PURPOSE: Port I/O functions + * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de) + * UPDATE HISTORY: + * Created 18/10/99 + */ + +#include +#define NDEBUG +#include + +/* FUNCTIONS ****************************************************************/ + +/* + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + +#if defined(__GNUC__) + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:") +#else +#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80") +#endif + +#elif defined(_MSC_VER) + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f: +#else +#define __SLOW_DOWN_IO __asm out 0x80, al +#endif + +#else +#error Unknown compiler for inline assembler +#endif + + +#ifdef REALLY_SLOW_IO +#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; } +#else +#define SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +extern int GetPhysByte(int Addr); +extern void SetPhysByte(int Addr, int Val); +extern int GetPhysWord(int Addr); +extern void SetPhysWord(int Addr, int Val); +extern int GetPhys(int Addr); +extern void SetPhys(int Addr, int Val); + +__asm__("\t.globl GetPhys\n" + "GetPhys:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "isync\n\t" + "sync\n\t" + "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ + "mtmsr 5\n\t" + "isync\n\t" + "sync\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl GetPhysWord\n" + "GetPhysWord:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,6\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "isync\n\t" + "sync\n\t" + "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ + "mtmsr 5\n\t" + "isync\n\t" + "sync\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl GetPhysByte\n" + "GetPhysByte:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,7\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "isync\n\t" + "sync\n\t" + "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ + "mtmsr 5\n\t" + "isync\n\t" + "sync\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl SetPhys\n" + "SetPhys:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,4\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "sync\n\t" + "eieio\n\t" + "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" + "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl SetPhysWord\n" + "SetPhysWord:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,6\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "sync\n\t" + "eieio\n\t" + "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" + "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +__asm__("\t.globl SetPhysByte\n" + "SetPhysByte:\t\n" + "mflr 0\n\t" + "stwu 0,-16(1)\n\t" + "mfmsr 5\n\t" + "xori 3,3,7\n\t" /* Undo effects of LE without swapping */ + "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ + "mtmsr 6\n\t" + "sync\n\t" + "eieio\n\t" + "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */ + "dcbst 0,3\n\t" + "mtmsr 5\n\t" + "sync\n\t" + "eieio\n\t" + "mr 3,4\n\t" + "lwz 0,0(1)\n\t" + "addi 1,1,16\n\t" + "mtlr 0\n\t" + "blr" + ); + +VOID STDCALL +READ_PORT_BUFFER_UCHAR (PUCHAR Port, + PUCHAR Buffer, + ULONG Count) +{ + while(Count--) { *Buffer++ = GetPhysByte((ULONG)Port); } +} + +VOID STDCALL +READ_PORT_BUFFER_USHORT (PUSHORT Port, + PUSHORT Buffer, + ULONG Count) +{ + while(Count--) { *Buffer++ = GetPhysWord((ULONG)Port); } +} + +VOID STDCALL +READ_PORT_BUFFER_ULONG (PULONG Port, + PULONG Buffer, + ULONG Count) +{ + while(Count--) { *Buffer++ = GetPhys((ULONG)Port); } +} + +UCHAR STDCALL +READ_PORT_UCHAR (PUCHAR Port) +{ + return GetPhys((ULONG)Port); +} + +USHORT STDCALL +READ_PORT_USHORT (PUSHORT Port) +{ + return GetPhysWord((ULONG)Port); +} + +ULONG STDCALL +READ_PORT_ULONG (PULONG Port) +{ + return GetPhys((ULONG)Port); +} + +VOID STDCALL +WRITE_PORT_BUFFER_UCHAR (PUCHAR Port, + PUCHAR Buffer, + ULONG Count) +{ + while(Count--) { SetPhysByte((ULONG)Port, *Buffer++); } +} + +VOID STDCALL +WRITE_PORT_BUFFER_USHORT (PUSHORT Port, + PUSHORT Buffer, + ULONG Count) +{ + while(Count--) { SetPhysWord((ULONG)Port, *Buffer++); } +} + +VOID STDCALL +WRITE_PORT_BUFFER_ULONG (PULONG Port, + PULONG Buffer, + ULONG Count) +{ + while(Count--) { SetPhys((ULONG)Port, *Buffer++); } +} + +VOID STDCALL +WRITE_PORT_UCHAR (PUCHAR Port, + UCHAR Value) +{ + SetPhysByte((ULONG)Port, Value); +} + +VOID STDCALL +WRITE_PORT_USHORT (PUSHORT Port, + USHORT Value) +{ + SetPhysWord((ULONG)Port, Value); +} + +VOID STDCALL +WRITE_PORT_ULONG (PULONG Port, + ULONG Value) +{ + SetPhys((ULONG)Port, Value); +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/processor.c b/reactos/hal/halppc/generic/processor.c new file mode 100644 index 00000000000..25867253203 --- /dev/null +++ b/reactos/hal/halppc/generic/processor.c @@ -0,0 +1,50 @@ +/* $Id: processor.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: hal/halx86/generic/processor.c + * PURPOSE: Intel MultiProcessor specification support + * PROGRAMMER: David Welch (welch@cwcom.net) + * Casper S. Hornstrup (chorns@users.sourceforge.net) + * NOTES: Parts adapted from linux SMP code + * UPDATE HISTORY: + * 22/05/1998 DW Created + * 12/04/2001 CSH Added MultiProcessor specification support + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +VOID STDCALL +HalInitializeProcessor(ULONG ProcessorNumber, + PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock); + /* Set default IDR */ + KeGetPcr()->IDR = 0xFFFFFFFB; + KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT; +} + +BOOLEAN STDCALL +HalAllProcessorsStarted (VOID) +{ + DPRINT("HalAllProcessorsStarted()\n"); + + return TRUE; +} + +BOOLEAN STDCALL +HalStartNextProcessor(ULONG Unknown1, + ULONG ProcessorStack) +{ + DPRINT("HalStartNextProcessor(0x%lx 0x%lx)\n", Unknown1, ProcessorStack); + + return TRUE; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/pwroff.c b/reactos/hal/halppc/generic/pwroff.c new file mode 100644 index 00000000000..cf6be7555b9 --- /dev/null +++ b/reactos/hal/halppc/generic/pwroff.c @@ -0,0 +1,121 @@ +/* $Id: pwroff.c 23907 2006-09-04 05:52:23Z arty $ + * + * FILE : reactos/hal/x86/apm.c + * DESCRIPTION: Turn CPU off... + * PROJECT : ReactOS Operating System + * AUTHOR : D. Lindauer (July 11 1997) + * NOTE : This program is public domain + * REVISIONS : + * 1999-12-26 + */ + +#define APM_FUNCTION_AVAILABLE 0x5300 +#define APM_FUNCTION_CONNREAL 0x5301 +#define APM_FUNCTION_POWEROFF 0x5307 +#define APM_FUNCTION_ENABLECPU 0x530d +#define APM_FUNCTION_ENABLEAPM 0x530e + +#define APM_DEVICE_BIOS 0 +#define APM_DEVICE_ALL 1 + +#define APM_MODE_DISABLE 0 +#define APM_MODE_ENABLE 1 + + + +#if defined(__GNUC__) + +nopm db 'No power management functionality',10,13,'$' +errmsg db 'Power management error',10,13,'$' +wrongver db 'Need APM version 1.1 or better',10,13,'$' +; +; Entry point +; +go: + mov dx,offset nopm + jc error + cmp ax,101h ; See if version 1.1 or greater + mov dx,offset wrongver + jc error + + mov [ver],ax + mov ax,5301h ; Do a real mode connection + mov bx,0 ; device = BIOS + int 15h + jnc noconerr + + cmp ah,2 ; Pass if already connected + mov dx,offset errmsg ; else error + jnz error +noconerr: + mov ax,530eh ; Enable latest version of APM + mov bx,0 ; device = BIOS + mov cx,[ver] ; version + int 15h + mov dx,offset errmsg + jc error + + mov ax,530dh ; Now engage and enable CPU management + mov bx,1 ; device = all + mov cx,1 ; enable + int 15h + mov dx,offset errmsg + jc error + + mov ax,530fh + mov bx,1 ; device = ALL + mov cx,1 ; enable + int 15h + mov dx,offset errmsg + jc error + + mov dx,offset errmsg +error: + call print + mov ax,4c01h + int 21h + int 3 + end start + + +BOOLEAN +ApmCall ( + DWORD Function, + DWORD Device, + DWORD Mode + ) +{ + /* AX <== Function */ + /* BX <== Device */ + /* CX <== Mode */ + __asm__("int 21\n"); /* 0x15 */ +} + +#elif defined(_MSC_VER) +#else +#error Unknown compiler for inline assembler +#endif + + +BOOLEAN +HalPowerOff (VOID) +{ + ApmCall ( + APM_FUNCTION_AVAILABLE, + APM_DEVICE_BIOS, + 0 + ); + ApmCall ( + APM_FUNCTION_ENABLEAPM, + ); + /* Shutdown CPU */ + ApmCall ( + APM_FUNCTION_POWEROFF, + APM_DEVICE_ALL, + 3 + ); + return TRUE; +} + + +/* EOF */ diff --git a/reactos/hal/halppc/generic/reboot.c b/reactos/hal/halppc/generic/reboot.c new file mode 100644 index 00000000000..89ab5c0d221 --- /dev/null +++ b/reactos/hal/halppc/generic/reboot.c @@ -0,0 +1,41 @@ +/* $Id: reboot.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/reboot.c + * PURPOSE: Reboot functions. + * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de) + * UPDATE HISTORY: + * Created 11/10/99 + */ + +#include +#define NDEBUG +#include + +typedef void (*void_fun)(); +static VOID +HalReboot (VOID) +{ + void_fun reset_vector = (void_fun)0xfff00100; + reset_vector(); +} + + +VOID STDCALL +HalReturnToFirmware ( + FIRMWARE_REENTRY Action + ) +{ + if (Action == HalHaltRoutine) + { + DbgPrint ("HalReturnToFirmware called!\n"); + DbgBreakPoint (); + } + else if (Action == HalRebootRoutine) + { + HalReboot (); + } +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/resource.c b/reactos/hal/halppc/generic/resource.c new file mode 100644 index 00000000000..acf17ff151d --- /dev/null +++ b/reactos/hal/halppc/generic/resource.c @@ -0,0 +1,31 @@ +/* $Id: resource.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: hal/halx86/generic/resource.c + * PURPOSE: Miscellaneous resource functions + * PROGRAMMER: Eric Kohl (ekohl@rz-online.de) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +/* FUNCTIONS ****************************************************************/ + +VOID STDCALL +HalReportResourceUsage(VOID) +{ + /* + * FIXME: Report all resources used by hal. + * Calls IoReportHalResourceUsage() + */ + + /* Initialize PCI bus. */ + HalpInitPciBus (); +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/spinlock.c b/reactos/hal/halppc/generic/spinlock.c new file mode 100644 index 00000000000..30d66bb230b --- /dev/null +++ b/reactos/hal/halppc/generic/spinlock.c @@ -0,0 +1,191 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/halx86/up/spinlock.c + * PURPOSE: Implements spinlocks + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ****************************************************************/ + +#include +#define NDEBUG +#include + +#undef KeAcquireSpinLock +#undef KeReleaseSpinLock +#undef KeLowerIrql +#undef KeRaiseIrql + +/* FUNCTIONS ***************************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +KeLowerIrql(KIRQL NewIrql) +{ + /* Call the fastcall function */ + KfLowerIrql(NewIrql); +} + +/* + * @implemented + */ +VOID +NTAPI +KeRaiseIrql(KIRQL NewIrql, + PKIRQL OldIrql) +{ + /* Call the fastcall function */ + *OldIrql = KfRaiseIrql(NewIrql); +} + +/* + * @implemented + */ +VOID +NTAPI +KeAcquireSpinLock(PKSPIN_LOCK SpinLock, + PKIRQL OldIrql) +{ + /* Call the fastcall function */ + *OldIrql = KfAcquireSpinLock(SpinLock); +} + +/* + * @implemented + */ +KIRQL +FASTCALL +KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock) +{ + /* Simply raise to dispatch */ + return KfRaiseIrql(DISPATCH_LEVEL); +} + +/* + * @implemented + */ +VOID +NTAPI +KeReleaseSpinLock(PKSPIN_LOCK SpinLock, + KIRQL NewIrql) +{ + /* Call the fastcall function */ + KfReleaseSpinLock(SpinLock, NewIrql); +} + +/* + * @implemented + */ +KIRQL +FASTCALL +KfAcquireSpinLock(PKSPIN_LOCK SpinLock) +{ + /* Simply raise to dispatch */ + return KfRaiseIrql(DISPATCH_LEVEL); +} + +/* + * @implemented + */ +VOID +FASTCALL +KfReleaseSpinLock(PKSPIN_LOCK SpinLock, + KIRQL OldIrql) +{ + /* Simply lower IRQL back */ + KfLowerIrql(OldIrql); +} + +/* + * @implemented + */ +KIRQL +FASTCALL +KeAcquireQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle) +{ + /* Simply raise to dispatch */ + return KfRaiseIrql(DISPATCH_LEVEL); +} + +/* + * @implemented + */ +KIRQL +FASTCALL +KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber) +{ + /* Simply raise to dispatch */ + return KfRaiseIrql(DISPATCH_LEVEL); +} + +/* + * @implemented + */ +VOID +FASTCALL +KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock, + IN PKLOCK_QUEUE_HANDLE LockHandle) +{ + /* Simply raise to dispatch */ + LockHandle->OldIrql = KfRaiseIrql(DISPATCH_LEVEL); +} + +/* + * @implemented + */ +VOID +FASTCALL +KeReleaseQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle, + IN KIRQL OldIrql) +{ + /* Simply lower IRQL back */ + KfLowerIrql(OldIrql); +} + +/* + * @implemented + */ +VOID +FASTCALL +KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle) +{ + /* Simply lower IRQL back */ + KfLowerIrql(LockHandle->OldIrql); +} + +/* + * @implemented + */ +BOOLEAN +FASTCALL +KeTryToAcquireQueuedSpinLockRaiseToSynch(IN PKLOCK_QUEUE_HANDLE LockHandle, + IN PKIRQL OldIrql) +{ + /* Simply raise to dispatch */ + *OldIrql = KfRaiseIrql(DISPATCH_LEVEL); + + /* Always return true on UP Machines */ + return TRUE; +} + +/* + * @implemented + */ +BOOLEAN +FASTCALL +KeTryToAcquireQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle, + IN PKIRQL OldIrql) +{ + /* Simply raise to dispatch */ + *OldIrql = KfRaiseIrql(DISPATCH_LEVEL); + + /* Always return true on UP Machines */ + return TRUE; +} + + +/* EOF */ diff --git a/reactos/hal/halppc/generic/sysbus.c b/reactos/hal/halppc/generic/sysbus.c new file mode 100644 index 00000000000..4955b122cfd --- /dev/null +++ b/reactos/hal/halppc/generic/sysbus.c @@ -0,0 +1,66 @@ +/* $Id: sysbus.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/sysbus.c + * PURPOSE: System bus handler functions + * PROGRAMMER: Eric Kohl (ekohl@rz-online.de) + * UPDATE HISTORY: + * 09/04/2000 Created + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +/* FUNCTIONS ****************************************************************/ + +ULONG STDCALL +HalpGetSystemInterruptVector(PVOID BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity) +{ + ULONG Vector = IRQ2VECTOR(BusInterruptVector); + *Irql = VECTOR2IRQL(Vector); + *Affinity = 0xFFFFFFFF; + return Vector; +} + + +BOOLEAN STDCALL +HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress) +{ + ULONG BaseAddress = 0; + + if (*AddressSpace == 0) + { + /* memory space */ + + } + else if (*AddressSpace == 1) + { + /* io space */ + + } + else + { + /* other */ + return FALSE; + } + + TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress; + + return TRUE; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/sysinfo.c b/reactos/hal/halppc/generic/sysinfo.c new file mode 100644 index 00000000000..a5ccfeb1be7 --- /dev/null +++ b/reactos/hal/halppc/generic/sysinfo.c @@ -0,0 +1,74 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/sysinfo.c + * PURPOSE: Getting system information + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS STDCALL +HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN OUT PVOID Buffer, + OUT PULONG ReturnedLength) +{ + ULONG DataLength; + NTSTATUS Status; + + DPRINT1("HalpQuerySystemInformation() called\n"); + + *ReturnedLength = 0; + + DataLength = 0; + + switch(InformationClass) + { +#if 0 + case HalInstalledBusInformation: + Status = HalpQueryBusInformation(BufferSize, + Buffer, + ReturnedLength); + break; +#endif + + default: + DataLength = 0; + Status = STATUS_INVALID_LEVEL; + break; + } + + if (DataLength != 0) + { + if (DataLength > BufferSize) + DataLength = BufferSize; + +// RtlCopyMemory(); + + *ReturnedLength = DataLength; + } + + return(Status); +} + + +#if 0 +NTSTATUS +HalpSetSystemInformation(VOID) +{ + UNIMPLEMENTED; +} +#endif + +/* EOF */ diff --git a/reactos/hal/halppc/generic/systimer.S b/reactos/hal/halppc/generic/systimer.S new file mode 100644 index 00000000000..285686675a7 --- /dev/null +++ b/reactos/hal/halppc/generic/systimer.S @@ -0,0 +1,48 @@ +/* + * FILE: hal/halx86/generic/timer.S + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: System Timer Interrupt and Management + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +.intel_syntax noprefix + +/* FUNCTIONS *****************************************************************/ + +.globl _HalpClockInterrupt@0 +.func HalpClockInterrupt@0 +_HalpClockInterrupt@0: + + /* Enter trap */ + INT_PROLOG Hci, DoPushFakeErrorCode + + /* Push vector and make stack for IRQL */ + push 0x30 + sub esp, 4 + + /* Begin the interrupt */ + push esp + push 0x30 + push CLOCK2_LEVEL + call _HalBeginSystemInterrupt@12 + + /* Check if it's spurious */ + or al, al + jz Spurious + + /* Do a tick */ + mov eax, 100000 + jmp _KeUpdateSystemTime@0 + +Spurious: + + /* Exit the interrupt */ + add esp, 8 + mov esi, $ + jmp _Kei386EoiHelper@0 +.endfunc + diff --git a/reactos/hal/halppc/generic/time.c b/reactos/hal/halppc/generic/time.c new file mode 100644 index 00000000000..bb81cc01cec --- /dev/null +++ b/reactos/hal/halppc/generic/time.c @@ -0,0 +1,102 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/time.c + * PURPOSE: Getting time information + * UPDATE HISTORY: + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + + +/* MACROS and CONSTANTS ******************************************************/ + +/* macro BCD_INT : convert bcd to int */ +#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f)) + +/* macro INT_BCD : convert int to bcd */ +#define INT_BCD(int) (((int / 10) << 4) + (int % 10)) + + +#define RTC_REGISTER_A 0x0A +#define RTC_REG_A_UIP 0x80 /* Update In Progress bit */ + +#define RTC_REGISTER_B 0x0B + +#define RTC_REGISTER_CENTURY 0x32 + +/* GLOBALS ******************************************************************/ + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN STDCALL +HalQueryRealTimeClock(PTIME_FIELDS Time) +{ + return TRUE; +} + + +VOID STDCALL +HalSetRealTimeClock(PTIME_FIELDS Time) +{ +} + + +BOOLEAN STDCALL +HalGetEnvironmentVariable(PCH Name, + USHORT ValueLength, + PCH Value) +{ + strncpy(Value, "TRUE", ValueLength); + return TRUE; +} + + +BOOLEAN STDCALL +HalSetEnvironmentVariable(PCH Name, + PCH Value) +{ + return TRUE; +} + + +ULONG STDCALL +HalpGetCmosData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + DPRINT("HalpGetCmosData() called.\n"); + DPRINT(" BusNumber %lu\n", BusNumber); + DPRINT(" SlotNumber %lu\n", SlotNumber); + DPRINT(" Offset 0x%lx\n", Offset); + DPRINT(" Length 0x%lx\n", Length); + + return 0; +} + + +ULONG STDCALL +HalpSetCmosData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length) +{ + DPRINT("HalpSetCmosData() called.\n"); + DPRINT(" BusNumber %lu\n", BusNumber); + DPRINT(" SlotNumber %lu\n", SlotNumber); + DPRINT(" Offset 0x%lx\n", Offset); + DPRINT(" Length 0x%lx\n", Length); + + return 0; +} + +/* EOF */ diff --git a/reactos/hal/halppc/generic/timer.c b/reactos/hal/halppc/generic/timer.c new file mode 100644 index 00000000000..9df30825631 --- /dev/null +++ b/reactos/hal/halppc/generic/timer.c @@ -0,0 +1,205 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * Copyright (C) 1999 Gareth Owen , Ramon von Handel + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This software is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write + * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + * MA 02139, USA. + * + */ +/* $Id: timer.c 23907 2006-09-04 05:52:23Z arty $ + * + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/udelay.c + * PURPOSE: Busy waiting + * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) + * UPDATE HISTORY: + * 06/11/99 Created + */ + +/* INCLUDES ***************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +#define TMR_CTRL 0x43 /* I/O for control */ +#define TMR_CNT0 0x40 /* I/O for counter 0 */ +#define TMR_CNT1 0x41 /* I/O for counter 1 */ +#define TMR_CNT2 0x42 /* I/O for counter 2 */ + +#define TMR_SC0 0 /* Select channel 0 */ +#define TMR_SC1 0x40 /* Select channel 1 */ +#define TMR_SC2 0x80 /* Select channel 2 */ + +#define TMR_LOW 0x10 /* RW low byte only */ +#define TMR_HIGH 0x20 /* RW high byte only */ +#define TMR_BOTH 0x30 /* RW both bytes */ + +#define TMR_MD0 0 /* Mode 0 */ +#define TMR_MD1 0x2 /* Mode 1 */ +#define TMR_MD2 0x4 /* Mode 2 */ +#define TMR_MD3 0x6 /* Mode 3 */ +#define TMR_MD4 0x8 /* Mode 4 */ +#define TMR_MD5 0xA /* Mode 5 */ + +#define TMR_BCD 1 /* BCD mode */ + +#define TMR_LATCH 0 /* Latch command */ + +#define TMR_READ 0xF0 /* Read command */ +#define TMR_CNT 0x20 /* CNT bit (Active low, subtract it) */ +#define TMR_STAT 0x10 /* Status bit (Active low, subtract it) */ +#define TMR_CH2 0x8 /* Channel 2 bit */ +#define TMR_CH1 0x4 /* Channel 1 bit */ +#define TMR_CH0 0x2 /* Channel 0 bit */ + +#define MILLISEC 10 /* Number of millisec between interrupts */ +#define HZ (1000 / MILLISEC) /* Number of interrupts per second */ +#define CLOCK_TICK_RATE 1193182 /* Clock frequency of the timer chip */ +#define LATCH (CLOCK_TICK_RATE / HZ) /* Count to program into the timer chip */ +#define PRECISION 8 /* Number of bits to calibrate for delay loop */ + +static BOOLEAN UdelayCalibrated = FALSE; + +/* FUNCTIONS **************************************************************/ + +static BOOLEAN PPCGetEEBit() +{ + ULONG Msr; + __asm__("mfmsr %0" : "=r" (Msr)); + return (Msr & 0x8000) != 0; +} + +/* + * NOTE: This function MUST NOT be optimized by the compiler! + * If it is, it obviously will not delay AT ALL, and the system + * will appear completely frozen at boot since + * HalpCalibrateStallExecution will never return. + * There are three options to stop optimization: + * 1. Use a volatile automatic variable. Making it delay quite a bit + * due to memory accesses, and keeping the code portable. However, + * as this involves memory access it depends on both the CPU cache, + * e.g. if the stack used is already in a cache line or not, and + * whether or not we're MP. If MP, another CPU could (probably would) + * also access RAM at the same time - making the delay imprecise. + * 2. Use compiler-specific #pragma's to disable optimization. + * 3. Use inline assembly, making it equally unportable as #2. + * For supported compilers we use inline assembler. For the others, + * portable plain C. + */ +DECLSPEC_NOINLINE VOID STDCALL +__KeStallExecutionProcessor(ULONG Loops) +{ + ULONG DecInit, DecCount; + if (!Loops) + { + return; + } + __asm__("mfdec %0" : "=r" (DecInit)); + do { + __asm__("mfdec %0" : "=r" (DecCount)); + } while((DecCount - DecInit) < Loops); +} + +VOID +STDCALL +KeStallExecutionProcessor(ULONG Microseconds) +{ + PKIPCR Pcr = (PKIPCR)KeGetPcr(); + LARGE_INTEGER EndCount, CurrentCount; + ULONG NewCount; + __asm__("mfdec %0" : "=r" (NewCount)); + EndCount.QuadPart = NewCount + Microseconds * (ULONGLONG)Pcr->Prcb->MHz; + do + { + __asm__("mfdec %0" : "=r" (NewCount)); + if(NewCount < CurrentCount.LowPart) + CurrentCount.HighPart++; + CurrentCount.LowPart = NewCount; + } + while (CurrentCount.QuadPart < EndCount.QuadPart); +} + +VOID HalpCalibrateStallExecution(VOID) +{ + PKIPCR Pcr; + + if (UdelayCalibrated) + { + return; + } + + UdelayCalibrated = TRUE; + Pcr = (PKIPCR)KeGetPcr(); + + // XXX arty FIXME + /* Pcr->Prcb.MHz = (ULONG)(EndCount.QuadPart - StartCount.QuadPart) / 10000; */ + Pcr->Prcb->MHz = 300; + DPRINT1("%luMHz\n", Pcr->Prcb->MHz); +} + + +VOID STDCALL +HalCalibratePerformanceCounter(ULONG Count) +{ + BOOLEAN InterruptsEnabled = PPCGetEEBit(); + + /* save flags and disable interrupts */ + _disable(); + + __KeStallExecutionProcessor(Count); + + /* restore flags */ + if(InterruptsEnabled) + _enable(); +} + + +LARGE_INTEGER +STDCALL +KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq) +/* + * FUNCTION: Queries the finest grained running count available in the system + * ARGUMENTS: + * PerformanceFreq (OUT) = The routine stores the number of + * performance counter ticks per second here + * RETURNS: The number of performance counter ticks since boot + */ +{ + PKIPCR Pcr; + LARGE_INTEGER Value; + BOOLEAN InterruptsEnabled = PPCGetEEBit(); + + _disable(); + + Pcr = (PKIPCR)KeGetPcr(); + + if (NULL != PerformanceFreq) + { + PerformanceFreq->QuadPart = Pcr->Prcb->MHz * (ULONGLONG)1000000; + } + __asm__("mfdec %0" : "=r" (Value.LowPart)); + + if(InterruptsEnabled) + _enable(); + + return Value; +} + +/* EOF */ diff --git a/reactos/hal/halppc/include/apic.h b/reactos/hal/halppc/include/apic.h new file mode 100644 index 00000000000..7454c210f72 --- /dev/null +++ b/reactos/hal/halppc/include/apic.h @@ -0,0 +1,214 @@ +/* + * + */ + +#ifndef __INTERNAL_HAL_APIC_H +#define __INTERNAL_HAL_APIC_H + +#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */ + +/* APIC Register Address Map */ +#define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */ +#define APIC_VER 0x0030 /* Local APIC Version Register (R) */ +#define APIC_TPR 0x0080 /* Task Priority Register (R/W) */ +#define APIC_APR 0x0090 /* Arbitration Priority Register (R) */ +#define APIC_PPR 0x00A0 /* Processor Priority Register (R) */ +#define APIC_EOI 0x00B0 /* EOI Register (W) */ +#define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */ +#define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */ +#define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */ +#define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */ +#define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */ +#define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */ +#define APIC_ESR 0x0280 /* Error Status Register (R) */ +#define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */ +#define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */ +#define APIC_LVTT 0x0320 /* Local Vector Table (Timer) (R/W) */ +#define APIC_LVTTHMR 0x0330 +#define APIC_LVTPC 0x0340 /* Performance Counter LVT (R/W) */ +#define APIC_LINT0 0x0350 /* Local Vector Table (LINT0) (R/W) */ +#define APIC_LINT1 0x0360 /* Local Vector Table (LINT1) (R/W) */ +#define APIC_LVT3 0x0370 /* Local Vector Table (Error) (R/W) */ +#define APIC_ICRT 0x0380 /* Initial Count Register for Timer (R/W) */ +#define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */ +#define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */ + +#define APIC_ID_MASK (0xF << 24) +#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24) +#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) +#define APIC_VER_MASK 0xFF00FF +#define GET_APIC_VERSION(x) ((x) & 0xFF) +#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF) + +#define APIC_TPR_PRI 0xFF +#define APIC_TPR_INT 0xF0 +#define APIC_TPR_SUB 0xF +#define APIC_TPR_MAX 0xFF /* Maximum priority */ +#define APIC_TPR_MIN 0x20 /* Minimum priority */ + +#define APIC_LDR_MASK (0xFF << 24) + +#define APIC_SIVR_ENABLE (0x1 << 8) +#define APIC_SIVR_FOCUS (0x1 << 9) + +#define APIC_ESR_MASK (0xFE << 0) /* Error Mask */ + +#define APIC_ICR0_VECTOR (0xFF << 0) /* Vector */ +#define APIC_ICR0_DM (0x7 << 8) /* Delivery Mode */ +#define APIC_ICR0_DESTM (0x1 << 11) /* Destination Mode */ +#define APIC_ICR0_DS (0x1 << 12) /* Delivery Status */ +#define APIC_ICR0_LEVEL (0x1 << 14) /* Level */ +#define APIC_ICR0_TM (0x1 << 15) /* Trigger Mode */ +#define APIC_ICR0_DESTS (0x3 << 18) /* Destination Shorthand */ + +/* Delivery Modes */ +#define APIC_DM_FIXED (0x0 << 8) +#define APIC_DM_LOWEST (0x1 << 8) +#define APIC_DM_SMI (0x2 << 8) +#define APIC_DM_REMRD (0x3 << 8) +#define APIC_DM_NMI (0x4 << 8) +#define APIC_DM_INIT (0x5 << 8) +#define APIC_DM_STARTUP (0x6 << 8) +#define APIC_DM_EXTINT (0x7 << 8) +#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7) +#define SET_APIC_DELIVERY_MODE(x,y) (((x) & ~0x700) | ((y) << 8)) + +/* Destination Shorthand values */ +#define APIC_ICR0_DESTS_FIELD (0x0 << 0) +#define APIC_ICR0_DESTS_SELF (0x1 << 18) +#define APIC_ICR0_DESTS_ALL (0x2 << 18) +#define APIC_ICR0_DESTS_ALL_BUT_SELF (0x3 << 18) + +#define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */ +#define APIC_ICR0_LEVEL_ASSERT (0x1 << 14) /* Assert level */ + +#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF) +#define SET_APIC_DEST_FIELD(x) (((x) & 0xFF) << 24) + +#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3) +#define SET_APIC_TIMER_BASE(x) ((x) << 18) +#define APIC_TIMER_BASE_CLKIN 0x0 +#define APIC_TIMER_BASE_TMBASE 0x1 +#define APIC_TIMER_BASE_DIV 0x2 + +#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */ +#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */ +#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */ +#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */ +#define APIC_LVT_MASKED (0x1 << 16) /* Mask */ +#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */ + +#define APIC_LVT3_DM (0x7 << 8) +#define APIC_LVT3_IIPP (0x1 << 13) +#define APIC_LVT3_TM (0x1 << 15) +#define APIC_LVT3_MASKED (0x1 << 16) +#define APIC_LVT3_OS (0x1 << 17) + +#define APIC_TDCR_TMBASE (0x1 << 2) +#define APIC_TDCR_MASK 0x0F +#define APIC_TDCR_2 0x00 +#define APIC_TDCR_4 0x01 +#define APIC_TDCR_8 0x02 +#define APIC_TDCR_16 0x03 +#define APIC_TDCR_32 0x08 +#define APIC_TDCR_64 0x09 +#define APIC_TDCR_128 0x0A +#define APIC_TDCR_1 0x0B + +#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */ +#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */ +#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */ +#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */ +#define APIC_LVT_MASKED (0x1 << 16) /* Mask */ +#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */ + +#define APIC_LVT3_DM (0x7 << 8) +#define APIC_LVT3_IIPP (0x1 << 13) +#define APIC_LVT3_TM (0x1 << 15) +#define APIC_LVT3_MASKED (0x1 << 16) +#define APIC_LVT3_OS (0x1 << 17) + +#define APIC_TDCR_TMBASE (0x1 << 2) +#define APIC_TDCR_MASK 0x0F +#define APIC_TDCR_2 0x00 +#define APIC_TDCR_4 0x01 +#define APIC_TDCR_8 0x02 +#define APIC_TDCR_16 0x03 +#define APIC_TDCR_32 0x08 +#define APIC_TDCR_64 0x09 +#define APIC_TDCR_128 0x0A +#define APIC_TDCR_1 0x0B + +#define APIC_TARGET_SELF 0x100 +#define APIC_TARGET_ALL 0x200 +#define APIC_TARGET_ALL_BUT_SELF 0x300 + +#define APIC_INTEGRATED(version) (version & 0xF0) + +typedef enum { + amPIC = 0, /* IMCR and PIC compatibility mode */ + amVWIRE /* Virtual Wire compatibility mode */ +} APIC_MODE; + +#ifdef CONFIG_SMP +#define MAX_CPU 32 +#else +#define MAX_CPU 1 +#endif + +/* + * Local APIC timer IRQ vector is on a different priority level, + * to work around the 'lost local interrupt if more than 2 IRQ + * sources per level' errata. + */ +#define LOCAL_TIMER_VECTOR 0xEF + +#define IPI_VECTOR 0xFB +#define ERROR_VECTOR 0xFE +#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */ + +/* CPU flags */ +#define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used) */ +#define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */ +#define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor */ +#define CPU_TSC 0x08 /* 1 if the CPU has a time stamp counter */ + +typedef struct _CPU_INFO +{ + UCHAR Flags; /* CPU flags */ + UCHAR APICId; /* Local APIC ID */ + UCHAR APICVersion; /* Local APIC version */ +// UCHAR MaxLVT; /* Number of LVT registers */ + ULONG BusSpeed; /* BUS speed */ + ULONG CoreSpeed; /* Core speed */ + UCHAR Padding[16-12]; /* Padding to 16-byte */ +} CPU_INFO, *PCPU_INFO; + +extern ULONG CPUCount; /* Total number of CPUs */ +extern ULONG BootCPU; /* Bootstrap processor */ +extern ULONG OnlineCPUs; /* Bitmask of online CPUs */ +extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */ + +/* Prototypes */ + +__inline VOID APICWrite(ULONG Offset, ULONG Value); +__inline ULONG APICRead(ULONG Offset); +VOID APICSendIPI(ULONG Target, ULONG Mode); +VOID APICSetup(VOID); +VOID HaliInitBSP(VOID); +VOID APICSyncArbIDs(VOID); +__inline VOID APICSendEOI(VOID); +VOID APICCalibrateTimer(ULONG CPU); +VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack); + +static __inline ULONG ThisCPU(VOID) +{ + return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24; +} + + +#endif + + +/* EOF */ + diff --git a/reactos/hal/halppc/include/bus.h b/reactos/hal/halppc/include/bus.h new file mode 100644 index 00000000000..b231d5ecf22 --- /dev/null +++ b/reactos/hal/halppc/include/bus.h @@ -0,0 +1,133 @@ +/* + + */ + +#ifndef __INTERNAL_HAL_BUS_H +#define __INTERNAL_HAL_BUS_H + + +typedef NTSTATUS +(STDCALL *pAdjustResourceList)(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN OUT PCM_RESOURCE_LIST Resources); + +typedef NTSTATUS +(STDCALL *pAssignSlotResources)(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources); + +typedef ULONG +(STDCALL *pGetSetBusData)(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length); + +typedef ULONG +(STDCALL *pGetInterruptVector)(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity); + +typedef ULONG +(STDCALL *pTranslateBusAddress)(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress); + +typedef struct _BUS_HANDLER +{ + LIST_ENTRY Entry; + INTERFACE_TYPE InterfaceType; + BUS_DATA_TYPE BusDataType; + ULONG BusNumber; + ULONG RefCount; + + pGetSetBusData GetBusData; + pGetSetBusData SetBusData; + pAdjustResourceList AdjustResourceList; + pAssignSlotResources AssignSlotResources; + pGetInterruptVector GetInterruptVector; + pTranslateBusAddress TranslateBusAddress; +} BUS_HANDLER; + + +/* FUNCTIONS *****************************************************************/ + +/* bus.c */ +PBUS_HANDLER +HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType, + BUS_DATA_TYPE BusDataType, + ULONG BusNumber); + +/* sysbus.h */ +ULONG STDCALL +HalpGetSystemInterruptVector(PVOID BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity); + +BOOLEAN STDCALL +HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress); + +/* isa.c */ +ULONG STDCALL +HalpGetIsaInterruptVector(PVOID BusHandler, + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity); + +BOOLEAN STDCALL +HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler, + ULONG BusNumber, + PHYSICAL_ADDRESS BusAddress, + PULONG AddressSpace, + PPHYSICAL_ADDRESS TranslatedAddress); + +/* time.c */ +ULONG STDCALL +HalpGetCmosData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length); + +ULONG STDCALL +HalpSetCmosData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length); + +/* mca.h */ +ULONG STDCALL +HalpGetMicroChannelData(PBUS_HANDLER BusHandler, + ULONG BusNumber, + ULONG SlotNumber, + PVOID Buffer, + ULONG Offset, + ULONG Length); + +#endif /* __INTERNAL_HAL_BUS_H */ + +/* EOF */ + diff --git a/reactos/hal/halppc/include/hal.h b/reactos/hal/halppc/include/hal.h new file mode 100644 index 00000000000..b15a4d9800d --- /dev/null +++ b/reactos/hal/halppc/include/hal.h @@ -0,0 +1,37 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Hardware Abstraction Layer + * FILE: hal/halx86/include/hal.h + * PURPOSE: HAL Header + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +/* C Headers */ +#include + +/* IFS/DDK/NDK Headers */ +#include +#include +#include +#include +#include +#include +#include + +#define KPCR_BASE 0xFF000000 // HACK! + +/* Internal HAL Headers */ +#include "apic.h" +#include "bus.h" +#include "halirq.h" +#include "haldma.h" +#include "halp.h" +#include "mps.h" +#include "ioapic.h" + +/* Helper Header */ +#include + +/* EOF */ diff --git a/reactos/hal/halppc/include/haldma.h b/reactos/hal/halppc/include/haldma.h new file mode 100644 index 00000000000..59ddb9338a0 --- /dev/null +++ b/reactos/hal/halppc/include/haldma.h @@ -0,0 +1,383 @@ +#ifndef HALDMA_H +#define HALDMA_H + +/* + * DMA Page Register Structure + * 080 DMA RESERVED + * 081 DMA Page Register (channel 2) + * 082 DMA Page Register (channel 3) + * 083 DMA Page Register (channel 1) + * 084 DMA RESERVED + * 085 DMA RESERVED + * 086 DMA RESERVED + * 087 DMA Page Register (channel 0) + * 088 DMA RESERVED + * 089 PS/2-DMA Page Register (channel 6) + * 08A PS/2-DMA Page Register (channel 7) + * 08B PS/2-DMA Page Register (channel 5) + * 08C PS/2-DMA RESERVED + * 08D PS/2-DMA RESERVED + * 08E PS/2-DMA RESERVED + * 08F PS/2-DMA Page Register (channel 4) + */ + +typedef struct _DMA_PAGE +{ + UCHAR Reserved1; + UCHAR Channel2; + UCHAR Channel3; + UCHAR Channel1; + UCHAR Reserved2[3]; + UCHAR Channel0; + UCHAR Reserved3; + UCHAR Channel6; + UCHAR Channel7; + UCHAR Channel5; + UCHAR Reserved4[3]; + UCHAR Channel4; +} DMA_PAGE, *PDMA_PAGE; + +/* + * DMA Channel Mask Register Structure + * + * MSB LSB + * x x x x x x x x + * ------------------- - ----- + * | | | 00 - Select channel 0 mask bit + * | | \---- 01 - Select channel 1 mask bit + * | | 10 - Select channel 2 mask bit + * | | 11 - Select channel 3 mask bit + * | | + * | \---------- 0 - Clear mask bit + * | 1 - Set mask bit + * | + * \----------------------- xx - Reserved + */ + +typedef struct _DMA_CHANNEL_MASK +{ + UCHAR Channel: 2; + UCHAR SetMask: 1; + UCHAR Reserved: 5; +} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK; + +/* + * DMA Mask Register Structure + * + * MSB LSB + * x x x x x x x x + * \---/ - - ----- ----- + * | | | | | 00 - Channel 0 select + * | | | | \---- 01 - Channel 1 select + * | | | | 10 - Channel 2 select + * | | | | 11 - Channel 3 select + * | | | | + * | | | | 00 - Verify transfer + * | | | \------------ 01 - Write transfer + * | | | 10 - Read transfer + * | | | + * | | \-------------------- 0 - Autoinitialized + * | | 1 - Non-autoinitialized + * | | + * | \------------------------ 0 - Address increment select + * | + * | 00 - Demand mode + * \------------------------------ 01 - Single mode + * 10 - Block mode + * 11 - Cascade mode + */ + +typedef union _DMA_MODE +{ + struct + { + UCHAR Channel: 2; + UCHAR TransferType: 2; + UCHAR AutoInitialize: 1; + UCHAR AddressDecrement: 1; + UCHAR RequestMode: 2; + }; + UCHAR Byte; +} DMA_MODE, *PDMA_MODE; + +/* + * DMA Extended Mode Register Structure + * + * MSB LSB + * x x x x x x x x + * - - ----- ----- ----- + * | | | | | 00 - Channel 0 select + * | | | | \---- 01 - Channel 1 select + * | | | | 10 - Channel 2 select + * | | | | 11 - Channel 3 select + * | | | | + * | | | | 00 - 8-bit I/O, by bytes + * | | | \------------ 01 - 16-bit I/O, by words, address shifted + * | | | 10 - 32-bit I/O, by bytes + * | | | 11 - 16-bit I/O, by bytes + * | | | + * | | \---------------------- 00 - Compatible + * | | 01 - Type A + * | | 10 - Type B + * | | 11 - Burst + * | | + * | \---------------------------- 0 - Terminal Count is Output + * | + * \---------------------------------0 - Disable Stop Register + * 1 - Enable Stop Register + */ + +typedef union _DMA_EXTENDED_MODE +{ + struct + { + UCHAR ChannelNumber: 2; + UCHAR TransferSize: 2; + UCHAR TimingMode: 2; + UCHAR TerminalCountIsOutput: 1; + UCHAR EnableStopRegister: 1; + }; + UCHAR Byte; +} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE; + +/* DMA Extended Mode Register Transfer Sizes */ +#define B_8BITS 0 +#define W_16BITS 1 +#define B_32BITS 2 +#define B_16BITS 3 + +/* DMA Extended Mode Register Timing */ +#define COMPATIBLE_TIMING 0 +#define TYPE_A_TIMING 1 +#define TYPE_B_TIMING 2 +#define BURST_TIMING 3 + +/* Channel Stop Registers for each Channel */ +typedef struct _DMA_CHANNEL_STOP +{ + UCHAR ChannelLow; + UCHAR ChannelMid; + UCHAR ChannelHigh; + UCHAR Reserved; +} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP; + +/* Transfer Types */ +#define VERIFY_TRANSFER 0x00 +#define READ_TRANSFER 0x01 +#define WRITE_TRANSFER 0x02 + +/* Request Modes */ +#define DEMAND_REQUEST_MODE 0x00 +#define SINGLE_REQUEST_MODE 0x01 +#define BLOCK_REQUEST_MODE 0x02 +#define CASCADE_REQUEST_MODE 0x03 + +#define DMA_SETMASK 4 +#define DMA_CLEARMASK 0 +#define DMA_READ 4 +#define DMA_WRITE 8 +#define DMA_SINGLE_TRANSFER 0x40 +#define DMA_AUTO_INIT 0x10 + +typedef struct _DMA1_ADDRESS_COUNT +{ + UCHAR DmaBaseAddress; + UCHAR DmaBaseCount; +} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT; + +typedef struct _DMA2_ADDRESS_COUNT +{ + UCHAR DmaBaseAddress; + UCHAR Reserved1; + UCHAR DmaBaseCount; + UCHAR Reserved2; +} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT; + +typedef struct _DMA1_CONTROL +{ + DMA1_ADDRESS_COUNT DmaAddressCount[4]; + UCHAR DmaStatus; + UCHAR DmaRequest; + UCHAR SingleMask; + UCHAR Mode; + UCHAR ClearBytePointer; + UCHAR MasterClear; + UCHAR ClearMask; + UCHAR AllMask; +} DMA1_CONTROL, *PDMA1_CONTROL; + +typedef struct _DMA2_CONTROL +{ + DMA2_ADDRESS_COUNT DmaAddressCount[4]; + UCHAR DmaStatus; + UCHAR Reserved1; + UCHAR DmaRequest; + UCHAR Reserved2; + UCHAR SingleMask; + UCHAR Reserved3; + UCHAR Mode; + UCHAR Reserved4; + UCHAR ClearBytePointer; + UCHAR Reserved5; + UCHAR MasterClear; + UCHAR Reserved6; + UCHAR ClearMask; + UCHAR Reserved7; + UCHAR AllMask; + UCHAR Reserved8; +} DMA2_CONTROL, *PDMA2_CONTROL; + +/* This structure defines the I/O Map of the 82537 controller. */ +typedef struct _EISA_CONTROL +{ + /* DMA Controller 1 */ + DMA1_CONTROL DmaController1; /* 00h-0Fh */ + UCHAR Reserved1[16]; /* 0Fh-1Fh */ + + /* Interrupt Controller 1 (PIC) */ + UCHAR Pic1Operation; /* 20h */ + UCHAR Pic1Interrupt; /* 21h */ + UCHAR Reserved2[30]; /* 22h-3Fh */ + + /* Timer */ + UCHAR TimerCounter; /* 40h */ + UCHAR TimerMemoryRefresh; /* 41h */ + UCHAR Speaker; /* 42h */ + UCHAR TimerOperation; /* 43h */ + UCHAR TimerMisc; /* 44h */ + UCHAR Reserved3[2]; /* 45-46h */ + UCHAR TimerCounterControl; /* 47h */ + UCHAR TimerFailSafeCounter; /* 48h */ + UCHAR Reserved4; /* 49h */ + UCHAR TimerCounter2; /* 4Ah */ + UCHAR TimerOperation2; /* 4Bh */ + UCHAR Reserved5[20]; /* 4Ch-5Fh */ + + /* NMI / Keyboard / RTC */ + UCHAR Keyboard; /* 60h */ + UCHAR NmiStatus; /* 61h */ + UCHAR Reserved6[14]; /* 62h-6Fh */ + UCHAR NmiEnable; /* 70h */ + UCHAR Reserved7[15]; /* 71h-7Fh */ + + /* DMA Page Registers Controller 1 */ + DMA_PAGE DmaController1Pages; /* 80h-8Fh */ + UCHAR Reserved8[16]; /* 90h-9Fh */ + + /* Interrupt Controller 2 (PIC) */ + UCHAR Pic2Operation; /* 0A0h */ + UCHAR Pic2Interrupt; /* 0A1h */ + UCHAR Reserved9[30]; /* 0A2h-0BFh */ + + /* DMA Controller 2 */ + DMA1_CONTROL DmaController2; /* 0C0h-0CFh */ + + /* System Reserved Ports */ + UCHAR SystemReserved[816]; /* 0D0h-3FFh */ + + /* Extended DMA Registers, Controller 1 */ + UCHAR DmaHighByteCount1[8]; /* 400h-407h */ + UCHAR Reserved10[2]; /* 408h-409h */ + UCHAR DmaChainMode1; /* 40Ah */ + UCHAR DmaExtendedMode1; /* 40Bh */ + UCHAR DmaBufferControl; /* 40Ch */ + UCHAR Reserved11[84]; /* 40Dh-460h */ + UCHAR ExtendedNmiControl; /* 461h */ + UCHAR NmiCommand; /* 462h */ + UCHAR Reserved12; /* 463h */ + UCHAR BusMaster; /* 464h */ + UCHAR Reserved13[27]; /* 465h-47Fh */ + + /* DMA Page Registers Controller 2 */ + DMA_PAGE DmaController2Pages; /* 480h-48Fh */ + UCHAR Reserved14[48]; /* 490h-4BFh */ + + /* Extended DMA Registers, Controller 2 */ + UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */ + + /* Edge/Level Control Registers */ + UCHAR Pic1EdgeLevel; /* 4D0h */ + UCHAR Pic2EdgeLevel; /* 4D1h */ + UCHAR Reserved15[2]; /* 4D2h-4D3h */ + + /* Extended DMA Registers, Controller 2 */ + UCHAR DmaChainMode2; /* 4D4h */ + UCHAR Reserved16; /* 4D5h */ + UCHAR DmaExtendedMode2; /* 4D6h */ + UCHAR Reserved17[9]; /* 4D7h-4DFh */ + + /* DMA Stop Registers */ + DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */ +} EISA_CONTROL, *PEISA_CONTROL; + +typedef struct _ROS_MAP_REGISTER_ENTRY +{ + PVOID VirtualAddress; + PHYSICAL_ADDRESS PhysicalAddress; + ULONG Counter; +} ROS_MAP_REGISTER_ENTRY, *PROS_MAP_REGISTER_ENTRY; + +struct _ADAPTER_OBJECT { + /* + * New style DMA object definition. The fact that it is at the beginning + * of the ADAPTER_OBJECT structure allows us to easily implement the + * fallback implementation of IoGetDmaAdapter. + */ + DMA_ADAPTER DmaHeader; + + /* + * For normal adapter objects pointer to master adapter that takes care + * of channel allocation. For master adapter set to NULL. + */ + struct _ADAPTER_OBJECT *MasterAdapter; + + ULONG MapRegistersPerChannel; + PVOID AdapterBaseVa; + PROS_MAP_REGISTER_ENTRY MapRegisterBase; + + ULONG NumberOfMapRegisters; + ULONG CommittedMapRegisters; + + PWAIT_CONTEXT_BLOCK CurrentWcb; + KDEVICE_QUEUE ChannelWaitQueue; + PKDEVICE_QUEUE RegisterWaitQueue; + LIST_ENTRY AdapterQueue; + KSPIN_LOCK SpinLock; + PRTL_BITMAP MapRegisters; + PUCHAR PagePort; + UCHAR ChannelNumber; + UCHAR AdapterNumber; + USHORT DmaPortAddress; + DMA_MODE AdapterMode; + BOOLEAN NeedsMapRegisters; + BOOLEAN MasterDevice; + BOOLEAN Width16Bits; + BOOLEAN ScatterGather; + BOOLEAN IgnoreCount; + BOOLEAN Dma32BitAddresses; + BOOLEAN Dma64BitAddresses; + LIST_ENTRY AdapterList; +} ADAPTER_OBJECT; + +typedef struct _GROW_WORK_ITEM { + WORK_QUEUE_ITEM WorkQueueItem; + PADAPTER_OBJECT AdapterObject; + ULONG NumberOfMapRegisters; +} GROW_WORK_ITEM, *PGROW_WORK_ITEM; + +#define MAP_BASE_SW_SG 1 + +PADAPTER_OBJECT STDCALL +HalpDmaAllocateMasterAdapter(VOID); + +PDMA_ADAPTER STDCALL +HalpGetDmaAdapter( + IN PVOID Context, + IN PDEVICE_DESCRIPTION DeviceDescription, + OUT PULONG NumberOfMapRegisters); + +ULONG STDCALL +HalpDmaGetDmaAlignment( + PADAPTER_OBJECT AdapterObject); + +#endif /* HALDMA_H */ diff --git a/reactos/hal/halppc/include/halirq.h b/reactos/hal/halppc/include/halirq.h new file mode 100644 index 00000000000..6d072738f5f --- /dev/null +++ b/reactos/hal/halppc/include/halirq.h @@ -0,0 +1,35 @@ +/* + * $Id: halirq.h 23907 2006-09-04 05:52:23Z arty $ + */ + +#ifndef __INCLUDE_HAL_HALIRQ +#define __INCLUDE_HAL_HALIRQ + +#ifdef CONFIG_SMP + +#define FIRST_DEVICE_VECTOR (0x30) +#define FIRST_SYSTEM_VECTOR (0xef) + +#define IRQ_BASE FIRST_DEVICE_VECTOR +#define NR_IRQS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR) + +/* + * FIXME: + * This does not work if we have more than 24 IRQs (ie. more than one I/O APIC) + */ +#define VECTOR2IRQ(vector) (23 - (vector - IRQ_BASE) / 8) +#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector)) +#define IRQ2VECTOR(irq) (((23 - (irq)) * 8) + FIRST_DEVICE_VECTOR) + +#else + +#define IRQ_BASE (0x30) +#define NR_IRQS (16) + +#define VECTOR2IRQ(vector) ((vector) - IRQ_BASE) +#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector)) +#define IRQ2VECTOR(irq) ((irq) + IRQ_BASE) + +#endif + +#endif /* __INCLUDE_HAL_HALIRQ */ diff --git a/reactos/hal/halppc/include/halp.h b/reactos/hal/halppc/include/halp.h new file mode 100644 index 00000000000..88f607e699d --- /dev/null +++ b/reactos/hal/halppc/include/halp.h @@ -0,0 +1,97 @@ +/* + * + */ + +#ifndef __INTERNAL_HAL_HAL_H +#define __INTERNAL_HAL_HAL_H + +#define HAL_APC_REQUEST 0 +#define HAL_DPC_REQUEST 1 + +// +// Kernel Debugger Port Definition +// +typedef struct _KD_PORT_INFORMATION +{ + ULONG ComPort; + ULONG BaudRate; + ULONG BaseAddress; +} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION; + +/* display.c */ +VOID FASTCALL HalInitializeDisplay (struct _ROS_LOADER_PARAMETER_BLOCK *LoaderBlock); +VOID FASTCALL HalClearDisplay (UCHAR CharAttribute); + +/* adapter.c */ +PADAPTER_OBJECT STDCALL HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses); + +/* bus.c */ +VOID HalpInitBusHandlers (VOID); + +/* irql.c */ +VOID NTAPI HalpInitPICs(VOID); + +/* udelay.c */ +VOID HalpCalibrateStallExecution(VOID); + +/* pci.c */ +VOID HalpInitPciBus (VOID); + +/* enum.c */ +VOID HalpStartEnumerator (VOID); + +/* dma.c */ +VOID HalpInitDma (VOID); + +/* mem.c */ +PVOID HalpMapPhysMemory(ULONG PhysAddr, ULONG Size); + +/* Non-generic initialization */ +VOID HalpInitPhase0 (PROS_LOADER_PARAMETER_BLOCK LoaderBlock); +VOID HalpInitPhase1(VOID); +VOID NTAPI HalpClockInterrupt(VOID); + +/* sysinfo.c */ +NTSTATUS STDCALL +HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN OUT PVOID Buffer, + OUT PULONG ReturnedLength); + +/* Non-standard functions */ +VOID STDCALL +HalReleaseDisplayOwnership(); + +BOOLEAN STDCALL +HalQueryDisplayOwnership(); + +#if defined(__GNUC__) +#define Ki386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) +#define Ki386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") +#define Ki386DisableInterrupts() __asm__ __volatile__("cli\n\t") +#define Ki386EnableInterrupts() __asm__ __volatile__("sti\n\t") +#define Ki386HaltProcessor() __asm__ __volatile__("hlt\n\t") +#define Ki386RdTSC(x) __asm__ __volatile__("rdtsc\n\t" : "=A" (x.u.LowPart), "=d" (x.u.HighPart)) +#define Ki386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr)) +#define Ki386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2)) +#define Ki386ReadFsByte(offset,x) __asm__ __volatile__("movb %%fs:%c1,%0" : "=q" (x) : "i" (offset)) +#define Ki386WriteFsByte(offset,x) __asm__ __volatile__("movb %0,%%fs:%c1" : : "q" ((UCHAR)x), "i" (offset)) + +#elif defined(_MSC_VER) +#define Ki386SaveFlags(x) __asm pushfd __asm pop x; +#define Ki386RestoreFlags(x) __asm push x __asm popfd; +#define Ki386DisableInterrupts() __asm cli +#define Ki386EnableInterrupts() __asm sti +#define Ki386HaltProcessor() __asm hlt +#else +#error Unknown compiler for inline assembler +#endif + +typedef struct tagHALP_HOOKS +{ + void (*InitPciBus)(ULONG BusNumber, PBUS_HANDLER BusHandler); +} HALP_HOOKS, *PHALP_HOOKS; + +extern HALP_HOOKS HalpHooks; + +#endif /* __INTERNAL_HAL_HAL_H */ diff --git a/reactos/hal/halppc/include/ioapic.h b/reactos/hal/halppc/include/ioapic.h new file mode 100644 index 00000000000..114853c4a6d --- /dev/null +++ b/reactos/hal/halppc/include/ioapic.h @@ -0,0 +1,103 @@ +/* + * + */ + +#ifndef __INTERNAL_HAL_IOAPIC_H +#define __INTERNAL_HAL_IOAPIC_H + +/* I/O APIC Register Address Map */ +#define IOAPIC_IOREGSEL 0x0000 /* I/O Register Select (index) (R/W) */ +#define IOAPIC_IOWIN 0x0010 /* I/O window (data) (R/W) */ + +#define IOAPIC_ID 0x0000 /* IO APIC ID (R/W) */ +#define IOAPIC_VER 0x0001 /* IO APIC Version (R) */ +#define IOAPIC_ARB 0x0002 /* IO APIC Arbitration ID (R) */ +#define IOAPIC_REDTBL 0x0010 /* Redirection Table (0-23 64-bit registers) (R/W) */ + +#define IOAPIC_ID_MASK (0xF << 24) +#define GET_IOAPIC_ID(x) (((x) & IOAPIC_ID_MASK) >> 24) +#define SET_IOAPIC_ID(x) ((x) << 24) + +#define IOAPIC_VER_MASK (0xFF) +#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK)) +#define IOAPIC_MRE_MASK (0xFF << 16) /* Maximum Redirection Entry */ +#define GET_IOAPIC_MRE(x) (((x) & IOAPIC_MRE_MASK) >> 16) + +#define IOAPIC_ARB_MASK (0xF << 24) +#define GET_IOAPIC_ARB(x) (((x) & IOAPIC_ARB_MASK) >> 24) + +#define IOAPIC_TBL_DELMOD (0x7 << 10) /* Delivery Mode (see APIC_DM_*) */ +#define IOAPIC_TBL_DM (0x1 << 11) /* Destination Mode */ +#define IOAPIC_TBL_DS (0x1 << 12) /* Delivery Status */ +#define IOAPIC_TBL_INTPOL (0x1 << 13) /* Interrupt Input Pin Polarity */ +#define IOAPIC_TBL_RIRR (0x1 << 14) /* Remote IRR */ +#define IOAPIC_TBL_TM (0x1 << 15) /* Trigger Mode */ +#define IOAPIC_TBL_IM (0x1 << 16) /* Interrupt Mask */ +#define IOAPIC_TBL_DF0 (0xF << 56) /* Destination Field (physical mode) */ +#define IOAPIC_TBL_DF1 (0xFF<< 56) /* Destination Field (logical mode) */ +#define IOAPIC_TBL_VECTOR (0xFF << 0) /* Vector (10h - FEh) */ + +#include +typedef struct _IOAPIC_ROUTE_ENTRY { + ULONG vector : 8, + delivery_mode : 3, /* 000: FIXED + * 001: lowest priority + * 111: ExtINT + */ + dest_mode : 1, /* 0: physical, 1: logical */ + delivery_status : 1, + polarity : 1, + irr : 1, + trigger : 1, /* 0: edge, 1: level */ + mask : 1, /* 0: enabled, 1: disabled */ + __reserved_2 : 15; + + union { + struct { + ULONG __reserved_1 : 24, + physical_dest : 4, + __reserved_2 : 4; + } physical; + struct { + ULONG __reserved_1 : 24, + logical_dest : 8; + } logical; + } dest; +} IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY; +#include + +typedef struct _IOAPIC_INFO +{ + ULONG ApicId; /* APIC ID */ + ULONG ApicVersion; /* APIC version */ + ULONG ApicAddress; /* APIC address */ + ULONG EntryCount; /* Number of redirection entries */ +} IOAPIC_INFO, *PIOAPIC_INFO; + +#define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base Register Address */ + +extern ULONG IRQCount; /* Number of IRQs */ +extern UCHAR BUSMap[MAX_BUS]; /* Map of all buses in the system */ +extern UCHAR PCIBUSMap[MAX_BUS]; /* Map of all PCI buses in the system */ +extern IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */ +extern ULONG IOAPICCount; /* Number of I/O APICs in the system */ +extern ULONG APICMode; /* APIC mode at startup */ +extern MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */ + +VOID IOAPICSetupIrqs(VOID); +VOID IOAPICEnable(VOID); +VOID IOAPICSetupIds(VOID); +VOID IOAPICMaskIrq(ULONG Irq); +VOID IOAPICUnmaskIrq(ULONG Irq); + +VOID HaliReconfigurePciInterrupts(VOID); + +/* For debugging */ +VOID IOAPICDump(VOID); + +#endif + + + +/* EOF */ + diff --git a/reactos/hal/halppc/include/mps.h b/reactos/hal/halppc/include/mps.h new file mode 100644 index 00000000000..83f9cfbe501 --- /dev/null +++ b/reactos/hal/halppc/include/mps.h @@ -0,0 +1,204 @@ +#ifndef __INCLUDE_HAL_MPS +#define __INCLUDE_HAL_MPS + +/* + * FIXME: This does not work if we have more than 24 IRQs (ie. more than one + * I/O APIC) + */ +#define IRQL2VECTOR(irql) (IRQ2VECTOR(PROFILE_LEVEL - (irql))) + +#define IRQL2TPR(irql) ((irql) >= IPI_LEVEL ? IPI_VECTOR : ((irql) >= PROFILE_LEVEL ? LOCAL_TIMER_VECTOR : ((irql) > DISPATCH_LEVEL ? IRQL2VECTOR(irql) : 0))) + +typedef struct _KIRQ_TRAPFRAME +{ + ULONG Magic; + ULONG Gs; + ULONG Fs; + ULONG Es; + ULONG Ds; + ULONG Eax; + ULONG Ecx; + ULONG Edx; + ULONG Ebx; + ULONG Esp; + ULONG Ebp; + ULONG Esi; + ULONG Edi; + ULONG Eip; + ULONG Cs; + ULONG Eflags; +} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME; + +#if 0 +/* This values are defined in halirql.h */ +#define FIRST_DEVICE_VECTOR 0x30 +#define FIRST_SYSTEM_VECTOR 0xEF +#endif + +#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR) + + +/* MP Floating Pointer Structure */ +#define MPF_SIGNATURE (('_' << 24) | ('P' << 16) | ('M' << 8) | '_') + +#include +typedef struct _MP_FLOATING_POINTER +{ + ULONG Signature; /* _MP_ */ + ULONG Address; /* Physical Address Pointer (0 means no configuration table exist) */ + UCHAR Length; /* Structure length in 16-byte paragraphs */ + UCHAR Specification; /* Specification revision */ + UCHAR Checksum; /* Checksum */ + UCHAR Feature1; /* MP System Configuration Type */ + UCHAR Feature2; /* Bit 7 set for IMCR|PIC */ + UCHAR Feature3; /* Unused (0) */ + UCHAR Feature4; /* Unused (0) */ + UCHAR Feature5; /* Unused (0) */ +} MP_FLOATING_POINTER, *PMP_FLOATING_POINTER; + + +#define FEATURE2_IMCRP 0x80 + +/* MP Configuration Table Header */ +#define MPC_SIGNATURE (('P' << 24) | ('M' << 16) | ('C' << 8) | 'P') + +typedef struct _MP_CONFIGURATION_TABLE +{ + ULONG Signature; /* PCMP */ + USHORT Length; /* Size of configuration table */ + CHAR Specification; /* Specification Revision */ + CHAR Checksum; /* Checksum */ + CHAR Oem[8]; /* OEM ID */ + CHAR ProductId[12]; /* Product ID */ + ULONG OemTable; /* 0 if not present */ + USHORT OemTableSize; /* 0 if not present */ + USHORT EntryCount; /* Number of entries */ + ULONG LocalAPICAddress; /* Local APIC address */ + USHORT ExtTableLength; /* Extended Table Length */ + UCHAR ExtTableChecksum; /* Extended Table Checksum */ + UCHAR Reserved; /* Reserved */ +} MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE; + +/* MP Configuration Table Entries */ +#define MPCTE_PROCESSOR 0 /* One entry per processor */ +#define MPCTE_BUS 1 /* One entry per bus */ +#define MPCTE_IOAPIC 2 /* One entry per I/O APIC */ +#define MPCTE_INTSRC 3 /* One entry per bus interrupt source */ +#define MPCTE_LINTSRC 4 /* One entry per system interrupt source */ + + +typedef struct _MP_CONFIGURATION_PROCESSOR +{ + UCHAR Type; /* 0 */ + UCHAR ApicId; /* Local APIC ID for the processor */ + UCHAR ApicVersion; /* Local APIC version */ + UCHAR CpuFlags; /* CPU flags */ + ULONG CpuSignature; /* CPU signature */ + ULONG FeatureFlags; /* CPUID feature value */ + ULONG Reserved[2]; /* Reserved (0) */ +} MP_CONFIGURATION_PROCESSOR, *PMP_CONFIGURATION_PROCESSOR; + + + +typedef struct _MP_CONFIGURATION_BUS +{ + UCHAR Type; /* 1 */ + UCHAR BusId; /* Bus ID */ + CHAR BusType[6]; /* Bus type */ +} MP_CONFIGURATION_BUS, *PMP_CONFIGURATION_BUS; + +#define MAX_BUS 32 + +#define MP_BUS_ISA 1 +#define MP_BUS_EISA 2 +#define MP_BUS_PCI 3 +#define MP_BUS_MCA 4 + +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ +#define BUSTYPE_MCA "MCA" +#define BUSTYPE_VL "VL" /* Local bus */ +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" +#define BUSTYPE_CBUS "CBUS" +#define BUSTYPE_CBUSII "CBUSII" +#define BUSTYPE_FUTURE "FUTURE" +#define BUSTYPE_MBI "MBI" +#define BUSTYPE_MBII "MBII" +#define BUSTYPE_MPI "MPI" +#define BUSTYPE_MPSA "MPSA" +#define BUSTYPE_NUBUS "NUBUS" +#define BUSTYPE_TC "TC" +#define BUSTYPE_VME "VME" +#define BUSTYPE_XPRESS "XPRESS" + + +typedef struct _MP_CONFIGURATION_IOAPIC +{ + UCHAR Type; /* 2 */ + UCHAR ApicId; /* I/O APIC ID */ + UCHAR ApicVersion; /* I/O APIC version */ + UCHAR ApicFlags; /* I/O APIC flags */ + ULONG ApicAddress; /* I/O APIC base address */ +} MP_CONFIGURATION_IOAPIC, *PMP_CONFIGURATION_IOAPIC; + +#define MAX_IOAPIC 2 + +#define MP_IOAPIC_USABLE 0x01 + + +typedef struct _MP_CONFIGURATION_INTSRC +{ + UCHAR Type; /* 3 */ + UCHAR IrqType; /* Interrupt type */ + USHORT IrqFlag; /* Interrupt flags */ + UCHAR SrcBusId; /* Source bus ID */ + UCHAR SrcBusIrq; /* Source bus interrupt */ + UCHAR DstApicId; /* Destination APIC ID */ + UCHAR DstApicInt; /* Destination interrupt */ +} MP_CONFIGURATION_INTSRC, *PMP_CONFIGURATION_INTSRC; + +#define MAX_IRQ_SOURCE 128 + +#define INT_VECTORED 0 +#define INT_NMI 1 +#define INT_SMI 2 +#define INT_EXTINT 3 + +#define IRQDIR_DEFAULT 0 +#define IRQDIR_HIGH 1 +#define IRQDIR_LOW 3 + + +typedef struct _MP_CONFIGURATION_INTLOCAL +{ + UCHAR Type; /* 4 */ + UCHAR IrqType; /* Interrupt type */ + USHORT IrqFlag; /* Interrupt flags */ + UCHAR SrcBusId; /* Source bus ID */ + UCHAR SrcBusIrq; /* Source bus interrupt */ + UCHAR DstApicId; /* Destination local APIC ID */ + UCHAR DstApicLInt; /* Destination local APIC interrupt */ +} MP_CONFIGURATION_INTLOCAL, *PMP_CONFIGURATION_INTLOCAL; +#include + +#define MP_APIC_ALL 0xFF + +#define CPU_FLAG_ENABLED 1 /* Processor is available */ +#define CPU_FLAG_BSP 2 /* Processor is the bootstrap processor */ + +#define CPU_STEPPING_MASK 0x0F +#define CPU_MODEL_MASK 0xF0 +#define CPU_FAMILY_MASK 0xF00 + +#define PIC_IRQS 16 + +/* Prototypes */ + +VOID HalpInitMPS(VOID); + + +#endif /* __INCLUDE_HAL_MPS */ + +/* EOF */ diff --git a/reactos/hal/halppc/up/halinit_up.c b/reactos/hal/halppc/up/halinit_up.c new file mode 100644 index 00000000000..38851c9dacf --- /dev/null +++ b/reactos/hal/halppc/up/halinit_up.c @@ -0,0 +1,35 @@ +/* $Id: halinit_up.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/halinit.c + * PURPOSE: Initalize the x86 hal + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + * 11/06/98: Created + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS ***************************************************************/ + +VOID +HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock) +{ + HalpInitPICs(); + + /* Setup busy waiting */ + HalpCalibrateStallExecution(); +} + +VOID +HalpInitPhase1(VOID) +{ + /* Nothing for now */ +} + +/* EOF */ diff --git a/reactos/hal/halppc/up/halup.rbuild b/reactos/hal/halppc/up/halup.rbuild new file mode 100644 index 00000000000..0ba1b0888a8 --- /dev/null +++ b/reactos/hal/halppc/up/halup.rbuild @@ -0,0 +1,12 @@ + + + + ../include + include + + + + halppc_generic + halinit_up.c + halup.rc + diff --git a/reactos/hal/halppc/up/halup.rc b/reactos/hal/halppc/up/halup.rc new file mode 100644 index 00000000000..90af6b929ff --- /dev/null +++ b/reactos/hal/halppc/up/halup.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer\0" +#define REACTOS_STR_INTERNAL_NAME "halup\0" +#define REACTOS_STR_ORIGINAL_FILENAME "halup.dll\0" +#include From c6f96d64937c0620dd9265a0c27627f1a4457b8c Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 8 Jan 2007 09:27:30 +0000 Subject: [PATCH 71/81] Add needed reloc types. svn path=/branches/powerpc/; revision=25374 --- reactos/lib/rtl/image.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index e7dafc25e25..5439e4f328c 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -164,14 +164,23 @@ LdrProcessRelocationBlockLongLong( USHORT Type; USHORT i; PUSHORT ShortPtr; + ULONG Addend; PULONG LongPtr; + DbgPrint("Relocating %08x-%08x (With delta %08x)\n", + Address, Address + 0x1000, (ULONG)Delta); + for (i = 0; i < Count; i++) { Offset = *TypeOffset & 0xFFF; Type = *TypeOffset >> 12; ShortPtr = (PUSHORT)(RVA(Address, Offset)); + DbgPrint("Correcting (%04x) %08x at %08x\n", + Type, + *((PULONG)RVA(Address,Offset)), + ShortPtr); + /* * Don't relocate within the relocation section itself. * GCC/LD generates sometimes relocation records for the relocation section. @@ -203,6 +212,11 @@ LdrProcessRelocationBlockLongLong( break; case IMAGE_REL_BASED_HIGHADJ: + Addend = (((ULONG)*ShortPtr) << 16) + (ULONG)Delta; + if(Addend & 0x8000) Addend += 0x8000; + *ShortPtr = Addend >> 16; + break; + case IMAGE_REL_BASED_MIPS_JMPADDR: default: DPRINT1("Unknown/unsupported fixup type %hu.\n", Type); @@ -256,6 +270,12 @@ LdrRelocateImageWithBias( RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + RelocationDDir->VirtualAddress); RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); + DbgPrint("Relocating a module from %08x to %08x (relocs at %08x to %08x)\n", + NtHeaders->OptionalHeader.ImageBase, + BaseAddress, + RelocationDir, + RelocationEnd); + while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { @@ -263,6 +283,8 @@ LdrRelocateImageWithBias( Address = (ULONG_PTR)RVA(BaseAddress, RelocationDir->VirtualAddress); TypeOffset = (PUSHORT)(RelocationDir + 1); + DbgPrint("Performing %d relocs from %08x to %08x\n", + Count, Address, Address + 0x1000); RelocationDir = LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, From fbaf823a61226c1f324f75e9ff215a8a4bbf272b Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 8 Jan 2007 09:28:39 +0000 Subject: [PATCH 72/81] Start of an implementation of page.c svn path=/branches/powerpc/; revision=25375 --- reactos/ntoskrnl/mm/powerpc/page.c | 1325 ++++++++++++++++++++++++++++ 1 file changed, 1325 insertions(+) create mode 100644 reactos/ntoskrnl/mm/powerpc/page.c diff --git a/reactos/ntoskrnl/mm/powerpc/page.c b/reactos/ntoskrnl/mm/powerpc/page.c new file mode 100644 index 00000000000..a4b1bdaf1ce --- /dev/null +++ b/reactos/ntoskrnl/mm/powerpc/page.c @@ -0,0 +1,1325 @@ +/* $Id: page.c 23907 2006-09-04 05:52:23Z arty $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/mm/i386/page.c + * PURPOSE: Low level memory managment manipulation + * + * PROGRAMMERS: David Welch (welch@cwcom.net) + * Revised for PowerPC by arty + */ + +/* INCLUDES ***************************************************************/ + +#include +#define NDEBUG +#include + +#if defined (ALLOC_PRAGMA) +#pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory) +#pragma alloc_text(INIT, MiInitPageDirectoryMap) +#endif + +/* GLOBALS *****************************************************************/ + +#define PAGETABLE_MAP (0xc0000000) +#define PAGEDIRECTORY_MAP (0xc0000000 + (PAGETABLE_MAP / (1024))) + +#define PA_PRESENT (1ll<<63) +#define PA_USER (1ll<<62) +#define PA_ACCESSED 0x200 +#define PA_DIRTY 0x100 +#define PA_WT 0x20 +#define PA_CD 0x10 +#define PA_READWRITE 3 + +#define HYPERSPACE (0xc0400000) +#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000)) + +#define PP_FROM_PROTECT(X) \ + ((X & (PAGE_NOACCESS | PAGE_GUARD)) ? 0 : \ + (X & PAGE_IS_WRITABLE) ? 2 : \ + (X & (PAGE_IS_READABLE | PAGE_IS_EXECUTABLE)) ? 3 : 0) + +ULONG MmGlobalKernelPageDirectory[1024]; + +#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT) +#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT) + +#if defined(__GNUC__) +#define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X))) +#else +__inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage) +{ + LARGE_INTEGER dummy; + dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage)); + return dummy; +} +#endif + +/* FUNCTIONS ***************************************************************/ + +BOOLEAN MmUnmapPageTable(PULONG Pt); + +VOID +STDCALL +MiFlushTlbIpiRoutine(PVOID Address) +{ + if (Address == (PVOID)0xffffffff) + { + KeFlushCurrentTb(); + } + else if (Address == (PVOID)0xfffffffe) + { + FLUSH_TLB; + } + else + { + FLUSH_TLB_ONE(Address); + } +} + +VOID +MiFlushTlb(PULONG Pt, PVOID Address) +{ +#ifdef CONFIG_SMP + if (Pt) + { + MmUnmapPageTable(Pt); + } + if (KeNumberProcessors>1) + { + KeIpiGenericCall(MiFlushTlbIpiRoutine, Address); + } + else + { + MiFlushTlbIpiRoutine(Address); + } +#else + if ((Pt && MmUnmapPageTable(Pt)) || Address >= MmSystemRangeStart) + { + FLUSH_TLB_ONE(Address); + } +#endif +} + + + +PULONG +MmGetPageDirectory(VOID) +{ + unsigned int page_dir=0; + return((PULONG)page_dir); +} + +static ULONGLONG +ProtectToPTE(ULONG flProtect) +{ + return PP_FROM_PROTECT(flProtect); +} + +#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE)) + +#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \ + ((((ULONG)(v)) / (1024 * 1024))&(~0x3))) +#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((((ULONG)(v) / 1024))&(~0x3))) + +#define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (1024 * PAGE_SIZE))) + +#define ADDR_TO_PTE_OFFSET(v) ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE) + +NTSTATUS +STDCALL +MmCopyMmInfo(PEPROCESS Src, + PEPROCESS Dest, + PPHYSICAL_ADDRESS DirectoryTableBase) +{ + NTSTATUS Status; + ULONG i, j; + PFN_TYPE Pfn[7]; + ULONG Count; + PULONG PageDirectory; + + DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest); + + Count = 2; + + for (i = 0; i < Count; i++) + { + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]); + if (!NT_SUCCESS(Status)) + { + for (j = 0; j < i; j++) + { + MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]); + } + return Status; + } + } + + PageDirectory = MmCreateHyperspaceMapping(Pfn[0]); + + memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart), + MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart), + (1024 - ADDR_TO_PDE_OFFSET(MmSystemRangeStart)) * sizeof(ULONG)); + + DPRINT("Addr %x\n",ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)); + PageDirectory[ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)] = PFN_TO_PTE(Pfn[0]) | PA_PRESENT | PA_READWRITE; + PageDirectory[ADDR_TO_PDE_OFFSET(HYPERSPACE)] = PFN_TO_PTE(Pfn[1]) | PA_PRESENT | PA_READWRITE; + + MmDeleteHyperspaceMapping(PageDirectory); + + DirectoryTableBase->QuadPart = PFN_TO_PTE(Pfn[0]); + DPRINT("Finished MmCopyMmInfo(): %I64x\n", DirectoryTableBase->QuadPart); + return(STATUS_SUCCESS); +} + +VOID +NTAPI +MmDeletePageTable(PEPROCESS Process, PVOID Address) +{ + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + + if (Process != NULL && Process != CurrentProcess) + { + KeAttachProcess(&Process->Pcb); + } + + *(ADDR_TO_PDE(Address)) = 0; + MiFlushTlb(ADDR_TO_PDE(Address), ADDR_TO_PTE(Address)); + + if (Address >= MmSystemRangeStart) + { + KEBUGCHECK(0); + } + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } +} + +VOID +NTAPI +MmFreePageTable(PEPROCESS Process, PVOID Address) +{ + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + ULONG i; + PFN_TYPE Pfn; + + DPRINT("ProcessId %d, Address %x\n", Process->UniqueProcessId, Address); + if (Process != NULL && Process != CurrentProcess) + { + KeAttachProcess(&Process->Pcb); + } + + PULONG PageTable; + PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address)); + for (i = 0; i < 1024; i++) + { + if (PageTable[i] != 0) + { + DbgPrint("Page table entry not clear at %x/%x (is %x)\n", + ((ULONG)Address / (4*1024*1024)), i, PageTable[i]); + KEBUGCHECK(0); + } + } + Pfn = PTE_TO_PFN(*(ADDR_TO_PDE(Address))); + *(ADDR_TO_PDE(Address)) = 0; + MiFlushTlb(ADDR_TO_PDE(Address), ADDR_TO_PTE(Address)); + + if (Address >= MmSystemRangeStart) + { + // MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; + KEBUGCHECK(0); + } + else + { + MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); + } + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } +} + +static PULONG +MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create) +{ + ULONG PdeOffset = ADDR_TO_PDE_OFFSET(Address); + NTSTATUS Status; + PFN_TYPE Pfn; + ULONG Entry; + PULONG Pt, PageDir; + + if (Address < MmSystemRangeStart && Process && Process != PsGetCurrentProcess()) + { + PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart)); + if (PageDir == NULL) + { + KEBUGCHECK(0); + } + if (0 == InterlockedCompareExchangeUL(&PageDir[PdeOffset], 0, 0)) + { + if (Create == FALSE) + { + MmDeleteHyperspaceMapping(PageDir); + return NULL; + } + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn); + if (!NT_SUCCESS(Status) || Pfn == 0) + { + KEBUGCHECK(0); + } + Entry = InterlockedCompareExchangeUL(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0); + if (Entry != 0) + { + MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); + Pfn = PTE_TO_PFN(Entry); + } + } + else + { + Pfn = PTE_TO_PFN(PageDir[PdeOffset]); + } + MmDeleteHyperspaceMapping(PageDir); + Pt = MmCreateHyperspaceMapping(Pfn); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + return Pt + ADDR_TO_PTE_OFFSET(Address); + } + PageDir = ADDR_TO_PDE(Address); + if (0 == InterlockedCompareExchangeUL(PageDir, 0, 0)) + { + if (Address >= MmSystemRangeStart) + { + if (0 == InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0)) + { + if (Create == FALSE) + { + return NULL; + } + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn); + if (!NT_SUCCESS(Status) || Pfn == 0) + { + KEBUGCHECK(0); + } + Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE; + if(0 != InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0)) + { + MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); + } + } + (void)InterlockedExchangeUL(PageDir, MmGlobalKernelPageDirectory[PdeOffset]); + } + else + { + if (Create == FALSE) + { + return NULL; + } + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn); + if (!NT_SUCCESS(Status) || Pfn == 0) + { + KEBUGCHECK(0); + } + Entry = InterlockedCompareExchangeUL(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0); + if (Entry != 0) + { + MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); + } + } + } + return (PULONG)ADDR_TO_PTE(Address); +} + +BOOLEAN MmUnmapPageTable(PULONG Pt) +{ + if (Pt >= (PULONG)PAGETABLE_MAP && Pt < (PULONG)PAGETABLE_MAP + 1024*1024) + { + return TRUE; + } + + if (Pt) + { + MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(Pt)); + } + return FALSE; +} + +static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address) +{ + ULONG Pte; + PULONG Pt; + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + if (Pt) + { + Pte = *Pt; + MmUnmapPageTable(Pt); + return Pte; + } + return 0; +} + +PFN_TYPE +NTAPI +MmGetPfnForProcess(PEPROCESS Process, + PVOID Address) +{ + ULONG Entry; + Entry = MmGetPageEntryForProcess(Process, Address); + return(PTE_TO_PFN(Entry)); +} + +VOID +NTAPI +MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN* WasDirty, PPFN_TYPE Page) +/* + * FUNCTION: Delete a virtual mapping + */ +{ + BOOLEAN WasValid; + ULONG Pte; + PULONG Pt; + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + /* + * Atomically disable the present bit and get the old value. + */ + do + { + Pte = *Pt; + } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_PRESENT, Pte)); + + MiFlushTlb(Pt, Address); + WasValid = (PAGE_MASK(Pte) != 0); + if (!WasValid) + { + KEBUGCHECK(0); + } + + /* + * Return some information to the caller + */ + if (WasDirty != NULL) + { + *WasDirty = Pte & PA_DIRTY; + } + if (Page != NULL) + { + *Page = PTE_TO_PFN(Pte); + } +} + +VOID +NTAPI +MmRawDeleteVirtualMapping(PVOID Address) +{ + PULONG Pt; + + Pt = MmGetPageTableForProcess(NULL, Address, FALSE); + if (Pt && *Pt) + { + /* + * Set the entry to zero + */ + (void)InterlockedExchangeUL(Pt, 0); + MiFlushTlb(Pt, Address); + } +} + +VOID +NTAPI +MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage, + BOOLEAN* WasDirty, PPFN_TYPE Page) +/* + * FUNCTION: Delete a virtual mapping + */ +{ + BOOLEAN WasValid = FALSE; + PFN_TYPE Pfn; + + DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n", + Process, Address, FreePage, WasDirty, Page); + + ULONG Pte; + PULONG Pt; + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + + if (Pt == NULL) + { + if (WasDirty != NULL) + { + *WasDirty = FALSE; + } + if (Page != NULL) + { + *Page = 0; + } + return; + } + + /* + * Atomically set the entry to zero and get the old value. + */ + Pte = InterlockedExchangeUL(Pt, 0); + + MiFlushTlb(Pt, Address); + + WasValid = (PAGE_MASK(Pte) != 0); + if (WasValid) + { + Pfn = PTE_TO_PFN(Pte); + MmMarkPageUnmapped(Pfn); + } + else + { + Pfn = 0; + } + + if (FreePage && WasValid) + { + MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); + } + + /* + * Return some information to the caller + */ + if (WasDirty != NULL) + { + *WasDirty = Pte & PA_DIRTY ? TRUE : FALSE; + } + if (Page != NULL) + { + *Page = Pfn; + } + /* + * Decrement the reference count for this page table. + */ + if (Process != NULL && WasValid && + ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && + Address < MmSystemRangeStart) + { + PUSHORT Ptrc; + ULONG Idx; + + Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; + Idx = ADDR_TO_PAGE_TABLE(Address); + + Ptrc[Idx]--; + if (Ptrc[Idx] == 0) + { + MmFreePageTable(Process, Address); + } + } +} + +VOID +NTAPI +MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, + SWAPENTRY* SwapEntry) +/* + * FUNCTION: Delete a virtual mapping + */ +{ + ULONG Pte; + PULONG Pt; + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + + if (Pt == NULL) + { + *SwapEntry = 0; + return; + } + + /* + * Atomically set the entry to zero and get the old value. + */ + Pte = InterlockedExchangeUL(Pt, 0); + + MiFlushTlb(Pt, Address); + + /* + * Decrement the reference count for this page table. + */ + if (Process != NULL && Pte && + ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && + Address < MmSystemRangeStart) + { + PUSHORT Ptrc; + + Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; + + Ptrc[ADDR_TO_PAGE_TABLE(Address)]--; + if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0) + { + MmFreePageTable(Process, Address); + } + } + + /* + * Return some information to the caller + */ + *SwapEntry = Pte >> 1; +} + +BOOLEAN +Mmi386MakeKernelPageTableGlobal(PVOID PAddress) +{ + PULONG Pt, Pde; + Pde = ADDR_TO_PDE(PAddress); + if (*Pde == 0) + { + Pt = MmGetPageTableForProcess(NULL, PAddress, FALSE); +#if 0 + /* Non existing mappings are not cached within the tlb. We must not invalidate this entry */ + FLASH_TLB_ONE(PAddress); +#endif + if (Pt != NULL) + { + return TRUE; + } + } + return(FALSE); +} + +BOOLEAN +NTAPI +MmIsDirtyPage(PEPROCESS Process, PVOID Address) +{ + return MmGetPageEntryForProcess(Process, Address) & PA_DIRTY ? TRUE : FALSE; +} + +BOOLEAN +NTAPI +MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address) +{ + PULONG Pt; + ULONG Pte; + + if (Address < MmSystemRangeStart && Process == NULL) + { + DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n"); + KEBUGCHECK(0); + } + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + + do + { + Pte = *Pt; + } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_ACCESSED, Pte)); + + if (Pte & PA_ACCESSED) + { + MiFlushTlb(Pt, Address); + return TRUE; + } + else + { + MmUnmapPageTable(Pt); + return FALSE; + } +} + +VOID +NTAPI +MmSetCleanPage(PEPROCESS Process, PVOID Address) +{ + PULONG Pt; + ULONG Pte; + + if (Address < MmSystemRangeStart && Process == NULL) + { + DPRINT1("MmSetCleanPage is called for user space without a process.\n"); + KEBUGCHECK(0); + } + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + + if (Pt == NULL) + { + KEBUGCHECK(0); + } + + do + { + Pte = *Pt; + } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_DIRTY, Pte)); + + if (Pte & PA_DIRTY) + { + MiFlushTlb(Pt, Address); + } + else + { + MmUnmapPageTable(Pt); + } +} + +VOID +NTAPI +MmSetDirtyPage(PEPROCESS Process, PVOID Address) +{ + PULONG Pt; + ULONG Pte; + + if (Address < MmSystemRangeStart && Process == NULL) + { + DPRINT1("MmSetDirtyPage is called for user space without a process.\n"); + KEBUGCHECK(0); + } + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + + do + { + Pte = *Pt; + } while (Pte != InterlockedCompareExchangeUL(Pt, Pte | PA_DIRTY, Pte)); + if (!(Pte & PA_DIRTY)) + { + MiFlushTlb(Pt, Address); + } + else + { + MmUnmapPageTable(Pt); + } +} + +VOID +NTAPI +MmEnableVirtualMapping(PEPROCESS Process, PVOID Address) +{ + PULONG Pt; + ULONG Pte; + + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + + do + { + Pte = *Pt; + } while (Pte != InterlockedCompareExchangeUL(Pt, Pte | PA_PRESENT, Pte)); + if (!(Pte & PA_PRESENT)) + { + MiFlushTlb(Pt, Address); + } + else + { + MmUnmapPageTable(Pt); + } +} + +BOOLEAN +NTAPI +MmIsPagePresent(PEPROCESS Process, PVOID Address) +{ + return MmGetPageEntryForProcess(Process, Address) & PA_PRESENT ? TRUE : FALSE; +} + +BOOLEAN +NTAPI +MmIsPageSwapEntry(PEPROCESS Process, PVOID Address) +{ + ULONG Entry; + Entry = MmGetPageEntryForProcess(Process, Address); + return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE; +} + +NTSTATUS +NTAPI +MmCreateVirtualMappingForKernel(PVOID Address, + ULONG flProtect, + PPFN_TYPE Pages, + ULONG PageCount) +{ + ULONG Attributes; + ULONG i; + PVOID Addr; + ULONG PdeOffset, oldPdeOffset; + BOOLEAN NoExecute = FALSE; + PULONG Pt; + ULONG Pte; + + DPRINT("MmCreateVirtualMappingForKernel(%x, %x, %x, %d)\n", + Address, flProtect, Pages, PageCount); + + if (Address < MmSystemRangeStart) + { + DPRINT1("MmCreateVirtualMappingForKernel is called for user space\n"); + KEBUGCHECK(0); + } + + Attributes = ProtectToPTE(flProtect); + if (Attributes & 0x80000000) + { + NoExecute = TRUE; + } + Attributes &= 0xfff; + + Addr = Address; + + oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr); + Pt = MmGetPageTableForProcess(NULL, Addr, TRUE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + Pt--; + + for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE)) + { + if (!(Attributes & PA_PRESENT) && Pages[i] != 0) + { + DPRINT1("Setting physical address but not allowing access at address " + "0x%.8X with attributes %x/%x.\n", + Addr, Attributes, flProtect); + KEBUGCHECK(0); + } + + PdeOffset = ADDR_TO_PDE_OFFSET(Addr); + if (oldPdeOffset != PdeOffset) + { + Pt = MmGetPageTableForProcess(NULL, Addr, TRUE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + } + else + { + Pt++; + } + oldPdeOffset = PdeOffset; + + Pte = *Pt; + if (Pte != 0) + { + KEBUGCHECK(0); + } + (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes); + } + + return(STATUS_SUCCESS); +} + +NTSTATUS +NTAPI +MmCreatePageFileMapping(PEPROCESS Process, + PVOID Address, + SWAPENTRY SwapEntry) +{ + PULONG Pt; + ULONG Pte; + + if (Process == NULL && Address < MmSystemRangeStart) + { + DPRINT1("No process\n"); + KEBUGCHECK(0); + } + if (Process != NULL && Address >= MmSystemRangeStart) + { + DPRINT1("Setting kernel address with process context\n"); + KEBUGCHECK(0); + } + if (SwapEntry & (1 << 31)) + { + KEBUGCHECK(0); + } + + Pt = MmGetPageTableForProcess(Process, Address, TRUE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + Pte = *Pt; + if (PAGE_MASK((Pte)) != 0) + { + MmMarkPageUnmapped(PTE_TO_PFN((Pte))); + } + (void)InterlockedExchangeUL(Pt, SwapEntry << 1); + if (Pte != 0) + { + MiFlushTlb(Pt, Address); + } + else + { + MmUnmapPageTable(Pt); + } + + if (Process != NULL && + ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && + Address < MmSystemRangeStart) + { + PUSHORT Ptrc; + ULONG Idx; + + Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; + Idx = ADDR_TO_PAGE_TABLE(Address); + Ptrc[Idx]++; + } + return(STATUS_SUCCESS); +} + + +NTSTATUS +NTAPI +MmCreateVirtualMappingUnsafe(PEPROCESS Process, + PVOID Address, + ULONG flProtect, + PPFN_TYPE Pages, + ULONG PageCount) +{ + ULONG Attributes; + PVOID Addr; + ULONG i; + ULONG oldPdeOffset, PdeOffset; + BOOLEAN NoExecute = FALSE; + PULONG Pt = NULL; + ULONG Pte; + + DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n", + Process, Address, flProtect, Pages, *Pages, PageCount); + + if (Process == NULL) + { + if (Address < MmSystemRangeStart) + { + DPRINT1("No process\n"); + KEBUGCHECK(0); + } + if (PageCount > 0x10000 || + (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000) + { + DPRINT1("Page count to large\n"); + KEBUGCHECK(0); + } + } + else + { + if (Address >= MmSystemRangeStart) + { + DPRINT1("Setting kernel address with process context\n"); + KEBUGCHECK(0); + } + if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE || + (ULONG_PTR) Address / PAGE_SIZE + PageCount > + (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE) + { + DPRINT1("Page Count to large\n"); + KEBUGCHECK(0); + } + } + + Attributes = ProtectToPTE(flProtect); + if (Attributes & 0x80000000) + { + NoExecute = TRUE; + } + Attributes &= 0xfff; + if (Address >= MmSystemRangeStart) + { + Attributes &= ~PA_USER; + } + else + { + Attributes |= PA_USER; + } + + Addr = Address; + + oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1; + for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE)) + { + if (!(Attributes & PA_PRESENT) && Pages[i] != 0) + { + DPRINT1("Setting physical address but not allowing access at address " + "0x%.8X with attributes %x/%x.\n", + Addr, Attributes, flProtect); + KEBUGCHECK(0); + } + PdeOffset = ADDR_TO_PDE_OFFSET(Addr); + if (oldPdeOffset != PdeOffset) + { + MmUnmapPageTable(Pt); + Pt = MmGetPageTableForProcess(Process, Addr, TRUE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + } + else + { + Pt++; + } + oldPdeOffset = PdeOffset; + + Pte = *Pt; + MmMarkPageMapped(Pages[i]); + if (PAGE_MASK((Pte)) != 0 && !((Pte) & PA_PRESENT)) + { + KEBUGCHECK(0); + } + if (PAGE_MASK((Pte)) != 0) + { + MmMarkPageUnmapped(PTE_TO_PFN((Pte))); + } + (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes); + if (Address < MmSystemRangeStart && + ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && + Attributes & PA_PRESENT) + { + PUSHORT Ptrc; + + Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; + + Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++; + } + if (Pte != 0) + { + if (Address > MmSystemRangeStart || + (Pt >= (PULONG)PAGETABLE_MAP && Pt < (PULONG)PAGETABLE_MAP + 1024*1024)) + { + MiFlushTlb(Pt, Address); + } + } + } + if (Addr > Address) + { + MmUnmapPageTable(Pt); + } + return(STATUS_SUCCESS); +} + +NTSTATUS +NTAPI +MmCreateVirtualMapping(PEPROCESS Process, + PVOID Address, + ULONG flProtect, + PPFN_TYPE Pages, + ULONG PageCount) +{ + ULONG i; + + for (i = 0; i < PageCount; i++) + { + if (!MmIsUsablePage(Pages[i])) + { + DPRINT1("Page at address %x not usable\n", PFN_TO_PTE(Pages[i])); + KEBUGCHECK(0); + } + } + + return(MmCreateVirtualMappingUnsafe(Process, + Address, + flProtect, + Pages, + PageCount)); +} + +ULONG +NTAPI +MmGetPageProtect(PEPROCESS Process, PVOID Address) +{ + ULONG Entry; + ULONG Protect; + + Entry = MmGetPageEntryForProcess(Process, Address); + + if (!(Entry & PA_PRESENT)) + { + Protect = PAGE_NOACCESS; + } + else + { + if (Entry & PA_READWRITE) + { + Protect = PAGE_READWRITE; + } + else + { + Protect = PAGE_EXECUTE_READ; + } + if (Entry & PA_CD) + { + Protect |= PAGE_NOCACHE; + } + if (Entry & PA_WT) + { + Protect |= PAGE_WRITETHROUGH; + } + if (!(Entry & PA_USER)) + { + Protect |= PAGE_SYSTEM; + } + + } + return(Protect); +} + +VOID +NTAPI +MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect) +{ + ULONG Attributes = 0; + + DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n", + Process, Address, flProtect); + + Attributes = ProtectToPTE(flProtect); + +#if 0 + Pt = MmGetPageTableForProcess(Process, Address, FALSE); + if (Pt == NULL) + { + KEBUGCHECK(0); + } + InterlockedExchange((PLONG)Pt, PAGE_MASK(*Pt) | Attributes | (*Pt & (PA_ACCESSED|PA_DIRTY))); + MiFlushTlb(Pt, Address); +#endif +} + +/* + * @implemented + */ +PHYSICAL_ADDRESS STDCALL +MmGetPhysicalAddress(PVOID vaddr) +/* + * FUNCTION: Returns the physical address corresponding to a virtual address + */ +{ + PHYSICAL_ADDRESS p; + ULONG Pte; + + DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr); + Pte = MmGetPageEntryForProcess(NULL, vaddr); + if (Pte != 0 && Pte & PA_PRESENT) + { + p.QuadPart = PAGE_MASK(Pte); + p.u.LowPart |= (ULONG_PTR)vaddr & (PAGE_SIZE - 1); + } + else + { + p.QuadPart = 0; + } + return p; +} + +PVOID +NTAPI +MmCreateHyperspaceMapping(PFN_TYPE Page) +{ + PVOID Address; + ULONG i; + ULONG Entry; + PULONG Pte; + Entry = PFN_TO_PTE(Page) | PA_PRESENT | PA_READWRITE; + Pte = ADDR_TO_PTE(HYPERSPACE) + Page % 1024; + if (Page & 1024) + { + for (i = Page % 1024; i < 1024; i++, Pte++) + { + if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0)) + { + break; + } + } + if (i >= 1024) + { + Pte = ADDR_TO_PTE(HYPERSPACE); + for (i = 0; i < Page % 1024; i++, Pte++) + { + if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0)) + { + break; + } + } + if (i >= Page % 1024) + { + KEBUGCHECK(0); + } + } + } + else + { + for (i = Page % 1024; (LONG)i >= 0; i--, Pte--) + { + if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0)) + { + break; + } + } + if ((LONG)i < 0) + { + Pte = ADDR_TO_PTE(HYPERSPACE) + 1023; + for (i = 1023; i > Page % 1024; i--, Pte--) + { + if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0)) + { + break; + } + } + if (i <= Page % 1024) + { + KEBUGCHECK(0); + } + } + } + Address = (PVOID)((ULONG_PTR)HYPERSPACE + i * PAGE_SIZE); + FLUSH_TLB_ONE(Address); + return Address; +} + +PFN_TYPE +NTAPI +MmChangeHyperspaceMapping(PVOID Address, PFN_TYPE NewPage) +{ + PFN_TYPE Pfn; + ASSERT (IS_HYPERSPACE(Address)); + ULONG Entry; + Entry = InterlockedExchange((PLONG)ADDR_TO_PTE(Address), PFN_TO_PTE(NewPage) | PA_PRESENT | PA_READWRITE); + Pfn = PTE_TO_PFN(Entry); + FLUSH_TLB_ONE(Address); + return Pfn; +} + +PFN_TYPE +NTAPI +MmDeleteHyperspaceMapping(PVOID Address) +{ + PFN_TYPE Pfn; + ASSERT (IS_HYPERSPACE(Address)); + ULONG Entry; + Entry = InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0); + Pfn = PTE_TO_PFN(Entry); + FLUSH_TLB_ONE(Address); + return Pfn; +} + +VOID +NTAPI +MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size) +{ + ULONG StartOffset, EndOffset, Offset; + PULONG Pde; + + if (Address < MmSystemRangeStart) + { + KEBUGCHECK(0); + } + StartOffset = ADDR_TO_PDE_OFFSET(Address); + EndOffset = ADDR_TO_PDE_OFFSET((PVOID)((ULONG_PTR)Address + Size)); + + if (Process != NULL && Process != PsGetCurrentProcess()) + { + Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.u.LowPart)); + } + else + { + Pde = (PULONG)PAGEDIRECTORY_MAP; + } + for (Offset = StartOffset; Offset <= EndOffset; Offset++) + { + if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)) + { + (void)InterlockedCompareExchangeUL(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0); + } + } + if (Pde != (PULONG)PAGEDIRECTORY_MAP) + { + MmDeleteHyperspaceMapping(Pde); + } +} + +VOID +INIT_FUNCTION +NTAPI +MmInitGlobalKernelPageDirectory(VOID) +{ + ULONG i; + PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP; + + DPRINT("MmInitGlobalKernelPageDirectory()\n"); + + for (i = ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 1024; i++) + { + if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && + i != ADDR_TO_PDE_OFFSET(HYPERSPACE) && + 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i]) + { + MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i]; + } + } +} + +ULONG +NTAPI +MiGetUserPageDirectoryCount(VOID) +{ + return ADDR_TO_PDE_OFFSET(MmSystemRangeStart); +} + +VOID +INIT_FUNCTION +NTAPI +MiInitPageDirectoryMap(VOID) +{ + MEMORY_AREA* kernel_map_desc = NULL; + MEMORY_AREA* hyperspace_desc = NULL; + PHYSICAL_ADDRESS BoundaryAddressMultiple; + PVOID BaseAddress; + NTSTATUS Status; + + DPRINT("MiInitPageDirectoryMap()\n"); + + BoundaryAddressMultiple.QuadPart = 0; + BaseAddress = (PVOID)PAGETABLE_MAP; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + 0x400000, + PAGE_READWRITE, + &kernel_map_desc, + TRUE, + 0, + BoundaryAddressMultiple); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + BaseAddress = (PVOID)HYPERSPACE; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + 0x400000, + PAGE_READWRITE, + &hyperspace_desc, + TRUE, + 0, + BoundaryAddressMultiple); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } +} + +/* EOF */ From e9873af4fc35154bb9248b9722b1d43700924c76 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 8 Jan 2007 09:30:17 +0000 Subject: [PATCH 73/81] HAL display implementation based on openfirmware framebuffer. svn path=/branches/powerpc/; revision=25376 --- reactos/hal/halppc/generic/display.c | 527 +++------------------- reactos/hal/halppc/generic/generic.rbuild | 4 + 2 files changed, 58 insertions(+), 473 deletions(-) diff --git a/reactos/hal/halppc/generic/display.c b/reactos/hal/halppc/generic/display.c index 1874de23331..f2858374c8d 100644 --- a/reactos/hal/halppc/generic/display.c +++ b/reactos/hal/halppc/generic/display.c @@ -122,59 +122,16 @@ */ #include +#include #define NDEBUG #include +#include "font.h" +boot_infos_t PpcEarlybootInfo; +BOOLEAN PPCGetEEBit(); #define SCREEN_SYNCHRONIZATION -#define VGA_GRAPH_MEM 0xa0000 -#define VGA_CHAR_MEM 0xb8000 -#define VGA_END_MEM 0xbffff - -#define VGA_AC_INDEX 0x3c0 -#define VGA_AC_READ 0x3c1 -#define VGA_AC_WRITE 0x3c0 - -#define VGA_MISC_WRITE 0x3c2 - -#define VGA_SEQ_INDEX 0x3c4 -#define VGA_SEQ_DATA 0x3c5 - -#define VGA_DAC_MASK 0x3c6 -#define VGA_DAC_READ_INDEX 0x3c7 -#define VGA_DAC_WRITE_INDEX 0x3c8 -#define VGA_DAC_DATA 0x3c9 -#define VGA_FEATURE_READ 0x3ca -#define VGA_MISC_READ 0x3cc - -#define VGA_GC_INDEX 0x3ce -#define VGA_GC_DATA 0x3cf - -#define VGA_CRTC_INDEX 0x3d4 -#define VGA_CRTC_DATA 0x3d5 - -#define VGA_INSTAT_READ 0x3da - -#define VGA_SEQ_NUM_REGISTERS 5 -#define VGA_CRTC_NUM_REGISTERS 25 -#define VGA_GC_NUM_REGISTERS 9 -#define VGA_AC_NUM_REGISTERS 21 - -#define CRTC_COLUMNS 0x01 -#define CRTC_OVERFLOW 0x07 -#define CRTC_ROWS 0x12 -#define CRTC_SCANLINES 0x09 - -#define CRTC_CURHI 0x0e -#define CRTC_CURLO 0x0f - - -#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */ -#define CHAR_ATTRIBUTE 0x17 /* grey on blue */ - -#define FONT_AMOUNT (8*8192) - /* VARIABLES ****************************************************************/ static ULONG CursorX = 0; /* Cursor Position */ @@ -184,34 +141,27 @@ static ULONG SizeY = 25; static BOOLEAN DisplayInitialized = FALSE; static BOOLEAN HalOwnsDisplay = TRUE; - -static PUSHORT VideoBuffer = NULL; -static PUCHAR GraphVideoBuffer = NULL; - +static ULONG GraphVideoBuffer = 0; static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL; -static UCHAR SavedTextPalette[768]; -static UCHAR SavedTextMiscOutReg; -static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS]; -static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS]; -static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS]; -static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS]; -static UCHAR SavedTextFont[2][FONT_AMOUNT]; -static BOOLEAN TextPaletteEnabled = FALSE; +extern UCHAR XboxFont8x16[]; +extern void SetPhys( ULONG Addr, ULONG Data ); +extern void SetPhysByte( ULONG Addr, ULONG Data ); /* PRIVATE FUNCTIONS *********************************************************/ VOID FASTCALL HalClearDisplay (UCHAR CharAttribute) { - WORD *ptr = (WORD*)VideoBuffer; ULONG i; + ULONG deviceSize = + PpcEarlybootInfo.dispDeviceRowBytes * PpcEarlybootInfo.dispDeviceDepth * + PpcEarlybootInfo.dispDeviceRect[3]; + for(i = 0; i < deviceSize; i += sizeof(int) ) + SetPhys(GraphVideoBuffer + i, CharAttribute); - for (i = 0; i < SizeX * SizeY; i++, ptr++) - *ptr = ((CharAttribute << 8) + ' '); - - CursorX = 0; - CursorY = 0; + CursorX = 0; + CursorY = 0; } @@ -220,352 +170,38 @@ HalClearDisplay (UCHAR CharAttribute) VOID STATIC HalScrollDisplay (VOID) { - PUSHORT ptr; - int i; - - ptr = VideoBuffer + SizeX; - RtlMoveMemory(VideoBuffer, - ptr, - SizeX * (SizeY - 1) * 2); - - ptr = VideoBuffer + (SizeX * (SizeY - 1)); - for (i = 0; i < (int)SizeX; i++, ptr++) + PULONG Dest = (PULONG)GraphVideoBuffer, + Src = (PULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes)); + PULONG End = (PULONG) + GraphVideoBuffer + + (PpcEarlybootInfo.dispDeviceRowBytes * PpcEarlybootInfo.dispDeviceDepth * + PpcEarlybootInfo.dispDeviceRect[3]); + + for( ; Src < End; Src += sizeof(int) ) { - *ptr = (CHAR_ATTRIBUTE << 8) + ' '; + *Dest++ = *Src++; } } VOID STATIC FASTCALL HalPutCharacter (CHAR Character) { - PUSHORT ptr; + int i,j,k; + PCHAR Dest = (PCHAR) + (GraphVideoBuffer + + (16 * PpcEarlybootInfo.dispDeviceRowBytes * CursorY) + + ((PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)); - ptr = VideoBuffer + ((CursorY * SizeX) + CursorX); - *ptr = (CHAR_ATTRIBUTE << 8) + Character; -} - -VOID STATIC -HalDisablePalette(VOID) -{ - (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); - WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20); - TextPaletteEnabled = FALSE; -} - -VOID STATIC -HalEnablePalette(VOID) -{ - (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); - WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00); - TextPaletteEnabled = TRUE; -} - -UCHAR STATIC FASTCALL -HalReadGc(ULONG Index) -{ - WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index); - return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA)); -} - -VOID STATIC FASTCALL -HalWriteGc(ULONG Index, UCHAR Value) -{ - WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index); - WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value); -} - -UCHAR STATIC FASTCALL -HalReadSeq(ULONG Index) -{ - WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index); - return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA)); -} - -VOID STATIC FASTCALL -HalWriteSeq(ULONG Index, UCHAR Value) -{ - WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index); - WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value); -} - -VOID STATIC FASTCALL -HalWriteAc(ULONG Index, UCHAR Value) -{ - if (TextPaletteEnabled) - { - Index &= ~0x20; + for( i = 0; i < 16; i++ ) { + for( j = 0; j < 8; j++ ) { + for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++ ) { + SetPhysByte + ((ULONG)(Dest + (j * PpcEarlybootInfo.dispDeviceDepth) + k), + ((1 << j) & (XboxFont8x16[(16 * Character) + i]) ? 0xff : 1)); + } + } + Dest += PpcEarlybootInfo.dispDeviceRowBytes; } - else - { - Index |= 0x20; - } - (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); - WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index); - WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value); -} - -UCHAR STATIC FASTCALL -HalReadAc(ULONG Index) -{ - if (TextPaletteEnabled) - { - Index &= ~0x20; - } - else - { - Index |= 0x20; - } - (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); - WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index); - return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ)); -} - -VOID STATIC FASTCALL -HalWriteCrtc(ULONG Index, UCHAR Value) -{ - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index); - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value); -} - -UCHAR STATIC FASTCALL -HalReadCrtc(ULONG Index) -{ - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index); - return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)); -} - -VOID STATIC FASTCALL -HalResetSeq(BOOLEAN Start) -{ - if (Start) - { - HalWriteSeq(0x00, 0x01); - } - else - { - HalWriteSeq(0x00, 0x03); - } -} - -VOID STATIC FASTCALL -HalBlankScreen(BOOLEAN On) -{ - UCHAR Scrn; - - Scrn = HalReadSeq(0x01); - - if (On) - { - Scrn &= ~0x20; - } - else - { - Scrn |= 0x20; - } - - HalResetSeq(TRUE); - HalWriteSeq(0x01, Scrn); - HalResetSeq(FALSE); -} - -VOID STATIC -HalSaveFont(VOID) -{ - UCHAR Attr10; - UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4; - ULONG i; - - /* Check if we are already in graphics mode. */ - Attr10 = HalReadAc(0x10); - if (Attr10 & 0x01) - { - return; - } - - /* Save registers. */ - MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ); - Gc4 = HalReadGc(0x04); - Gc5 = HalReadGc(0x05); - Gc6 = HalReadGc(0x06); - Seq2 = HalReadSeq(0x02); - Seq4 = HalReadSeq(0x04); - - /* Force colour mode. */ - WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01)); - - HalBlankScreen(FALSE); - - for (i = 0; i < 2; i++) - { - /* Save font 1 */ - HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */ - HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */ - HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */ - HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */ - HalWriteGc(0x06, 0x05); /* Set graphics. */ - memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT); - } - - /* Restore registers. */ - HalWriteAc(0x10, Attr10); - HalWriteSeq(0x02, Seq2); - HalWriteSeq(0x04, Seq4); - HalWriteGc(0x04, Gc4); - HalWriteGc(0x05, Gc5); - HalWriteGc(0x06, Gc6); - WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut); - - HalBlankScreen(TRUE); -} - -VOID STATIC -HalSaveMode(VOID) -{ - ULONG i; - - SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ); - - for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++) - { - SavedTextCrtcReg[i] = HalReadCrtc(i); - } - - HalEnablePalette(); - for (i = 0; i < VGA_AC_NUM_REGISTERS; i++) - { - SavedTextAcReg[i] = HalReadAc(i); - } - HalDisablePalette(); - - for (i = 0; i < VGA_GC_NUM_REGISTERS; i++) - { - SavedTextGcReg[i] = HalReadGc(i); - } - - for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++) - { - SavedTextSeqReg[i] = HalReadSeq(i); - } -} - -VOID STATIC -HalDacDelay(VOID) -{ - (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); - (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ); -} - -VOID STATIC -HalSavePalette(VOID) -{ - ULONG i; - WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF); - WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00); - for (i = 0; i < 768; i++) - { - SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA); - HalDacDelay(); - } -} - -VOID STATIC -HalRestoreFont(VOID) -{ - UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8; - UCHAR Seq2, Seq4; - ULONG i; - - /* Save registers. */ - MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ); - Attr10 = HalReadAc(0x10); - Gc1 = HalReadGc(0x01); - Gc3 = HalReadGc(0x03); - Gc4 = HalReadGc(0x04); - Gc5 = HalReadGc(0x05); - Gc6 = HalReadGc(0x06); - Gc8 = HalReadGc(0x08); - Seq2 = HalReadSeq(0x02); - Seq4 = HalReadSeq(0x04); - - /* Force into colour mode. */ - WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10)); - - HalBlankScreen(FALSE); - - HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */ - HalWriteGc(0x08, 0xFF); /* Write all bits. */ - HalWriteGc(0x01, 0x00); /* All planes from CPU. */ - - for (i = 0; i < 2; i++) - { - HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */ - HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */ - HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */ - HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */ - HalWriteGc(0x06, 0x05); /* Set graphics. */ - memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT); - } - - HalBlankScreen(TRUE); - - /* Restore registers. */ - WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut); - HalWriteAc(0x10, Attr10); - HalWriteGc(0x01, Gc1); - HalWriteGc(0x03, Gc3); - HalWriteGc(0x04, Gc4); - HalWriteGc(0x05, Gc5); - HalWriteGc(0x06, Gc6); - HalWriteGc(0x08, Gc8); - HalWriteSeq(0x02, Seq2); - HalWriteSeq(0x04, Seq4); -} - -VOID STATIC -HalRestoreMode(VOID) -{ - ULONG i; - - WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg); - - for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++) - { - HalWriteSeq(i, SavedTextSeqReg[i]); - } - - /* Unlock CRTC registers 0-7 */ - HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80)); - - for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++) - { - HalWriteCrtc(i, SavedTextCrtcReg[i]); - } - - for (i = 0; i < VGA_GC_NUM_REGISTERS; i++) - { - HalWriteGc(i, SavedTextGcReg[i]); - } - - HalEnablePalette(); - for (i = 0; i < VGA_AC_NUM_REGISTERS; i++) - { - HalWriteAc(i, SavedTextAcReg[i]); - } - HalDisablePalette(); -} - -VOID STATIC -HalRestorePalette(VOID) -{ - ULONG i; - WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF); - WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00); - for (i = 0; i < 768; i++) - { - WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]); - HalDacDelay(); - } - HalDisablePalette(); } /* PRIVATE FUNCTIONS ********************************************************/ @@ -578,55 +214,27 @@ HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock) * InitParameters = Parameters setup by the boot loader */ { - PHYSICAL_ADDRESS PhysBuffer; + __asm__("mr 20, %0\n\t" + "mr 21, %0\n\t" + "nop" : + : + "r" (DisplayInitialized), + "r" (&GraphVideoBuffer) : + "r20", "r21"); if (! DisplayInitialized) { - ULONG ScanLines; - ULONG Data; - - PhysBuffer.u.HighPart = 0; - PhysBuffer.u.LowPart = VGA_GRAPH_MEM; - GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached); - if (NULL == GraphVideoBuffer) - { - return; - } - VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM)); + boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra; + GraphVideoBuffer = (ULONG)XBootInfo->dispDeviceBase; + memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(*XBootInfo)); /* Set cursor position */ -// CursorX = LoaderBlock->cursorx; -// CursorY = LoaderBlock->cursory; CursorX = 0; CursorY = 0; - /* read screen size from the crtc */ - /* FIXME: screen size should be read from the boot parameters */ - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS); - SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1; - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS); - SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA); - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW); - Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA); - SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3)); - SizeY++; - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES); - ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1; - SizeY = SizeY / ScanLines; - -#ifdef BOCHS_30ROWS - SizeY=30; -#endif - HalClearDisplay(CHAR_ATTRIBUTE_BLACK); + HalClearDisplay(1); DisplayInitialized = TRUE; - - /* - Save the VGA state at this point so we can restore it on a bugcheck. - */ - HalSavePalette(); - HalSaveMode(); - HalSaveFont(); } } @@ -645,14 +253,8 @@ HalReleaseDisplayOwnership(VOID) if (HalOwnsDisplay == TRUE) return; - if (!HalResetDisplayParameters(SizeX, SizeY)) - { - HalRestoreMode(); - HalRestoreFont(); - HalRestorePalette(); - } HalOwnsDisplay = TRUE; - HalClearDisplay(CHAR_ATTRIBUTE); + HalClearDisplay(0); } @@ -681,12 +283,9 @@ HalDisplayString(IN PCH String) */ { PCH pch; -#ifdef SCREEN_SYNCHRONIZATION - int offset; -#endif static KSPIN_LOCK Lock; KIRQL OldIrql; - ULONG Flags; + BOOLEAN InterruptsEnabled = PPCGetEEBit(); /* See comment at top of file */ if (! HalOwnsDisplay || ! DisplayInitialized) @@ -699,18 +298,7 @@ HalDisplayString(IN PCH String) OldIrql = KfRaiseIrql(HIGH_LEVEL); KiAcquireSpinLock(&Lock); - Ki386SaveFlags(Flags); - Ki386DisableInterrupts(); - -#ifdef SCREEN_SYNCHRONIZATION - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI); - offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8; - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO); - offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA); - - CursorY = offset / SizeX; - CursorX = offset % SizeX; -#endif + _disable(); while (*pch != 0) { @@ -747,15 +335,8 @@ HalDisplayString(IN PCH String) pch++; } -#ifdef SCREEN_SYNCHRONIZATION - offset = (CursorY * SizeX) + CursorX; - - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO); - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff)); - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI); - WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff)); -#endif - Ki386RestoreFlags(Flags); + if(InterruptsEnabled) + _enable(); KiReleaseSpinLock(&Lock); KfLowerIrql(OldIrql); diff --git a/reactos/hal/halppc/generic/generic.rbuild b/reactos/hal/halppc/generic/generic.rbuild index ab14f754594..3a507fcaa93 100644 --- a/reactos/hal/halppc/generic/generic.rbuild +++ b/reactos/hal/halppc/generic/generic.rbuild @@ -6,17 +6,21 @@ beep.c bus.c + display.c dma.c drive.c enum.c fmutex.c + font.c halinit.c + irql.c isa.c kdbg.c mca.c misc.c pci.c portio.c + processor.c reboot.c sysbus.c sysinfo.c From 483d900bfb88d9eb0e557c9904031c1a9d896c93 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 8 Jan 2007 10:12:22 +0000 Subject: [PATCH 74/81] Update address of hal before performing imports, add page.c svn path=/branches/powerpc/; revision=25377 --- reactos/ntoskrnl/ke/freeldr.c | 20 ++++++++------------ reactos/ntoskrnl/ldr/loader.c | 28 ++++++++++++++++++++++++---- reactos/ntoskrnl/ntoskrnl.rbuild | 5 +++++ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 714bc780ff2..575809edd9a 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -296,6 +296,11 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, do {if (*BootPath == '/') *BootPath = ' ';} while (*BootPath++); } +VOID +INIT_FUNCTION +NTAPI +LdrpSettleHal(PVOID NewHalBase); + VOID FASTCALL KiRosPrepareForSystemStartup(IN ULONG Dummy, @@ -467,18 +472,9 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, (PVOID)KeLoaderModules[0].ModStart, &DriverSize); - // - // - // HACK HACK HACK WHEN WILL YOU PEOPLE FIX FREELDR?!?!?! - // FREELDR SENDS US AN ***INVALID*** HAL PE HEADER!!! - // WE READ IT IN LdrInitModuleManagement ABOVE!!! - // WE SET .SizeOfImage TO A *GARBAGE* VALUE!!! - // - // This dirty hack fixes it, and should make symbol lookup work too. - // - HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject. - DllBase)-> - OptionalHeader.SizeOfImage; +#ifdef _M_PPC + LdrpSettleHal((PVOID)DriverBase); +#endif /* Increase the last kernel address with the size of HAL */ MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize); diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index e65d7a1b699..1a269918293 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -26,7 +26,7 @@ #endif /* __GNUC__ */ #endif -#if 0 +#if 1 #undef ps #define ps(args...) DPRINT1(args) #endif @@ -104,6 +104,14 @@ LdrInit1 ( VOID ) KDB_LOADERINIT_HOOK(&NtoskrnlModuleObject, &HalModuleObject); } +VOID +INIT_FUNCTION +NTAPI +LdrpSettleHal (PVOID NewHalBase) +{ + HalModuleObject.DllBase = (PVOID) NewHalBase; +} + VOID INIT_FUNCTION NTAPI @@ -994,9 +1002,9 @@ LdrSafePEProcessModule ( // Copy current section into current offset of virtual section if (Section->SizeOfRawData) { - // ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n", - // PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase); - memcpy(Section->VirtualAddress + (char*)DriverBase, + ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n", + PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase); + memmove(Section->VirtualAddress + (char*)DriverBase, Section->PointerToRawData + (char*)ModuleLoadBase, Section->Misc.VirtualSize > Section->SizeOfRawData ? Section->SizeOfRawData : Section->Misc.VirtualSize); } @@ -1019,6 +1027,17 @@ LdrSafePEProcessModule ( return NULL; } } + else if(ModuleLoadBase != (PVOID)PENtHeaders->OptionalHeader.ImageBase) + { + /* Perform relocation fixups */ + Status = LdrRelocateImageWithBias(DriverBase, 0, "", STATUS_SUCCESS, + STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); + + if (!NT_SUCCESS(Status)) + { + return NULL; + } + } /* Perform import fixups */ Status = LdrPEFixupImports(DriverBase == ModuleLoadBase ? &NtoskrnlModuleObject : &HalModuleObject); @@ -1392,6 +1411,7 @@ LdrPEProcessImportDirectoryEntry( DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName); return STATUS_UNSUCCESSFUL; } + DbgPrint("Function %08x: %s\n", *ImportAddressList, pe_name->Name); } ImportAddressList++; FunctionNameList++; diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 4f0cba59073..ecd647dc624 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -253,6 +253,11 @@ pfault.c
+ + + page.c + + anonmem.c aspace.c balance.c From 58bde260650f9fd48cd4fb948736c570c0c99403 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 11 Jan 2007 09:00:30 +0000 Subject: [PATCH 75/81] Zero other BSS type sections where applicable. svn path=/branches/powerpc/; revision=25424 --- reactos/tools/ppc-build/alink/elf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/tools/ppc-build/alink/elf.cpp b/reactos/tools/ppc-build/alink/elf.cpp index cf50d2a14a6..3537ca59bf4 100755 --- a/reactos/tools/ppc-build/alink/elf.cpp +++ b/reactos/tools/ppc-build/alink/elf.cpp @@ -429,7 +429,7 @@ void loadelf(FILE *objfile) seg->winFlags ^= WINF_NEG_FLAGS; seg->datmask.resize(roundup(seg->length,8)/8); seg->data.resize(roundup(seg->length,8)); - if(seg->name == ".bss") + if(elf32shdr[i].sh_type == SHT_NOBITS) { memset(&seg->datmask[0], 0, seg->datmask.size()); memset(&seg->data[0], 0, seg->data.size()); From ea981c38bb6ed132af3de12a2a42b47c7f664325 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 14 Jan 2007 03:02:43 +0000 Subject: [PATCH 76/81] Some additions for relocatable ppc dlls. svn path=/branches/powerpc/; revision=25446 --- reactos/tools/ppc-build/alink/alink.h | 6 ++++++ reactos/tools/ppc-build/alink/elf.cpp | 15 +++++++++++++-- reactos/tools/ppc-build/alink/output.cpp | 18 +++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/reactos/tools/ppc-build/alink/alink.h b/reactos/tools/ppc-build/alink/alink.h index 86f032ab8da..f18dc00a1e3 100644 --- a/reactos/tools/ppc-build/alink/alink.h +++ b/reactos/tools/ppc-build/alink/alink.h @@ -375,6 +375,7 @@ typedef enum segframe_t { #define R_PPC_ADDR16_HI 5 #define R_PPC_ADDR16_HA 6 #define R_PPC_REL24 10 +#define R_PPC_PLTREL24 18 #define R_PPC_UADDR32 24 #define R_PPC_REL32 26 #define R_PPC_SECTOFF 33 @@ -397,6 +398,11 @@ typedef enum segframe_t { #define IMAGE_REL_PPC_SECRELLO 0x13 #define IMAGE_REL_PPC_SECRELHI 0x14 #define IMAGE_REL_PPC_GPREL 0x15 +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 #define OUTPUT_COM 1 #define OUTPUT_EXE 2 diff --git a/reactos/tools/ppc-build/alink/elf.cpp b/reactos/tools/ppc-build/alink/elf.cpp index 3537ca59bf4..4c47b4f9cd4 100755 --- a/reactos/tools/ppc-build/alink/elf.cpp +++ b/reactos/tools/ppc-build/alink/elf.cpp @@ -306,12 +306,22 @@ void loadelf(FILE *objfile) elf32sym.st_name); #if 0 + const char *segname = + elf32sym.st_shndx & 0x8000 ? + "*SPC*" : + (char *) + (&stringList[0] + + stringListOffsets[elf32hdr.e_shtrndx] + + elf32shdr[elf32sym.st_shndx].sh_name); + fprintf(stderr, "S[%05x] value %08x size %08x info %08x " - "other %08x shndx %08x %s\n", + "other %08x shndx %08x (%-10s) %s\n", j, elf32sym.st_value, elf32sym.st_size, elf32sym.st_info, - elf32sym.st_other, elf32sym.st_shndx, sym[j].name.c_str()); + elf32sym.st_other, elf32sym.st_shndx, + segname, + sym[j].name.c_str()); #endif if(!case_sensitive) @@ -608,6 +618,7 @@ void loadelf(FILE *objfile) reloc->rtype = FIX_PPC_ADDR24; break; + case R_PPC_PLTREL24: case R_PPC_REL24: reloc->rtype = FIX_PPC_REL24; break; diff --git a/reactos/tools/ppc-build/alink/output.cpp b/reactos/tools/ppc-build/alink/output.cpp index 262fbb810ee..fac9fc16a29 100644 --- a/reactos/tools/ppc-build/alink/output.cpp +++ b/reactos/tools/ppc-build/alink/output.cpp @@ -1216,6 +1216,9 @@ void BuildPERelocs(long relocSectNum,PUCHAR objectTable) case FIX_SELF_OFS16_2: case FIX_SELF_LBYTE: case FIX_RVA32: + case FIX_REL32: + case FIX_PPC_REL24: + case FIX_PPC_SECTOFF: continue; /* self-relative fixups and RVA fixups don't relocate */ default: break; @@ -1260,8 +1263,20 @@ void BuildPERelocs(long relocSectNum,PUCHAR objectTable) break; case FIX_PTR1632: case FIX_OFS32: - case FIX_OFS32_2: + case FIX_OFS32_2: j|= PE_REL_OFS32; + + case FIX_ADDR32: + j = (IMAGE_REL_BASED_HIGHLOW << 12) | (j & 0xfff); + break; + + case FIX_PPC_RVA16LO: + j = (IMAGE_REL_BASED_LOW << 12) | (j & 0xfff); + break; + + case FIX_PPC_RVA16HA: + j = (IMAGE_REL_BASED_HIGHADJ << 12) | (j & 0xfff); + break; } /* store relocation */ put16(relocSect->data, relocSect->length, j); @@ -2382,6 +2397,7 @@ void OutputWin32file(const std::string &outname) for(i=0;igetbase(), outlist[i]->name.c_str()); if(outlist[i] && ((outlist[i]->attr&SEG_ALIGN) !=SEG_ABS)) { /* ensure section is aligned to file-Align */ From e4aa183ac9342636ccb9637f1a38e240c9c2f199 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 15 Jan 2007 09:43:12 +0000 Subject: [PATCH 77/81] Remove some spam and add options to make ntoskrnl a bit smaller and easier to process. svn path=/branches/powerpc/; revision=25462 --- reactos/ReactOS-ppc.rbuild | 4 ++++ reactos/lib/rtl/image.c | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/reactos/ReactOS-ppc.rbuild b/reactos/ReactOS-ppc.rbuild index d6f73a4483b..25ee4ef343e 100644 --- a/reactos/ReactOS-ppc.rbuild +++ b/reactos/ReactOS-ppc.rbuild @@ -29,6 +29,10 @@ -fshort-wchar -fsigned-char -map + -mfull-toc + -meabi + -O2 + -Wno-strict-aliasing diff --git a/reactos/lib/rtl/image.c b/reactos/lib/rtl/image.c index 5439e4f328c..c4e5e64896b 100644 --- a/reactos/lib/rtl/image.c +++ b/reactos/lib/rtl/image.c @@ -176,11 +176,6 @@ LdrProcessRelocationBlockLongLong( Type = *TypeOffset >> 12; ShortPtr = (PUSHORT)(RVA(Address, Offset)); - DbgPrint("Correcting (%04x) %08x at %08x\n", - Type, - *((PULONG)RVA(Address,Offset)), - ShortPtr); - /* * Don't relocate within the relocation section itself. * GCC/LD generates sometimes relocation records for the relocation section. @@ -213,7 +208,6 @@ LdrProcessRelocationBlockLongLong( case IMAGE_REL_BASED_HIGHADJ: Addend = (((ULONG)*ShortPtr) << 16) + (ULONG)Delta; - if(Addend & 0x8000) Addend += 0x8000; *ShortPtr = Addend >> 16; break; From 674fbb117a3e440cec276fefc7987ac0600842fb Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 15 Jan 2007 09:54:16 +0000 Subject: [PATCH 78/81] Checkpoint. HalDisplayString is working and hooked up to DbgPrint. We've now got reciprocal imports from hal working. I've added a small hack, that being to relocate modules to 64k boundaries. This works around ABI issues for now. Some warning suppression re: uninitialized values. KdInit: make it possible to use a subset of the x86 debug targets. svn path=/branches/powerpc/; revision=25463 --- reactos/ntoskrnl/cm/regobj.c | 2 +- reactos/ntoskrnl/kd/kdinit.c | 10 +++++- reactos/ntoskrnl/kd/wrappers/gdbstub.c | 2 +- reactos/ntoskrnl/ke/bug.c | 2 ++ reactos/ntoskrnl/ke/freeldr.c | 26 +++++++++++++--- reactos/ntoskrnl/ke/powerpc/kiinit.c | 43 ++++++++------------------ 6 files changed, 47 insertions(+), 38 deletions(-) diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 6ed5f62ca10..43c549b8aa6 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -850,7 +850,7 @@ CmiScanKeyList(PKEY_OBJECT Parent, ULONG Attributes, PKEY_OBJECT* ReturnedObject) { - PKEY_OBJECT CurKey; + PKEY_OBJECT CurKey = 0; ULONG Index; DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n", diff --git a/reactos/ntoskrnl/kd/kdinit.c b/reactos/ntoskrnl/kd/kdinit.c index 263faaa865a..aed40e9f6c4 100644 --- a/reactos/ntoskrnl/kd/kdinit.c +++ b/reactos/ntoskrnl/kd/kdinit.c @@ -34,10 +34,15 @@ BOOLEAN KdpEarlyBreak = FALSE; LIST_ENTRY KdProviders = {&KdProviders, &KdProviders}; KD_DISPATCH_TABLE DispatchTable[KdMax]; +#ifdef _M_IX86 PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit, KdpSerialInit, KdpInitDebugLog, KdpBochsInit}; +#elif defined(_M_PPC) +PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit, + KdpInitDebugLog}; +#endif /* PRIVATE FUNCTIONS *********************************************************/ @@ -248,7 +253,10 @@ KdInitSystem(ULONG BootPhase, /* Call Providers at Phase 0 */ for (i = 0; i < KdMax; i++) { - InitRoutines[i](&DispatchTable[i], 0); + if(InitRoutines[i]) + { + InitRoutines[i](&DispatchTable[i], 0); + } } /* Call Wrapper at Phase 0 */ diff --git a/reactos/ntoskrnl/kd/wrappers/gdbstub.c b/reactos/ntoskrnl/kd/wrappers/gdbstub.c index a9b2342523e..0a9bcfd9b8f 100644 --- a/reactos/ntoskrnl/kd/wrappers/gdbstub.c +++ b/reactos/ntoskrnl/kd/wrappers/gdbstub.c @@ -1552,7 +1552,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, case 'c': { ULONG BreakpointNumber; - ULONG dr6_; + ULONG dr6_ = 0; /* try to read optional parameter, pc unchanged if no parm */ if (GspHex2Long (&ptr, &Address)) diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index f6e837c3887..5ce8e7cca20 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -122,6 +122,7 @@ INIT_FUNCTION NTAPI KiInitializeBugCheck(VOID) { +#if 0 PRTL_MESSAGE_RESOURCE_DATA BugCheckData; LDR_RESOURCE_INFO ResourceInfo; PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; @@ -148,6 +149,7 @@ KiInitializeBugCheck(VOID) NULL); if (NT_SUCCESS(Status)) KiBugCodeMessages = BugCheckData; } +#endif } VOID diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 575809edd9a..1308e937465 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -294,6 +294,11 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, /* Parse it and change every slash to a space */ BootPath = LoaderBlock->LoadOptions; do {if (*BootPath == '/') *BootPath = ' ';} while (*BootPath++); + +#ifdef _M_PPC + /* Finally link to the ReactOS specific part in the extension section */ + LoaderBlock->u.PowerPC.BootInfo = &KeRosLoaderBlock; +#endif } VOID @@ -325,6 +330,7 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra; memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(PpcEarlybootInfo)); PpcEarlybootInfo.dispFont = BootDigits; + LoaderBlock->ArchExtra = (ULONG)&PpcEarlybootInfo; BootInfo = (struct _boot_infos_t *)&PpcEarlybootInfo; DrawNumber(BootInfo, 0x1234abcd, 10, 100); DrawNumber(BootInfo, (ULONG)nk, 10 , 150); @@ -447,10 +453,14 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, } /* Choose last module address as the final kernel address */ + /* This is a workaround re: high and low adjust. + * The ABI we're using doesn't respect HIGHADJ pairing like compilers for NT do, so well be a bit + * lenient. This can be fixed later. + */ +#ifndef _M_PPC MmFreeLdrLastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd); -#ifndef _M_PPC /* Select the HAL Base */ HalBase = KeLoaderModules[1].ModStart; @@ -458,7 +468,13 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, DriverBase = MmFreeLdrLastKernelAddress; LdrHalBase = (ULONG_PTR)DriverBase; #else + MmFreeLdrLastKernelAddress = + ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd, 0x10000); + + /* Select the HAL Base */ HalBase = KeLoaderModules[1].ModStart; + + /* Choose Driver Base */ DriverBase = MmFreeLdrLastKernelAddress; LdrHalBase = KeLoaderModules[1].ModStart; #endif @@ -466,16 +482,16 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, /* Initialize Module Management */ LdrInitModuleManagement((PVOID)KeLoaderModules[0].ModStart); +#ifdef _M_PPC + LdrpSettleHal((PVOID)DriverBase); +#endif + /* Load HAL.DLL with the PE Loader */ LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)KeLoaderModules[0].ModStart, &DriverSize); -#ifdef _M_PPC - LdrpSettleHal((PVOID)DriverBase); -#endif - /* Increase the last kernel address with the size of HAL */ MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize); diff --git a/reactos/ntoskrnl/ke/powerpc/kiinit.c b/reactos/ntoskrnl/ke/powerpc/kiinit.c index c2036558836..496246d9761 100644 --- a/reactos/ntoskrnl/ke/powerpc/kiinit.c +++ b/reactos/ntoskrnl/ke/powerpc/kiinit.c @@ -14,11 +14,17 @@ #define NDEBUG #include +#include /* GLOBALS *******************************************************************/ +/* Ku bit should be set, so that we get the best options for page protection */ +#define PPC_SEG_Ku 0x40000000 +#define PPC_SEG_Ks 0x20000000 + extern LOADER_MODULE KeLoaderModules[64]; extern ULONG KeLoaderModuleCount; +extern ULONG_PTR MmFreeLdrLastKernelAddress; KPRCB PrcbData[MAXIMUM_PROCESSORS]; /* FUNCTIONS *****************************************************************/ @@ -78,29 +84,17 @@ KiInitializePcr(IN ULONG ProcessorNumber, IN PKTHREAD IdleThread, IN PVOID DpcStack) { - TRACE; Pcr->MajorVersion = PCR_MAJOR_VERSION; - TRACE; Pcr->MinorVersion = PCR_MINOR_VERSION; - TRACE; Pcr->CurrentIrql = PASSIVE_LEVEL; - TRACE; Pcr->Prcb = PrcbData; - TRACEXY(Pcr->Prcb, PrcbData); Pcr->Prcb->MajorVersion = 1; - TRACE; Pcr->Prcb->MinorVersion = 1; - TRACE; Pcr->Prcb->Number = 0; /* UP for now */ - TRACE; Pcr->Prcb->SetMember = 1; - TRACE; Pcr->Prcb->BuildType = 0; - TRACE; Pcr->Prcb->DpcStack = DpcStack; - TRACE; KiProcessorBlock[ProcessorNumber] = Pcr->Prcb; - TRACEXY(0xd00d,0xbeef); } extern ULONG KiGetFeatureBits(); @@ -257,7 +251,7 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Set up segs for normal paged address space. */ for( i = 0; i < 16; i++ ) { - SetSR(i, i); + SetSR(i, (i < 8 ? PPC_SEG_Ku : PPC_SEG_Ks) | i); } /* Save the loader block and get the current CPU */ @@ -269,14 +263,13 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* We'll allocate a page from the end of the kernel area for KPCR. This code will probably * change when we get SMP support. */ - ULONG LastPage = ROUND_UP(KeLoaderModules[KeLoaderModuleCount-1].ModEnd,1<Prcb; Pcr->Number = Cpu; Pcr->SetMember = 1 << Cpu; Prcb->SetMember = 1 << Cpu; - TRACE; /* Initialize the Processor with HAL */ HalInitializeProcessor(Cpu, LoaderBlock); - TRACE; /* Set active processors */ KeActiveProcessors |= Pcr->SetMember; KeNumberProcessors++; - TRACE; /* Initialize the Debugger for the Boot CPU */ if (!Cpu) KdInitSystem (0, LoaderBlock); - TRACE; /* Check for break-in */ if (KdPollBreakIn()) { DbgBreakPointWithStatus(1); } - TRACE; /* Raise to HIGH_LEVEL */ KfRaiseIrql(HIGH_LEVEL); - TRACE; /* Call main kernel intialization */ KiInitializeKernel(&KiInitialProcess.Pcb, &KiInitialThread.Tcb, @@ -334,6 +318,5 @@ AppCpuInit: Prcb, Cpu, (PVOID)LoaderBlock); - TRACE; } From c668a23039e3d640dda0007fc4af120214e93d1d Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 15 Jan 2007 10:00:47 +0000 Subject: [PATCH 79/81] Corresponding checkpoint for HAL. Some hacks are still in here. Not much is implemented yet. Just getting the basics going. svn path=/branches/powerpc/; revision=25464 --- reactos/hal/hal.rbuild | 3 ++ reactos/hal/halppc/generic/bus.c | 2 +- reactos/hal/halppc/generic/display.c | 64 ++++++++++++++------------ reactos/hal/halppc/generic/halinit.c | 2 +- reactos/hal/halppc/generic/irql.c | 30 +++--------- reactos/hal/halppc/generic/processor.c | 8 ++-- reactos/hal/halppc/generic/timer.c | 2 +- reactos/hal/halppc/up/halup.rbuild | 2 + 8 files changed, 54 insertions(+), 59 deletions(-) diff --git a/reactos/hal/hal.rbuild b/reactos/hal/hal.rbuild index 552e3306f9a..5392b057edb 100644 --- a/reactos/hal/hal.rbuild +++ b/reactos/hal/hal.rbuild @@ -5,4 +5,7 @@ + + + diff --git a/reactos/hal/halppc/generic/bus.c b/reactos/hal/halppc/generic/bus.c index 35bac840f2c..cbf9c351885 100644 --- a/reactos/hal/halppc/generic/bus.c +++ b/reactos/hal/halppc/generic/bus.c @@ -138,9 +138,9 @@ HalpInitBusHandlers(VOID) InitializeListHead(&HalpBusHandlerList); /* Initialize hal dispatch tables */ +#if 0 HalQuerySystemInformation = HalpQuerySystemInformation; -#if 0 HalSetSystemInformation = HalpSetSystemInformation; HalQueryBusSlots = HalpQueryBusSlots; diff --git a/reactos/hal/halppc/generic/display.c b/reactos/hal/halppc/generic/display.c index f2858374c8d..f5c7f505120 100644 --- a/reactos/hal/halppc/generic/display.c +++ b/reactos/hal/halppc/generic/display.c @@ -123,10 +123,11 @@ #include #include +#include + #define NDEBUG #include -#include "font.h" boot_infos_t PpcEarlybootInfo; BOOLEAN PPCGetEEBit(); @@ -146,6 +147,7 @@ static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL; extern UCHAR XboxFont8x16[]; extern void SetPhys( ULONG Addr, ULONG Data ); +extern ULONG GetPhys( ULONG Addr ); extern void SetPhysByte( ULONG Addr, ULONG Data ); /* PRIVATE FUNCTIONS *********************************************************/ @@ -155,7 +157,7 @@ HalClearDisplay (UCHAR CharAttribute) { ULONG i; ULONG deviceSize = - PpcEarlybootInfo.dispDeviceRowBytes * PpcEarlybootInfo.dispDeviceDepth * + PpcEarlybootInfo.dispDeviceRowBytes * PpcEarlybootInfo.dispDeviceRect[3]; for(i = 0; i < deviceSize; i += sizeof(int) ) SetPhys(GraphVideoBuffer + i, CharAttribute); @@ -170,34 +172,43 @@ HalClearDisplay (UCHAR CharAttribute) VOID STATIC HalScrollDisplay (VOID) { - PULONG Dest = (PULONG)GraphVideoBuffer, - Src = (PULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes)); - PULONG End = (PULONG) + ULONG i, deviceSize = + PpcEarlybootInfo.dispDeviceRowBytes * + PpcEarlybootInfo.dispDeviceRect[3]; + ULONG Dest = (ULONG)GraphVideoBuffer, + Src = (ULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes)); + ULONG End = (ULONG) GraphVideoBuffer + - (PpcEarlybootInfo.dispDeviceRowBytes * PpcEarlybootInfo.dispDeviceDepth * - PpcEarlybootInfo.dispDeviceRect[3]); + (PpcEarlybootInfo.dispDeviceRowBytes * + (PpcEarlybootInfo.dispDeviceRect[3]-16)); - for( ; Src < End; Src += sizeof(int) ) + while( Src < End ) { - *Dest++ = *Src++; + SetPhys((ULONG)Dest, GetPhys(Src)); + Src += 4; Dest += 4; } + + /* Clear the bottom row */ + for(i = End; i < deviceSize; i += sizeof(int) ) + SetPhys(GraphVideoBuffer + i, 1); } VOID STATIC FASTCALL HalPutCharacter (CHAR Character) { int i,j,k; - PCHAR Dest = (PCHAR) + ULONG Dest = (GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes * CursorY) + - ((PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)); + (8 * (PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)), RowDest; + UCHAR ByteToPlace; for( i = 0; i < 16; i++ ) { + RowDest = Dest; for( j = 0; j < 8; j++ ) { - for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++ ) { - SetPhysByte - ((ULONG)(Dest + (j * PpcEarlybootInfo.dispDeviceDepth) + k), - ((1 << j) & (XboxFont8x16[(16 * Character) + i]) ? 0xff : 1)); + ByteToPlace = ((128 >> j) & (XboxFont8x16[(16 * Character) + i])) ? 0xff : 1; + for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++, RowDest++ ) { + SetPhysByte(RowDest, ByteToPlace); } } Dest += PpcEarlybootInfo.dispDeviceRowBytes; @@ -214,15 +225,7 @@ HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock) * InitParameters = Parameters setup by the boot loader */ { - __asm__("mr 20, %0\n\t" - "mr 21, %0\n\t" - "nop" : - : - "r" (DisplayInitialized), - "r" (&GraphVideoBuffer) : - "r20", "r21"); - - if (! DisplayInitialized) + if (! DisplayInitialized) { boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra; GraphVideoBuffer = (ULONG)XBootInfo->dispDeviceBase; @@ -232,6 +235,9 @@ HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock) CursorX = 0; CursorY = 0; + SizeX = XBootInfo->dispDeviceRowBytes / XBootInfo->dispDeviceDepth; + SizeY = XBootInfo->dispDeviceRect[3] / 16; + HalClearDisplay(1); DisplayInitialized = TRUE; @@ -283,7 +289,7 @@ HalDisplayString(IN PCH String) */ { PCH pch; - static KSPIN_LOCK Lock; + //static KSPIN_LOCK Lock; KIRQL OldIrql; BOOLEAN InterruptsEnabled = PPCGetEEBit(); @@ -296,7 +302,7 @@ HalDisplayString(IN PCH String) pch = String; OldIrql = KfRaiseIrql(HIGH_LEVEL); - KiAcquireSpinLock(&Lock); + //KiAcquireSpinLock(&Lock); _disable(); @@ -331,14 +337,14 @@ HalDisplayString(IN PCH String) HalScrollDisplay (); CursorY = SizeY - 1; } - + pch++; } - + if(InterruptsEnabled) _enable(); - KiReleaseSpinLock(&Lock); + //KiReleaseSpinLock(&Lock); KfLowerIrql(OldIrql); } diff --git a/reactos/hal/halppc/generic/halinit.c b/reactos/hal/halppc/generic/halinit.c index fe78f9bc438..473180e666e 100644 --- a/reactos/hal/halppc/generic/halinit.c +++ b/reactos/hal/halppc/generic/halinit.c @@ -37,6 +37,7 @@ HalInitSystem (ULONG BootPhase, { if (BootPhase == 0) { + HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)(LoaderBlock->u.PowerPC.BootInfo)); RtlZeroMemory(&HalpHooks, sizeof(HALP_HOOKS)); HalpInitPhase0((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock); } @@ -46,7 +47,6 @@ HalInitSystem (ULONG BootPhase, //HalpInitPhase1(); /* Initialize display and make the screen black */ - HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock); HalpInitBusHandlers(); HalpInitDma(); diff --git a/reactos/hal/halppc/generic/irql.c b/reactos/hal/halppc/generic/irql.c index fd55e42c1f7..393fc7800e5 100644 --- a/reactos/hal/halppc/generic/irql.c +++ b/reactos/hal/halppc/generic/irql.c @@ -57,6 +57,7 @@ static ULONG HalpPendingInterruptCount[NR_IRQS]; VOID STDCALL KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); +BOOLEAN PPCGetEEBit(); /* FUNCTIONS ****************************************************************/ @@ -73,26 +74,7 @@ KIRQL STDCALL KeGetCurrentIrql (VOID) VOID NTAPI HalpInitPICs(VOID) { memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount)); - - /* Initialization sequence */ - WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11); - WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11); - /* Start of hardware irqs (0x24) */ - WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE); - WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8); - /* 8259-1 is master */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4); - /* 8259-2 is slave */ - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2); - /* 8086 mode */ - WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1); - WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1); - /* Enable interrupts */ - WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master); - WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave); - - /* We can now enable interrupts */ - Ki386EnableInterrupts(); + _enable(); } VOID HalpEndSystemInterrupt(KIRQL Irql) @@ -100,7 +82,7 @@ VOID HalpEndSystemInterrupt(KIRQL Irql) * FUNCTION: Enable all irqs with higher priority. */ { - ULONG flags; + BOOLEAN InterruptsEnabled = PPCGetEEBit(); const USHORT mask[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, @@ -110,15 +92,15 @@ VOID HalpEndSystemInterrupt(KIRQL Irql) }; /* Interrupts should be disable while enabling irqs of both pics */ - Ki386SaveFlags(flags); - Ki386DisableInterrupts(); + _disable(); pic_mask_intr.both &= mask[Irql]; WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master)); WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); /* restore flags */ - Ki386RestoreFlags(flags); + if(InterruptsEnabled) + _enable(); } VOID STATIC diff --git a/reactos/hal/halppc/generic/processor.c b/reactos/hal/halppc/generic/processor.c index 25867253203..4df7c36886a 100644 --- a/reactos/hal/halppc/generic/processor.c +++ b/reactos/hal/halppc/generic/processor.c @@ -20,13 +20,15 @@ /* FUNCTIONS *****************************************************************/ +#define INITIAL_STALL_COUNT 0x10000 + VOID STDCALL HalInitializeProcessor(ULONG ProcessorNumber, PLOADER_PARAMETER_BLOCK LoaderBlock) { - DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock); - /* Set default IDR */ - KeGetPcr()->IDR = 0xFFFFFFFB; + DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock); + /* Do this a bit earlier for the purpose of getting gossip from the kernel */ + HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)(LoaderBlock->u.PowerPC.BootInfo)); KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT; } diff --git a/reactos/hal/halppc/generic/timer.c b/reactos/hal/halppc/generic/timer.c index 9df30825631..004460c6c42 100644 --- a/reactos/hal/halppc/generic/timer.c +++ b/reactos/hal/halppc/generic/timer.c @@ -79,7 +79,7 @@ static BOOLEAN UdelayCalibrated = FALSE; /* FUNCTIONS **************************************************************/ -static BOOLEAN PPCGetEEBit() +BOOLEAN PPCGetEEBit() { ULONG Msr; __asm__("mfmsr %0" : "=r" (Msr)); diff --git a/reactos/hal/halppc/up/halup.rbuild b/reactos/hal/halppc/up/halup.rbuild index 0ba1b0888a8..019d9ef7d29 100644 --- a/reactos/hal/halppc/up/halup.rbuild +++ b/reactos/hal/halppc/up/halup.rbuild @@ -7,6 +7,8 @@ halppc_generic + string + ntoskrnl halinit_up.c halup.rc From 66ccb79bbf31472dee6ea14f4ada75f3f7dd914a Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Mon, 15 Jan 2007 10:20:00 +0000 Subject: [PATCH 80/81] Updated linker script. svn path=/branches/powerpc/; revision=25465 --- reactos/tools/ppc-build/ldscript | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/tools/ppc-build/ldscript b/reactos/tools/ppc-build/ldscript index 11fd10be4a8..d1e30b32694 100644 --- a/reactos/tools/ppc-build/ldscript +++ b/reactos/tools/ppc-build/ldscript @@ -23,6 +23,7 @@ SECTIONS .rodata : { *(.rodata) + *(.got2) } .idata : { @@ -40,6 +41,7 @@ SECTIONS } .bss : { + *(.sbss) *(.bss) *(COMMON) } From 2a58de26de8f3f453216c73840ba42ceed136349 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 16 Mar 2007 07:16:45 +0000 Subject: [PATCH 81/81] Stragglers plus warning fixen. svn path=/branches/powerpc/; revision=26110 --- reactos/ReactOS-ppc.rbuild | 1 - reactos/boot/freeldr/freeldr/rtl/libsupp.c | 46 ++++ reactos/hal/halppc/generic/font.c | 280 +++++++++++++++++++++ reactos/include/psdk/intrin.h | 4 +- reactos/include/psdk/winnt.h | 10 +- reactos/lib/rtl/exception.c | 2 +- reactos/lib/string/sscanf.c | 2 +- 7 files changed, 337 insertions(+), 8 deletions(-) create mode 100644 reactos/boot/freeldr/freeldr/rtl/libsupp.c create mode 100644 reactos/hal/halppc/generic/font.c diff --git a/reactos/ReactOS-ppc.rbuild b/reactos/ReactOS-ppc.rbuild index 25ee4ef343e..c7fdb86a046 100644 --- a/reactos/ReactOS-ppc.rbuild +++ b/reactos/ReactOS-ppc.rbuild @@ -28,7 +28,6 @@ 1 -fshort-wchar -fsigned-char - -map -mfull-toc -meabi -O2 diff --git a/reactos/boot/freeldr/freeldr/rtl/libsupp.c b/reactos/boot/freeldr/freeldr/rtl/libsupp.c new file mode 100644 index 00000000000..6236367e414 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/rtl/libsupp.c @@ -0,0 +1,46 @@ +/* + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer + * Copyright (C) 2006 Aleksey Bragin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#ifdef DBG +VOID FASTCALL +CHECK_PAGED_CODE_RTL(char *file, int line) +{ + // boot-code is always ok +} +#endif + +PVOID +STDCALL +RtlpAllocateMemory(ULONG Bytes, + ULONG Tag) +{ + return MmAllocateMemory(Bytes); +} + + +VOID +STDCALL +RtlpFreeMemory(PVOID Mem, + ULONG Tag) +{ + return MmFreeMemory(Mem); +} diff --git a/reactos/hal/halppc/generic/font.c b/reactos/hal/halppc/generic/font.c new file mode 100644 index 00000000000..c69c0729280 --- /dev/null +++ b/reactos/hal/halppc/generic/font.c @@ -0,0 +1,280 @@ +/* $Id: font.c 21840 2006-05-07 18:56:52Z ion $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: Xbox HAL + * FILE: hal/halx86/xbox/font.h + * PURPOSE: Font glyphs + * PROGRAMMER: Ge van Geldorp (gvg@reactos.com) + * UPDATE HISTORY: + * Created 2004/12/02 + * + * Note: Converted from the XFree vga.bdf font + */ + +#include + +#define NDEBUG +#include + +UCHAR XboxFont8x16[256 * 16] = +{ + 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* 0x00 */ + 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xa5,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* 0x01 */ + 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xdb,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, /* 0x02 */ + 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, /* 0x03 */ + 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x04 */ + 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x05 */ + 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x06 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x07 */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x08 */ + 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, /* 0x09 */ + 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, /* 0x0a */ + 0x00,0x00,0x1e,0x06,0x0e,0x1a,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* 0x0b */ + 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0c */ + 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, /* 0x0d */ + 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, /* 0x0e */ + 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0f */ + 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, /* 0x10 */ + 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* 0x11 */ + 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, /* 0x12 */ + 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, /* 0x13 */ + 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, /* 0x14 */ + 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, /* 0x15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, /* 0x16 */ + 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0x17 */ + 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x18 */ + 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0x19 */ + 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1a */ + 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1b */ + 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1c */ + 0x00,0x00,0x00,0x00,0x00,0x28,0x6c,0xfe,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1d */ + 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x1e */ + 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x1f */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ + 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ! */ + 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* " */ + 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, /* # */ + 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, /* $ */ + 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, /* % */ + 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* & */ + 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ' */ + 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, /* ( */ + 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, /* ) */ + 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, /* * */ + 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* + */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, /* , */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* . */ + 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, /* / */ + 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xd6,0xd6,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0 */ + 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, /* 1 */ + 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 2 */ + 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 3 */ + 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, /* 4 */ + 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 5 */ + 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 6 */ + 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, /* 7 */ + 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 8 */ + 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, /* 9 */ + 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* : */ + 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, /* ; */ + 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, /* < */ + 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* = */ + 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, /* > */ + 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ? */ + 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* @ */ + 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* A */ + 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, /* B */ + 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, /* C */ + 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, /* D */ + 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* E */ + 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* F */ + 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, /* G */ + 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* H */ + 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* I */ + 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* J */ + 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* K */ + 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* L */ + 0x00,0x00,0xc6,0xee,0xfe,0xfe,0xd6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* M */ + 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* N */ + 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* O */ + 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* P */ + 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, /* Q */ + 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* R */ + 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* S */ + 0x00,0x00,0x7e,0x7e,0x5a,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* T */ + 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* U */ + 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x6c,0x38,0x10,0x00,0x00,0x00,0x00, /* V */ + 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0xee,0x6c,0x00,0x00,0x00,0x00, /* W */ + 0x00,0x00,0xc6,0xc6,0x6c,0x7c,0x38,0x38,0x7c,0x6c,0xc6,0xc6,0x00,0x00,0x00,0x00, /* X */ + 0x00,0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* Y */ + 0x00,0x00,0xfe,0xc6,0x86,0x0c,0x18,0x30,0x60,0xc2,0xc6,0xfe,0x00,0x00,0x00,0x00, /* Z */ + 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, /* [ */ + 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* \ */ + 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, /* ] */ + 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, /* _ */ + 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ` */ + 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* a */ + 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, /* b */ + 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* c */ + 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* d */ + 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* e */ + 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* f */ + 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, /* g */ + 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* h */ + 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* i */ + 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, /* j */ + 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, /* k */ + 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* l */ + 0x00,0x00,0x00,0x00,0x00,0xec,0xfe,0xd6,0xd6,0xd6,0xd6,0xc6,0x00,0x00,0x00,0x00, /* m */ + 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* n */ + 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* o */ + 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, /* p */ + 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, /* q */ + 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* r */ + 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, /* s */ + 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, /* t */ + 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* u */ + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, /* v */ + 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0x6c,0x00,0x00,0x00,0x00, /* w */ + 0x00,0x00,0x00,0x00,0x00,0xc6,0x6c,0x38,0x38,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00, /* x */ + 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, /* y */ + 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* z */ + 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, /* { */ + 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* | */ + 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, /* } */ + 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ~ */ + 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x7f */ + 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, /* 0x80 */ + 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x81 */ + 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x82 */ + 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x83 */ + 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x84 */ + 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x85 */ + 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x86 */ + 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, /* 0x87 */ + 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x88 */ + 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x89 */ + 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x8a */ + 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8b */ + 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8c */ + 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8d */ + 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8e */ + 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8f */ + 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, /* 0x90 */ + 0x00,0x00,0x00,0x00,0x00,0xcc,0x76,0x36,0x7e,0xd8,0xd8,0x6e,0x00,0x00,0x00,0x00, /* 0x91 */ + 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, /* 0x92 */ + 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x93 */ + 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x94 */ + 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x95 */ + 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x96 */ + 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x97 */ + 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, /* 0x98 */ + 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x99 */ + 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x9a */ + 0x00,0x18,0x18,0x3c,0x66,0x60,0x60,0x60,0x66,0x3c,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9b */ + 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, /* 0x9c */ + 0x00,0x00,0x66,0x66,0x3c,0x18,0x7e,0x18,0x7e,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9d */ + 0x00,0xf8,0xcc,0xcc,0xf8,0xc4,0xcc,0xde,0xcc,0xcc,0xcc,0xc6,0x00,0x00,0x00,0x00, /* 0x9e */ + 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, /* 0x9f */ + 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa0 */ + 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0xa1 */ + 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa2 */ + 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa3 */ + 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* 0xa4 */ + 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xa5 */ + 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa6 */ + 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa7 */ + 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa8 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, /* 0xa9 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, /* 0xaa */ + 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xdc,0x86,0x0c,0x18,0x3e,0x00,0x00, /* 0xab */ + 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x9e,0x3e,0x06,0x06,0x00,0x00, /* 0xac */ + 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0xad */ + 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xae */ + 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xaf */ + 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, /* 0xb0 */ + 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, /* 0xb1 */ + 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, /* 0xb2 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb3 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb4 */ + 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb5 */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb6 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb7 */ + 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb8 */ + 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb9 */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xba */ + 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xbb */ + 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbc */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbd */ + 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbe */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xbf */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc0 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc1 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc2 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc3 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc4 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc5 */ + 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc6 */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc7 */ + 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc8 */ + 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc9 */ + 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xca */ + 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcb */ + 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcc */ + 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcd */ + 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xce */ + 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcf */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd0 */ + 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd1 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd2 */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd3 */ + 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd4 */ + 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd5 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd6 */ + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd7 */ + 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd8 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd9 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xda */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdb */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdc */ + 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, /* 0xdd */ + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, /* 0xde */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdf */ + 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, /* 0xe0 */ + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, /* 0xe1 */ + 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, /* 0xe2 */ + 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, /* 0xe3 */ + 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 0xe4 */ + 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xe5 */ + 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, /* 0xe6 */ + 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0xe7 */ + 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0xe8 */ + 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0xe9 */ + 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, /* 0xea */ + 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, /* 0xeb */ + 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xec */ + 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, /* 0xed */ + 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, /* 0xee */ + 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xef */ + 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0xf0 */ + 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, /* 0xf1 */ + 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf2 */ + 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf3 */ + 0x00,0x00,0x0e,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xf4 */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xf5 */ + 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* 0xf6 */ + 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf7 */ + 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf8 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf9 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfa */ + 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, /* 0xfb */ + 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfc */ + 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfd */ + 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, /* 0xfe */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 0xff */ +}; + +/* EOF */ + diff --git a/reactos/include/psdk/intrin.h b/reactos/include/psdk/intrin.h index ab36de39c26..7e8317235f1 100644 --- a/reactos/include/psdk/intrin.h +++ b/reactos/include/psdk/intrin.h @@ -1650,8 +1650,8 @@ static __inline__ __attribute__((always_inline)) unsigned short __readfsword(con static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(const unsigned long Offset) { - unsigned long result; - char *addr; + unsigned long result = 0; + char *addr = 0; __asm__("\tadd %2,13,%1\n" "\tlwz %0,0(%2)\n" : "=b" (result) diff --git a/reactos/include/psdk/winnt.h b/reactos/include/psdk/winnt.h index 7d54e14e84b..b07f9112e40 100644 --- a/reactos/include/psdk/winnt.h +++ b/reactos/include/psdk/winnt.h @@ -62,9 +62,13 @@ extern "C" { #elif (_MSC_VER) #define FORCEINLINE __inline #else +#ifdef _PPC_ +#define FORCEINLINE __inline +#else #define FORCEINLINE static __attribute__((unused)) #endif #endif +#endif #if !defined(_NTSYSTEM_) #define NTSYSAPI DECLSPEC_IMPORT @@ -3788,7 +3792,7 @@ static __inline__ PVOID GetCurrentFiber(void) #ifndef __NTDDK_H static __inline__ struct _TEB * NtCurrentTeb(void) { - struct _TEB *ret; + struct _TEB *ret = 0; #ifndef _M_PPC __asm__ __volatile__ ( @@ -3869,7 +3873,7 @@ InterlockedBitTestAndSet(IN LONG volatile *Base, :"Ir" (Bit) : "memory"); #elif defined(_M_PPC) - LONG scratch; + LONG scratch = 0; Bit = 1 << Bit; /* %0 - OldBit @@ -3909,7 +3913,7 @@ InterlockedBitTestAndReset(IN LONG volatile *Base, :"Ir" (Bit) : "memory"); #elif defined(_M_PPC) - LONG scratch; + LONG scratch = 0; Bit = ~(1 << Bit); /* %0 - OldBit diff --git a/reactos/lib/rtl/exception.c b/reactos/lib/rtl/exception.c index 917f74a3b5d..becb2229ebb 100644 --- a/reactos/lib/rtl/exception.c +++ b/reactos/lib/rtl/exception.c @@ -115,7 +115,7 @@ RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags) { - PULONG Stack, NewStack; + PULONG Stack = 0, NewStack; ULONG Eip; ULONG_PTR StackBegin, StackEnd; BOOLEAN Result, StopSearch = FALSE; diff --git a/reactos/lib/string/sscanf.c b/reactos/lib/string/sscanf.c index 3d459750461..079df0feee6 100644 --- a/reactos/lib/string/sscanf.c +++ b/reactos/lib/string/sscanf.c @@ -28,7 +28,7 @@ static int char2digit(char c, int base) { int sscanf(const char *str, const char *format, ...) { - int res; + int res = 0; #if 0 va_list valist;